summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@kozmo.(none)>2002-12-05 20:17:32 -0800
committerJames Simmons <jsimmons@kozmo.(none)>2002-12-05 20:17:32 -0800
commitb4e5e606e98b5edb81079e937f341c0557cfbdba (patch)
tree0aabc6f050790029636982efa89f0ea04c8a8b3b
parenta610260de458941d2c3e0b7b0a2a9a4989d3b02b (diff)
parent4dcc2bc5ef2901c9a5e756976d063f0bb16a3f02 (diff)
Merge kozmo.(none):/usr/src/linus-2.5
into kozmo.(none):/usr/src/fbdev-2.5
-rw-r--r--CREDITS10
-rw-r--r--Documentation/DocBook/kernel-api.tmpl4
-rw-r--r--Documentation/fb/internals.txt5
-rw-r--r--Documentation/fb/sstfb.txt (renamed from Documentation/fb/README-sstfb.txt)0
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/alpha/Kconfig31
-rw-r--r--arch/arm/Kconfig21
-rw-r--r--arch/i386/Kconfig55
-rw-r--r--arch/ia64/Kconfig25
-rw-r--r--arch/m68k/Kconfig7
-rw-r--r--arch/m68knommu/Kconfig35
-rw-r--r--arch/mips/Kconfig62
-rw-r--r--arch/mips64/Kconfig23
-rw-r--r--arch/parisc/Kconfig30
-rw-r--r--arch/ppc/Kconfig22
-rw-r--r--arch/ppc64/Kconfig7
-rw-r--r--arch/sh/Kconfig55
-rw-r--r--arch/sparc/Kconfig16
-rw-r--r--arch/sparc64/Kconfig11
-rw-r--r--arch/v850/Kconfig35
-rw-r--r--arch/x86_64/Kconfig55
-rw-r--r--drivers/Makefile3
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/consolemap.c5
-rw-r--r--drivers/char/keyboard.c1
-rw-r--r--drivers/char/mem.c12
-rw-r--r--drivers/char/selection.c1
-rw-r--r--drivers/char/toshiba.c2
-rw-r--r--drivers/char/tty_io.c7
-rw-r--r--drivers/char/vc_screen.c1
-rw-r--r--drivers/char/vt.c202
-rw-r--r--drivers/char/vt_ioctl.c60
-rw-r--r--drivers/video/Kconfig411
-rw-r--r--drivers/video/Makefile58
-rw-r--r--drivers/video/S3triofb.c2
-rw-r--r--drivers/video/amifb.c2
-rw-r--r--drivers/video/anakinfb.c62
-rw-r--r--drivers/video/atafb.c2
-rw-r--r--drivers/video/aty/atyfb.h18
-rw-r--r--drivers/video/aty/atyfb_base.c99
-rw-r--r--drivers/video/aty/mach64_ct.c2
-rw-r--r--drivers/video/aty/mach64_cursor.c155
-rw-r--r--drivers/video/aty/mach64_gx.c2
-rw-r--r--drivers/video/aty128fb.c3245
-rw-r--r--drivers/video/cfbcopyarea.c511
-rw-r--r--drivers/video/cfbfillrect.c534
-rw-r--r--drivers/video/cfbimgblt.c360
-rw-r--r--drivers/video/chipsfb.c2
-rw-r--r--drivers/video/clps711xfb.c16
-rw-r--r--drivers/video/console/Kconfig221
-rw-r--r--drivers/video/console/Makefile61
-rw-r--r--drivers/video/console/dummycon.c (renamed from drivers/video/dummycon.c)11
-rw-r--r--drivers/video/console/fbcon-sti.c (renamed from drivers/video/fbcon-sti.c)64
-rw-r--r--drivers/video/console/fbcon.c2843
-rw-r--r--drivers/video/console/fbcon.h142
-rw-r--r--drivers/video/console/font.h (renamed from include/video/font.h)22
-rw-r--r--drivers/video/console/font_6x11.c (renamed from drivers/video/font_6x11.c)4
-rw-r--r--drivers/video/console/font_8x16.c (renamed from drivers/video/font_8x16.c)4
-rw-r--r--drivers/video/console/font_8x8.c (renamed from drivers/video/font_8x8.c)4
-rw-r--r--drivers/video/console/font_acorn_8x8.c (renamed from drivers/video/font_acorn_8x8.c)4
-rw-r--r--drivers/video/console/font_mini_4x6.c (renamed from drivers/video/font_mini_4x6.c)4
-rw-r--r--drivers/video/console/font_pearl_8x8.c (renamed from drivers/video/font_pearl_8x8.c)4
-rw-r--r--drivers/video/console/font_sun12x22.c (renamed from drivers/video/font_sun12x22.c)4
-rw-r--r--drivers/video/console/font_sun8x16.c (renamed from drivers/video/font_sun8x16.c)4
-rw-r--r--drivers/video/console/fonts.c (renamed from drivers/video/fonts.c)39
-rw-r--r--drivers/video/console/mdacon.c (renamed from drivers/video/mdacon.c)3
-rw-r--r--drivers/video/console/newport_con.c (renamed from drivers/video/newport_con.c)5
-rw-r--r--drivers/video/console/prom.uni (renamed from drivers/video/prom.uni)0
-rw-r--r--drivers/video/console/promcon.c (renamed from drivers/video/promcon.c)3
-rw-r--r--drivers/video/console/sti.h (renamed from drivers/video/sti.h)0
-rw-r--r--drivers/video/console/sticon.c (renamed from drivers/video/sticon.c)3
-rw-r--r--drivers/video/console/sticore.c (renamed from drivers/video/sticore.c)0
-rw-r--r--drivers/video/console/vgacon.c (renamed from drivers/video/vgacon.c)17
-rw-r--r--drivers/video/controlfb.c499
-rw-r--r--drivers/video/cyberfb.c2
-rw-r--r--drivers/video/dnfb.c18
-rw-r--r--drivers/video/epson1355fb.c2
-rw-r--r--drivers/video/fbcmap.c92
-rw-r--r--drivers/video/fbcon-accel.c188
-rw-r--r--drivers/video/fbcon-accel.h34
-rw-r--r--drivers/video/fbcon-afb.c448
-rw-r--r--drivers/video/fbcon-cfb16.c319
-rw-r--r--drivers/video/fbcon-cfb2.c225
-rw-r--r--drivers/video/fbcon-cfb24.c333
-rw-r--r--drivers/video/fbcon-cfb32.c305
-rw-r--r--drivers/video/fbcon-cfb4.c229
-rw-r--r--drivers/video/fbcon-cfb8.c294
-rw-r--r--drivers/video/fbcon-hga.c253
-rw-r--r--drivers/video/fbcon-ilbm.c296
-rw-r--r--drivers/video/fbcon-iplan2p2.c476
-rw-r--r--drivers/video/fbcon-iplan2p4.c497
-rw-r--r--drivers/video/fbcon-iplan2p8.c534
-rw-r--r--drivers/video/fbcon-mfb.c217
-rw-r--r--drivers/video/fbcon-vga-planes.c387
-rw-r--r--drivers/video/fbcon.c2508
-rw-r--r--drivers/video/fbgen.c286
-rw-r--r--drivers/video/fbmem.c252
-rw-r--r--drivers/video/fm2fb.c17
-rw-r--r--drivers/video/g364fb.c74
-rw-r--r--drivers/video/hgafb.c424
-rw-r--r--drivers/video/hitfb.c17
-rw-r--r--drivers/video/hpfb.c16
-rw-r--r--drivers/video/igafb.c485
-rw-r--r--drivers/video/imsttfb.c41
-rw-r--r--drivers/video/macfb.c22
-rw-r--r--drivers/video/macmodes.c3
-rw-r--r--drivers/video/macmodes.h (renamed from include/video/macmodes.h)0
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.c4
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c4
-rw-r--r--drivers/video/maxinefb.c48
-rw-r--r--drivers/video/modedb.c7
-rw-r--r--drivers/video/neofb.c389
-rw-r--r--drivers/video/offb.c23
-rw-r--r--drivers/video/platinumfb.c453
-rw-r--r--drivers/video/pm2fb.c2
-rw-r--r--drivers/video/pm3fb.c2
-rw-r--r--drivers/video/pmag-ba-fb.c59
-rw-r--r--drivers/video/pmagb-b-fb.c53
-rw-r--r--drivers/video/pvr2fb.c4
-rw-r--r--drivers/video/q40fb.c16
-rw-r--r--drivers/video/radeonfb.c2896
-rw-r--r--drivers/video/retz3fb.c2
-rw-r--r--drivers/video/riva/Makefile2
-rw-r--r--drivers/video/riva/accel.c427
-rw-r--r--drivers/video/riva/fbdev.c2248
-rw-r--r--drivers/video/riva/riva_hw.h1
-rw-r--r--drivers/video/riva/rivafb.h51
-rw-r--r--drivers/video/sa1100fb.c2
-rw-r--r--drivers/video/sbusfb.c2
-rw-r--r--drivers/video/sgivwfb.c62
-rw-r--r--drivers/video/sis/Makefile2
-rw-r--r--drivers/video/sis/sis_accel.c495
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c28
-rw-r--r--drivers/video/softcursor.c62
-rw-r--r--drivers/video/sstfb.c2
-rw-r--r--drivers/video/sti-bmode.h287
-rw-r--r--drivers/video/sticon-bmode.c895
-rw-r--r--drivers/video/sticore.h407
-rw-r--r--drivers/video/stifb.c1403
-rw-r--r--drivers/video/sun3fb.c2
-rw-r--r--drivers/video/tdfxfb.c533
-rw-r--r--drivers/video/tgafb.c2
-rw-r--r--drivers/video/tridentfb.c2
-rw-r--r--drivers/video/tx3912fb.c19
-rw-r--r--drivers/video/valkyriefb.c27
-rw-r--r--drivers/video/vesafb.c24
-rw-r--r--drivers/video/vfb.c36
-rw-r--r--drivers/video/vga16fb.c1401
-rw-r--r--drivers/video/vgastate.c438
-rw-r--r--drivers/video/virgefb.c2
-rw-r--r--include/linux/console.h1
-rw-r--r--include/linux/console_struct.h1
-rw-r--r--include/linux/fb.h238
-rw-r--r--include/linux/radeonfb.h15
-rw-r--r--include/linux/sisfb.h58
-rw-r--r--include/linux/vt_kern.h8
-rw-r--r--include/video/fbcon-afb.h32
-rw-r--r--include/video/fbcon-cfb16.h34
-rw-r--r--include/video/fbcon-cfb2.h32
-rw-r--r--include/video/fbcon-cfb24.h34
-rw-r--r--include/video/fbcon-cfb32.h34
-rw-r--r--include/video/fbcon-cfb4.h32
-rw-r--r--include/video/fbcon-cfb8.h34
-rw-r--r--include/video/fbcon-hga.h32
-rw-r--r--include/video/fbcon-ilbm.h32
-rw-r--r--include/video/fbcon-iplan2p2.h32
-rw-r--r--include/video/fbcon-iplan2p4.h32
-rw-r--r--include/video/fbcon-iplan2p8.h32
-rw-r--r--include/video/fbcon-mac.h32
-rw-r--r--include/video/fbcon-mfb.h32
-rw-r--r--include/video/fbcon-vga-planes.h37
-rw-r--r--include/video/fbcon-vga.h32
-rw-r--r--include/video/fbcon.h795
-rw-r--r--include/video/iga.h (renamed from drivers/video/iga.h)5
-rw-r--r--include/video/neomagic.h1
-rw-r--r--include/video/radeon.h (renamed from drivers/video/radeon.h)0
-rw-r--r--kernel/printk.c1
179 files changed, 14328 insertions, 19700 deletions
diff --git a/CREDITS b/CREDITS
index 8b794197d3ec..6a86e079496c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2842,6 +2842,16 @@ S: Klosterweg 28 / i309
S: 76131 Karlsruhe
S: Germany
+N: James Simmons
+E: jsimmons@users.sf.net
+D: Frame buffer device maintainer
+D: input layer developement
+D: tty/console layer
+D: various mipsel devices
+S: 115 Carmel Avenue
+S: El Cerrito CA 94530
+S: USA
+
N: Jaspreet Singh
E: jaspreet@sangoma.com
W: www.sangoma.com
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 325a9447e073..f7b088432595 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -365,7 +365,7 @@ KAO -->
!Edrivers/video/fbmem.c
</sect1>
<sect1><title>Frame Buffer Console</title>
-!Edrivers/video/fbcon.c
+!Edrivers/video/console/fbcon.c
</sect1>
<sect1><title>Frame Buffer Colormap</title>
!Edrivers/video/fbcmap.c
@@ -385,7 +385,7 @@ KAO -->
!Idrivers/video/macmodes.c
</sect1>
<sect1><title>Frame Buffer Fonts</title>
-!Idrivers/video/fonts.c
+!Idrivers/video/console/fonts.c
</sect1>
</chapter>
<!-- Needs ksyms to list additional exported symbols, but no specific doc.
diff --git a/Documentation/fb/internals.txt b/Documentation/fb/internals.txt
index a73d721d7bba..9b2a2b2f3e57 100644
--- a/Documentation/fb/internals.txt
+++ b/Documentation/fb/internals.txt
@@ -3,6 +3,7 @@ This is a first start for some documentation about frame buffer device
internals.
Geert Uytterhoeven <geert@linux-m68k.org>, 21 July 1998
+James Simmons <jsimmons@user.sf.net>, Nov 26 2002
--------------------------------------------------------------------------------
@@ -44,10 +45,6 @@ are defined in <linux/fb.h>.
Device dependent information that uniquely defines the video mode for this
particular piece of hardware.
- - struct display
-
- Interface between the frame buffer device and the console driver.
-
--------------------------------------------------------------------------------
diff --git a/Documentation/fb/README-sstfb.txt b/Documentation/fb/sstfb.txt
index b6d9d923fbb7..b6d9d923fbb7 100644
--- a/Documentation/fb/README-sstfb.txt
+++ b/Documentation/fb/sstfb.txt
diff --git a/MAINTAINERS b/MAINTAINERS
index b4f0efbace88..d282eb76988d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -637,6 +637,13 @@ M: kevin.curtis@farsite.co.uk
W: http://www.farsite.co.uk/
S: Supported
+FRAMEBUFFER LAYER
+P: James Simmons, Geert Uytterhoeven
+M: jsimmons@users.sf.net, geert@linux-m68k.org
+L: linux-fbdev-devel@lists.sourceforge.net
+W: http://www.linux-fbdev.org
+S: Supported
+
FILE LOCKING (flock() and fcntl()/lockf())
P: Matthew Wilcox
M: matthew@wil.cx
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index ac17f1cbcffb..33175c774128 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -900,39 +900,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- Say Y.
-
-# if [ "$CONFIG_PCI" = "y" -a "$CONFIG_VGA_CONSOLE" = "y" ]; then
-# bool ' Allow VGA on any bus?' CONFIG_VGA_HOSE
-# if [ "$CONFIG_VGA_HOSE" = "y" ]; then
-# define_bool CONFIG_DUMMY_CONSOLE y
-# fi
-# fi
source "drivers/video/Kconfig"
-config PCI_CONSOLE
- bool
- depends on FB
- default y
-
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4637eccd0d87..f887b250fee1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1047,29 +1047,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- depends on !ARCH_ACORN && !ARCH_EBSA110
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- Say Y.
-
source "drivers/video/Kconfig"
-endmenu
-
-
menu "Sound"
depends on ARCH_ACORN || ARCH_CLPS7500 || ARCH_TBOX || ARCH_SHARK || ARCH_SA1100 || PCI
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 073355b7deff..6ebd4c56faba 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -1443,63 +1443,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- Say Y.
-
-config VIDEO_SELECT
- bool "Video mode selection support"
- ---help---
- This enables support for text mode selection on kernel startup. If
- you want to take advantage of some high-resolution text mode your
- card's BIOS offers, but the traditional Linux utilities like
- SVGATextMode don't, you can say Y here and set the mode using the
- "vga=" option from your boot loader (lilo or loadlin) or set
- "vga=ask" which brings up a video mode menu on kernel startup. (Try
- "man bootparam" or see the documentation of your boot loader about
- how to pass options to the kernel.)
-
- Read the file <file:Documentation/svga.txt> for more information
- about the Video mode selection support. If unsure, say N.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
- tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
- ---help---
- Say Y here if you have an old MDA or monochrome Hercules graphics
- adapter in your system acting as a second head ( = video card). You
- will then be able to use two monitors with your Linux system. Do not
- say Y here if your MDA card is the primary card in your system; the
- normal VGA driver will handle it.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want).
- The module will be called mdacon.o. If you want to compile it as
- a module, say M here and read <file:Documentation/modules.txt>.
-
- If unsure, say N.
-
source "drivers/video/Kconfig"
-endif
-
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 7708b29a0f90..7c1bc5127807 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -729,33 +729,8 @@ source "fs/Kconfig"
if !IA64_HP_SIM
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- Say Y.
-
source "drivers/video/Kconfig"
-config PCI_CONSOLE
- bool
- depends on FB
- default y
-
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index ba138ab925ff..59e449a9187f 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -2309,15 +2309,8 @@ endmenu
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
source "drivers/video/Kconfig"
-endmenu
-
-
menu "Kernel hacking"
config DEBUG_KERNEL
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index e199b0a322cd..333eb3c5fb98 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -672,43 +672,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- If unsure, say N.
-
-config VIDEO_SELECT
- bool "Video mode selection support"
- ---help---
- This enables support for text mode selection on kernel startup. If
- you want to take advantage of some high-resolution text mode your
- card's BIOS offers, but the traditional Linux utilities like
- SVGATextMode don't, you can say Y here and set the mode using the
- "vga=" option from your boot loader (lilo or loadlin) or set
- "vga=ask" which brings up a video mode menu on kernel startup. (Try
- "man bootparam" or see the documentation of your boot loader about
- how to pass options to the kernel.)
-
- Read the file <file:Documentation/svga.txt> for more information
- about the Video mode selection support. If unsure, say N.
-
source "drivers/video/Kconfig"
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 61aefc45cc10..fb570cf0ae57 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1115,28 +1115,6 @@ config VT_CONSOLE
bool "Support for console on virtual terminal"
depends on VT
-config SGI_NEWPORT_CONSOLE
- tristate "SGI Newport Console support"
- depends on VT
- help
- Say Y here if you want the console on the Newport aka XL graphics
- card of your Indy. Most people say Y here.
-
-config DUMMY_CONSOLE
- bool
- depends on VT && SGI_NEWPORT_CONSOLE!=y
- default y
-
-config FONT_8x16
- bool
- depends on VT && SGI_NEWPORT_CONSOLE=y
- default y
- help
- This is the "high resolution" font for the VGA frame buffer (the one
- provided by the VGA text console 80x25 mode.
-
- If unsure, say Y.
-
config PSMOUSE
bool "PS/2 mouse support (aka \"auxiliary device\")"
---help---
@@ -1192,48 +1170,8 @@ endmenu
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- Say Y.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
- tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
- ---help---
- Say Y here if you have an old MDA or monochrome Hercules graphics
- adapter in your system acting as a second head ( = video card). You
- will then be able to use two monitors with your Linux system. Do not
- say Y here if your MDA card is the primary card in your system; the
- normal VGA driver will handle it.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want).
- The module will be called mdacon.o. If you want to compile it as
- a module, say M here and read <file:Documentation/modules.txt>.
-
- If unsure, say N.
-
source "drivers/video/Kconfig"
-endif
-
-endmenu
-
-
menu "Sound"
depends on !DECSTATION
diff --git a/arch/mips64/Kconfig b/arch/mips64/Kconfig
index 40620ceced66..571fd0f25375 100644
--- a/arch/mips64/Kconfig
+++ b/arch/mips64/Kconfig
@@ -593,31 +593,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
source "drivers/video/Kconfig"
-config SGI_NEWPORT_CONSOLE
- tristate "SGI Newport Console support"
- depends on SGI_IP22
- help
- Say Y here if you want the console on the Newport aka XL graphics
- card of your Indy. Most people say Y here.
-
-config DUMMY_CONSOLE
- bool
- depends on SGI_IP22 && SGI_NEWPORT_CONSOLE!=y
- default y
-
-config FONT_8x16
- bool
- depends on SGI_IP22 && SGI_NEWPORT_CONSOLE=y
- default y
-
-endmenu
-
config KCORE_ELF
bool
depends on PROC_FS
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index c1a28b2e814d..3104b344cf09 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -335,38 +335,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config STI_CONSOLE
- bool "STI console"
- help
- STI refers to the HP "Standard Text Interface" which is a set of
- BIOS routines contained in a ROM chip in HP PA-RISC based machines.
- Enabling this option will give you an 8 color text console on
- most of the PA-RISC systems.
- Really old HP boxes may not have STI, in which case you must use the
- PDC console or your primary serial port as a console.
-
- The text console uses a strange memory layout, and changing the
- plane mask to create colored characters requires calls to the STI
- routines. Because of that do not expect it to be actually very fast,
- but it is sufficient for basic text console functions, including fonts.
-
- The alternative is to use your primary serial port as a console.
-
- It is safe to enable this option, so you should probably say "Y".
-
-config DUMMY_CONSOLE
- bool
- depends on STI_CONSOLE || SERIAL_8250_CONSOLE
- default y
-
source "drivers/video/Kconfig"
-endmenu
-
menu "Sound"
config SOUND
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 431ef90e5b6c..3c55bfb40f21 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1054,11 +1054,6 @@ config CMDLINE
some command-line options at build time by entering them here. In
most cases you will need to specify the root device here.
-config FB_CONSOLE
- bool
- depends on APUS
- default y
-
config AMIGA
bool
depends on APUS
@@ -1467,25 +1462,8 @@ source "net/irda/Kconfig"
source "drivers/isdn/Kconfig"
-
-menu "Console drivers"
-
-config VGA_CONSOLE
- bool "VGA text console"
- depends on !4xx && !8xx
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. This can be
- useful on PReP systems and IBM RS/6000 or pSeries machines but is of
- limited usefulness on Apple machines.
-
- Say N here if you have an Apple machine.
-
source "drivers/video/Kconfig"
-endmenu
-
-
menu "iSeries device drivers"
depends on PPC_ISERIES
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index 9cdcc3d85124..4cb9f52630f0 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -410,15 +410,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
source "drivers/video/Kconfig"
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 367e9abb76f0..24d33e1d5734 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1190,63 +1190,8 @@ source "fs/Kconfig"
source "drivers/media/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- Say Y.
-
-config VIDEO_SELECT
- bool "Video mode selection support"
- ---help---
- This enables support for text mode selection on kernel startup. If
- you want to take advantage of some high-resolution text mode your
- card's BIOS offers, but the traditional Linux utilities like
- SVGATextMode don't, you can say Y here and set the mode using the
- "vga=" option from your boot loader (lilo or loadlin) or set
- "vga=ask" which brings up a video mode menu on kernel startup. (Try
- "man bootparam" or see the documentation of your boot loader about
- how to pass options to the kernel.)
-
- Read the file <file:Documentation/svga.txt> for more information
- about the Video mode selection support. If unsure, say N.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
- tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
- ---help---
- Say Y here if you have an old MDA or monochrome Hercules graphics
- adapter in your system acting as a second head ( = video card). You
- will then be able to use two monitors with your Linux system. Do not
- say Y here if your MDA card is the primary card in your system; the
- normal VGA driver will handle it.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want).
- The module will be called mdacon.o. If you want to compile it as
- a module, say M here and read <file:Documentation/modules.txt>.
-
- If unsure, say N.
-
source "drivers/video/Kconfig"
-endif
-
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index c50de97230f1..cc5d534ec3b1 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -417,24 +417,8 @@ config PRINTER
endmenu
-
-menu "Console drivers"
-
-config PROM_CONSOLE
- bool "PROM console"
- help
- Say Y to build a console driver for Sun machines that uses the
- terminal emulation built into their console PROMS.
-
-config DUMMY_CONSOLE
- bool
- depends on !PROM_CONSOLE
- default y
-
source "drivers/video/Kconfig"
-endmenu
-
source "drivers/mtd/Kconfig"
source "drivers/serial/Kconfig"
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index c61e098e0f56..f28c476dd5da 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -530,19 +530,8 @@ config WATCHDOG_RIO
endmenu
-
-menu "Console drivers"
-
-config PROM_CONSOLE
- bool "PROM console"
- help
- Say Y to build a console driver for Sun machines that uses the
- terminal emulation built into their console PROMS.
-
source "drivers/video/Kconfig"
-endmenu
-
source "drivers/serial/Kconfig"
source "drivers/sbus/char/Kconfig"
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index bdd17d8a015b..c96e55a6aebd 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -365,43 +365,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- If unsure, say N.
-
-config VIDEO_SELECT
- bool "Video mode selection support"
- ---help---
- This enables support for text mode selection on kernel startup. If
- you want to take advantage of some high-resolution text mode your
- card's BIOS offers, but the traditional Linux utilities like
- SVGATextMode don't, you can say Y here and set the mode using the
- "vga=" option from your boot loader (lilo or loadlin) or set
- "vga=ask" which brings up a video mode menu on kernel startup. (Try
- "man bootparam" or see the documentation of your boot loader about
- how to pass options to the kernel.)
-
- Read the file <file:Documentation/svga.txt> for more information
- about the Video mode selection support. If unsure, say N.
-
source "drivers/video/Kconfig"
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 867d54bea665..3d5d90fddec6 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -588,63 +588,8 @@ source "drivers/media/Kconfig"
source "fs/Kconfig"
-
-menu "Console drivers"
- depends on VT
-
-config VGA_CONSOLE
- bool "VGA text console"
- help
- Saying Y here will allow you to use Linux in text mode through a
- display that complies with the generic VGA standard. Virtually
- everyone wants that.
-
- The program SVGATextMode can be used to utilize SVGA video cards to
- their full potential in text mode. Download it from
- <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
- Say Y.
-
-config VIDEO_SELECT
- bool "Video mode selection support"
- ---help---
- This enables support for text mode selection on kernel startup. If
- you want to take advantage of some high-resolution text mode your
- card's BIOS offers, but the traditional Linux utilities like
- SVGATextMode don't, you can say Y here and set the mode using the
- "vga=" option from your boot loader (lilo or loadlin) or set
- "vga=ask" which brings up a video mode menu on kernel startup. (Try
- "man bootparam" or see the documentation of your boot loader about
- how to pass options to the kernel.)
-
- Read the file <file:Documentation/svga.txt> for more information
- about the Video mode selection support. If unsure, say N.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
- tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
- ---help---
- Say Y here if you have an old MDA or monochrome Hercules graphics
- adapter in your system acting as a second head ( = video card). You
- will then be able to use two monitors with your Linux system. Do not
- say Y here if your MDA card is the primary card in your system; the
- normal VGA driver will handle it.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want).
- The module will be called mdacon.o. If you want to compile it as
- a module, say M here and read <file:Documentation/modules.txt>.
-
- If unsure, say N.
-
source "drivers/video/Kconfig"
-endif
-
-endmenu
-
-
menu "Sound"
config SOUND
diff --git a/drivers/Makefile b/drivers/Makefile
index 2d983c7d9271..b882bfe78399 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_FC4) += fc4/
obj-$(CONFIG_SCSI) += scsi/
obj-$(CONFIG_FUSION) += message/
obj-$(CONFIG_IEEE1394) += ieee1394/
-obj-y += cdrom/
+obj-y += cdrom/ video/
obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_PCMCIA) += pcmcia/
obj-$(CONFIG_DIO) += dio/
@@ -30,7 +30,6 @@ obj-$(CONFIG_ZORRO) += zorro/
obj-$(CONFIG_ALL_PPC) += macintosh/
obj-$(CONFIG_MAC) += macintosh/
obj-$(CONFIG_SGI) += sgi/
-obj-$(CONFIG_VT) += video/
obj-$(CONFIG_PARIDE) += block/paride/
obj-$(CONFIG_TC) += tc/
obj-$(CONFIG_USB) += usb/
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 1ac447432022..8b1b9a2a3c1c 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -12,7 +12,7 @@ obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-export-objs := busmouse.o vt.o generic_serial.o ip2main.o \
+export-objs := busmouse.o vt.o generic_serial.o ip2main.o consolemap.o\
ite_gpio.o keyboard.o misc.o nvram.o random.o rtc.o \
selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index bf55df922e45..72ba2932fead 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -11,6 +11,8 @@
* Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
*/
+#include <linux/config.h>
+#include <linux/module.h>
#include <linux/kd.h>
#include <linux/errno.h>
#include <linux/mm.h>
@@ -19,7 +21,6 @@
#include <linux/tty.h>
#include <asm/uaccess.h>
#include <linux/consolemap.h>
-#include <linux/console_struct.h>
#include <linux/vt_kern.h>
static unsigned short translations[][256] = {
@@ -681,3 +682,5 @@ console_map_init(void)
if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
con_set_default_unimap(i);
}
+
+EXPORT_SYMBOL(con_copy_unimap);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index ddb472255a6a..bc1dfea7021d 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/console_struct.h>
#include <linux/kbd_kern.h>
#include <linux/kbd_diacr.h>
#include <linux/vt_kern.h>
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 9e888905fd27..2639b087e5f4 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -33,12 +33,6 @@ extern int i2c_init_all(void);
#ifdef CONFIG_FB
extern void fbmem_init(void);
#endif
-#ifdef CONFIG_PROM_CONSOLE
-extern void prom_con_init(void);
-#endif
-#ifdef CONFIG_MDA_CONSOLE
-extern void mda_console_init(void);
-#endif
#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
extern void tapechar_init(void);
#endif
@@ -686,12 +680,6 @@ int __init chr_dev_init(void)
#if defined (CONFIG_FB)
fbmem_init();
#endif
-#if defined (CONFIG_PROM_CONSOLE)
- prom_con_init();
-#endif
-#if defined (CONFIG_MDA_CONSOLE)
- mda_console_init();
-#endif
tty_init();
#ifdef CONFIG_M68K_PRINTER
lp_m68k_init();
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 3295c7d6e6d2..6aa4932e7c4a 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -22,7 +22,6 @@
#include <linux/vt_kern.h>
#include <linux/consolemap.h>
-#include <linux/console_struct.h>
#include <linux/selection.h>
#ifndef MIN
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index 21cfdd3f1417..fc93acbc6dc1 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -210,7 +210,7 @@ static int tosh_emulate_fan(SMMRegisters *regs)
/*
* Put the laptop into System Management Mode
*/
-static int tosh_smm(SMMRegisters *regs)
+int tosh_smm(SMMRegisters *regs)
{
int eax;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index cf880e8cacae..b39feeb6a4bc 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1509,6 +1509,13 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
return -EFAULT;
if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg)))
return 0;
+#ifdef CONFIG_VT
+ if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) {
+ unsigned int currcons = minor(tty->device) - tty->driver.minor_start;
+ if (vc_resize(currcons, tmp_ws.ws_col, tmp_ws.ws_row))
+ return -ENXIO;
+ }
+#endif
if (tty->pgrp > 0)
kill_pg(tty->pgrp, SIGWINCH, 1);
if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 2fe40dfbd425..9e33415f8cdc 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -32,7 +32,6 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/vt_kern.h>
-#include <linux/console_struct.h>
#include <linux/selection.h>
#include <linux/kbd_kern.h>
#include <linux/console.h>
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 7ace02f718fb..21699dc053f9 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -90,7 +90,6 @@
#include <linux/devfs_fs_kernel.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
-#include <linux/console_struct.h>
#include <linux/kbd_kern.h>
#include <linux/consolemap.h>
#include <linux/timer.h>
@@ -127,6 +126,15 @@ const struct consw *conswitchp;
extern void vcs_make_devfs (unsigned int index, int unregister);
extern void console_map_init(void);
+#ifdef CONFIG_PROM_CONSOLE
+extern void prom_con_init(void);
+#endif
+#ifdef CONFIG_MDA_CONSOLE
+extern void mda_console_init(void);
+#endif
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+extern int fb_console_init(void);
+#endif
static struct tty_struct *console_table[MAX_NR_CONSOLES];
static struct termios *console_termios[MAX_NR_CONSOLES];
@@ -691,106 +699,106 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
return 0;
}
+inline int resize_screen(int currcons, int width, int height)
+{
+ /* Resizes the resolution of the display adapater */
+ int err = 0;
+
+ if (vcmode != KD_GRAPHICS && sw->con_resize)
+ err = sw->con_resize(vc_cons[currcons].d, width, height);
+ return err;
+}
+
/*
* Change # of rows and columns (0 means unchanged/the size of fg_console)
* [this is to be used together with some user program
* like resize that changes the hardware videomode]
*/
-int vc_resize(unsigned int lines, unsigned int cols,
- unsigned int first, unsigned int last)
-{
- unsigned int cc, ll, ss, sr, todo = 0;
- unsigned int currcons = fg_console, i;
- unsigned short *newscreens[MAX_NR_CONSOLES];
-
- cc = (cols ? cols : video_num_columns);
- ll = (lines ? lines : video_num_lines);
- sr = cc << 1;
- ss = sr * ll;
-
- for (currcons = first; currcons <= last; currcons++) {
- if (!vc_cons_allocated(currcons) ||
- (cc == video_num_columns && ll == video_num_lines))
- newscreens[currcons] = NULL;
- else {
- unsigned short *p = (unsigned short *) kmalloc(ss, GFP_USER);
- if (!p) {
- for (i = first; i < currcons; i++)
- if (newscreens[i])
- kfree(newscreens[i]);
- return -ENOMEM;
- }
- newscreens[currcons] = p;
- todo++;
- }
- }
- if (!todo)
+int vc_resize(int currcons, unsigned int cols, unsigned int lines)
+{
+ unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
+ unsigned int old_cols, old_rows, old_row_size, old_screen_size;
+ unsigned int new_cols, new_rows, new_row_size, new_screen_size;
+ unsigned short *newscreen;
+
+ if (!vc_cons_allocated(currcons))
+ return -ENXIO;
+
+ new_cols = (cols ? cols : video_num_columns);
+ new_rows = (lines ? lines : video_num_lines);
+ new_row_size = new_cols << 1;
+ new_screen_size = new_row_size * new_rows;
+
+ if (new_cols == video_num_columns && new_rows == video_num_lines)
return 0;
- for (currcons = first; currcons <= last; currcons++) {
- unsigned int occ, oll, oss, osr;
- unsigned long ol, nl, nlend, rlth, rrem;
- if (!newscreens[currcons] || !vc_cons_allocated(currcons))
- continue;
+ newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);
+ if (!newscreen)
+ return -ENOMEM;
- oll = video_num_lines;
- occ = video_num_columns;
- osr = video_size_row;
- oss = screenbuf_size;
-
- video_num_lines = ll;
- video_num_columns = cc;
- video_size_row = sr;
- screenbuf_size = ss;
-
- rlth = min(osr, sr);
- rrem = sr - rlth;
- ol = origin;
- nl = (long) newscreens[currcons];
- nlend = nl + ss;
- if (ll < oll)
- ol += (oll - ll) * osr;
-
- update_attr(currcons);
-
- while (ol < scr_end) {
- scr_memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
- if (rrem)
- scr_memsetw((void *)(nl + rlth), video_erase_char, rrem);
- ol += osr;
- nl += sr;
- }
- if (nlend > nl)
- scr_memsetw((void *) nl, video_erase_char, nlend - nl);
- if (kmalloced)
- kfree(screenbuf);
- screenbuf = newscreens[currcons];
- kmalloced = 1;
- screenbuf_size = ss;
- set_origin(currcons);
+ old_rows = video_num_lines;
+ old_cols = video_num_columns;
+ old_row_size = video_size_row;
+ old_screen_size = screenbuf_size;
- /* do part of a reset_terminal() */
- top = 0;
- bottom = video_num_lines;
- gotoxy(currcons, x, y);
- save_cur(currcons);
-
- if (console_table[currcons]) {
- struct winsize ws, *cws = &console_table[currcons]->winsize;
- memset(&ws, 0, sizeof(ws));
- ws.ws_row = video_num_lines;
- ws.ws_col = video_num_columns;
- if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
- console_table[currcons]->pgrp > 0)
- kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
- *cws = ws;
- }
+ video_num_lines = new_rows;
+ video_num_columns = new_cols;
+ video_size_row = new_row_size;
+ screenbuf_size = new_screen_size;
- if (IS_VISIBLE)
- update_screen(currcons);
+ err = resize_screen(currcons, new_cols, new_rows);
+ if (err)
+ return err;
+
+ rlth = min(old_row_size, new_row_size);
+ rrem = new_row_size - rlth;
+ old_origin = origin;
+ new_origin = (long) newscreen;
+ new_scr_end = new_origin + new_screen_size;
+ if (new_rows < old_rows)
+ old_origin += (old_rows - new_rows) * old_row_size;
+
+ update_attr(currcons);
+
+ while (old_origin < scr_end) {
+ scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth);
+ if (rrem)
+ scr_memsetw((void *)(new_origin + rlth), video_erase_char, rrem);
+ old_origin += old_row_size;
+ new_origin += new_row_size;
}
+ if (new_scr_end > new_origin)
+ scr_memsetw((void *) new_origin, video_erase_char, new_scr_end - new_origin);
+ if (kmalloced)
+ kfree(screenbuf);
+ screenbuf = newscreen;
+ kmalloced = 1;
+ screenbuf_size = new_screen_size;
+ if (IS_VISIBLE)
+ err = resize_screen(currcons, new_cols, new_rows);
+ set_origin(currcons);
- return 0;
+ /* do part of a reset_terminal() */
+ top = 0;
+ bottom = video_num_lines;
+ gotoxy(currcons, x, y);
+ save_cur(currcons);
+
+ if (vc_cons[currcons].d->vc_tty) {
+ struct winsize ws, *cws = &vc_cons[currcons].d->vc_tty->winsize;
+
+ memset(&ws, 0, sizeof(ws));
+ ws.ws_row = video_num_lines;
+ ws.ws_col = video_num_columns;
+ if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
+ vc_cons[currcons].d->vc_tty->pgrp > 0)
+ kill_pg(vc_cons[currcons].d->vc_tty->pgrp, SIGWINCH, 1);
+ *cws = ws;
+ }
+
+ if (IS_VISIBLE)
+ update_screen(currcons);
+ return err;
}
@@ -1200,7 +1208,7 @@ static void set_mode(int currcons, int on_off)
case 3: /* 80/132 mode switch unimplemented */
deccolm = on_off;
#if 0
- (void) vc_resize(video_num_lines, deccolm ? 132 : 80);
+ (void) vc_resize(deccolm ? 132 : 80, video_num_lines);
/* this alone does not suffice; some user mode
utility has to change the hardware regs */
#endif
@@ -2525,6 +2533,15 @@ int __init vty_init(void)
kbd_init();
console_map_init();
+#ifdef CONFIG_PROM_CONSOLE
+ prom_con_init();
+#endif
+#ifdef CONFIG_MDA_CONSOLE
+ mda_console_init();
+#endif
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+ fb_console_init();
+#endif
con_init_devfs();
vcs_init();
return 0;
@@ -3021,10 +3038,15 @@ EXPORT_SYMBOL(default_grn);
EXPORT_SYMBOL(default_blu);
EXPORT_SYMBOL(video_font_height);
EXPORT_SYMBOL(video_scan_lines);
+EXPORT_SYMBOL(vc_cons_allocated);
+EXPORT_SYMBOL(update_region);
+EXPORT_SYMBOL(redraw_screen);
EXPORT_SYMBOL(vc_resize);
EXPORT_SYMBOL(fg_console);
EXPORT_SYMBOL(console_blank_hook);
+EXPORT_SYMBOL(console_blanked);
EXPORT_SYMBOL(vt_cons);
+EXPORT_SYMBOL(vc_cons);
#ifndef VT_SINGLE_DRIVER
EXPORT_SYMBOL(take_over_console);
EXPORT_SYMBOL(give_up_console);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index fcdb5208acea..cda2f20d8308 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -810,7 +810,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (get_user(ll, &vtsizes->v_rows) ||
get_user(cc, &vtsizes->v_cols))
return -EFAULT;
- return vc_resize_all(ll, cc);
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ vc_resize(i, cc, ll);
+ return 0;
}
case VT_RESIZEX:
@@ -829,37 +831,33 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
__get_user(vcol, &vtconsize->v_vcol);
__get_user(ccol, &vtconsize->v_ccol);
vlin = vlin ? vlin : video_scan_lines;
- if ( clin )
- {
- if ( ll )
- {
- if ( ll != vlin/clin )
- return -EINVAL; /* Parameters don't add up */
- }
- else
- ll = vlin/clin;
- }
- if ( vcol && ccol )
- {
- if ( cc )
- {
- if ( cc != vcol/ccol )
- return -EINVAL;
- }
- else
- cc = vcol/ccol;
- }
-
- if ( clin > 32 )
- return -EINVAL;
+ if (clin) {
+ if (ll) {
+ if (ll != vlin/clin)
+ return -EINVAL; /* Parameters don't add up */
+ } else
+ ll = vlin/clin;
+ }
+ if (vcol && ccol) {
+ if (cc) {
+ if (cc != vcol/ccol)
+ return -EINVAL;
+ } else
+ cc = vcol/ccol;
+ }
+
+ if (clin > 32)
+ return -EINVAL;
- if ( vlin )
- video_scan_lines = vlin;
- if ( clin )
- video_font_height = clin;
-
- return vc_resize_all(ll, cc);
- }
+ if (vlin)
+ video_scan_lines = vlin;
+ if (clin)
+ video_font_height = clin;
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ vc_resize(i, cc, ll);
+ return 0;
+ }
case PIO_FONT: {
struct console_font_op op;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index cdac597766c1..e0f0af3145ba 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2,10 +2,10 @@
# Video configuration
#
-menu "Frame-buffer support"
+menu "Graphics support"
config FB
- bool "Support for frame buffer devices (EXPERIMENTAL)"
+ bool "Support for frame buffer devices"
---help---
The frame buffer device provides an abstraction for the graphics
hardware. It represents the frame buffer of some video hardware and
@@ -38,14 +38,9 @@ config FB
(e.g. an accelerated X server) and that are not frame buffer
device-aware may cause unexpected results. If unsure, say N.
-config DUMMY_CONSOLE
- bool
- depends on FB
- default y
-
config FB_CLGEN
- tristate "Cirrus Logic support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && (AMIGA || PCI)
+ tristate "Cirrus Logic support"
+ depends on FB && (AMIGA || PCI)
---help---
This enables support for Cirrus Logic GD542x/543x based boards on
Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@@ -59,8 +54,8 @@ config FB_CLGEN
before you next recompile the kernel.
config FB_PM2
- tristate "Permedia2 support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && (AMIGA || PCI)
+ tristate "Permedia2 support"
+ depends on FB && (AMIGA || PCI)
help
This is the frame buffer device driver for the Permedia2 AGP frame
buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a
@@ -206,8 +201,8 @@ config FB_CYBER
Cybervision 64 3D card, as they use incompatible video chips.
config FB_VIRGE
- bool "Amiga CyberVision3D support (EXPERIMENTAL)"
- depends on FB && ZORRO && EXPERIMENTAL
+ bool "Amiga CyberVision3D support "
+ depends on FB && ZORRO
help
This enables support for the Cybervision 64/3D graphics card from
Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -217,16 +212,16 @@ config FB_VIRGE
Cybervision 64 card, as they use incompatible video chips.
config FB_RETINAZ3
- tristate "Amiga RetinaZ3 support (EXPERIMENTAL)"
- depends on FB && ZORRO && EXPERIMENTAL
+ tristate "Amiga RetinaZ3 support"
+ depends on FB && ZORRO
help
This enables support for the Retina Z3 graphics card. Say N unless
you have a Retina Z3 or plan to get one before you next recompile
the kernel.
config FB_FM2
- bool "Amiga FrameMaster II/Rainbow II support (EXPERIMENTAL)"
- depends on FB && ZORRO && EXPERIMENTAL
+ bool "Amiga FrameMaster II/Rainbow II support"
+ depends on FB && ZORRO
help
This is the frame buffer device driver for the Amiga FrameMaster
card from BSC (exhibited 1992 but not shipped as a CBM product).
@@ -238,33 +233,6 @@ config FB_ATARI
This is the frame buffer device driver for the builtin graphics
chipset found in Ataris.
-config FB_ATY
- tristate "ATI Mach64 display support (EXPERIMENTAL)" if EXPERIMENTAL && PCI
- depends on FB
- help
- This driver supports graphics boards with the ATI Mach64 chips.
- Say Y if you have such a graphics board.
-
- The driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called atyfb.o. If you want to compile it as a
- module, say M here and read <file:Documentation/modules.txt>.
-
-config FB_ATY
- prompt "ATI Mach64 display support"
- depends on FB && (SPARC64 && PCI && FB_PCI || ATARI)
-
-config FB_ATY_GX
- bool "Mach64 GX support (EXPERIMENTAL)" if EXPERIMENTAL && PCI
- depends on FB_ATY
- default y if ATARI
- help
- Say Y here to support use of the ATI Mach64 Graphics Expression
- board (or other boards based on the Mach64 GX chipset) as a
- framebuffer device. The ATI product support page for these boards
- is at
- <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
-
config FB_OF
bool "Open Firmware frame buffer device support"
depends on FB && PPC && ALL_PPC
@@ -302,7 +270,7 @@ config FB_CT65550
config FB_IMSTT
bool "IMS Twin Turbo display support"
- depends on FB && PPC
+ depends on FB && PCI
help
The IMS Twin Turbo is a PCI-based frame buffer card bundled with
many Macintosh and compatible computers.
@@ -368,15 +336,20 @@ config FB_TGA
config FB_VESA
bool "VESA VGA graphics console"
- depends on FB && X86
+ depends on FB && (X86 || X86_64)
help
This is the frame buffer device driver for generic VESA 2.0
compliant graphic cards. The older VESA 1.2 cards are not supported.
You will get a boot time penguin logo at no additional cost. Please
read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
+config VIDEO_SELECT
+ bool
+ depends on FB_VESA
+ default y
+
config FB_HGA
- tristate "Hercules mono graphics console (EXPERIMENTAL)"
+ tristate "Hercules mono graphics console"
depends on FB && X86
help
Say Y here if you have a Hercules mono graphics card.
@@ -486,8 +459,8 @@ config E1355_FB_BASE
discussion.
config FB_RIVA
- tristate "nVidia Riva support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "nVidia Riva support"
+ depends on FB && PCI
help
This driver supports graphics boards with the nVidia Riva/Geforce
chips.
@@ -499,8 +472,8 @@ config FB_RIVA
module, say M here and read <file:Documentation/modules.txt>.
config FB_MATROX
- tristate "Matrox acceleration (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "Matrox acceleration"
+ depends on FB && PCI
---help---
Say Y here if you have a Matrox Millennium, Matrox Millennium II,
Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
@@ -654,19 +627,9 @@ config FB_MATROX_MULTIHEAD
There is no need for enabling 'Matrox multihead support' if you have
only one Matrox card in the box.
-config FB_ATY_CT
- bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" if EXPERIMENTAL
- depends on PCI && FB_ATY
- default y if SPARC64 && FB_PCI
- help
- Say Y here to support use of ATI's 64-bit Rage boards (or other
- boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
- framebuffer device. The ATI product support page for these boards
- is at <http://support.ati.com/products/pc/mach64/>.
-
config FB_RADEON
- tristate "ATI Radeon display support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "ATI Radeon display support"
+ depends on FB && PCI
help
Choose this option if you want to use an ATI Radeon graphics card as
a framebuffer device. There are both PCI and AGP versions. You
@@ -675,8 +638,8 @@ config FB_RADEON
<http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
config FB_ATY128
- tristate "ATI Rage128 display support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "ATI Rage128 display support"
+ depends on FB && PCI
help
This driver supports graphics boards with the ATI Rage128 chips.
Say Y if you have such a graphics board and read
@@ -687,9 +650,42 @@ config FB_ATY128
module will be called aty128fb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
+config FB_ATY
+ tristate "ATI Mach64 display support" if PCI || ATARI
+ depends on FB
+ help
+ This driver supports graphics boards with the ATI Mach64 chips.
+ Say Y if you have such a graphics board.
+
+ The driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called atyfb.o. If you want to compile it as a
+ module, say M here and read <file:Documentation/modules.txt>.
+
+config FB_ATY_CT
+ bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
+ depends on PCI && FB_ATY
+ default y if SPARC64 && FB_PCI
+ help
+ Say Y here to support use of ATI's 64-bit Rage boards (or other
+ boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
+ framebuffer device. The ATI product support page for these boards
+ is at <http://support.ati.com/products/pc/mach64/>.
+
+config FB_ATY_GX
+ bool "Mach64 GX support" if PCI
+ depends on FB_ATY
+ default y if ATARI
+ help
+ Say Y here to support use of the ATI Mach64 Graphics Expression
+ board (or other boards based on the Mach64 GX chipset) as a
+ framebuffer device. The ATI product support page for these boards
+ is at
+ <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
+
config FB_SIS
- tristate "SIS acceleration (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "SIS acceleration"
+ depends on FB && PCI
help
This is the frame buffer device driver for the SiS 630 and 640 Super
Socket 7 UMA cards. Specs available at <http://www.sis.com.tw/>.
@@ -710,8 +706,8 @@ config FB_SIS_315
card. Specs available at <http://www.sis.com.tw/>.
config FB_NEOMAGIC
- tristate "NeoMagic display support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "NeoMagic display support"
+ depends on FB && PCI
help
This driver supports notebooks with NeoMagic PCI chips.
Say Y if you have such a graphics card.
@@ -722,8 +718,8 @@ config FB_NEOMAGIC
module, say M here and read Documentation/modules.txt.
config FB_3DFX
- tristate "3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "3Dfx Banshee/Voodoo3 display support"
+ depends on FB && PCI
help
This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
chips. Say Y if you have such a graphics board.
@@ -734,8 +730,8 @@ config FB_3DFX
module, say M here and read <file:Documentation/modules.txt>.
config FB_VOODOO1
- tristate "3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "3Dfx Voodoo Graphics (sst1) support"
+ depends on FB && PCI
---help---
Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
Voodoo2 (cvg) based graphics card.
@@ -751,8 +747,8 @@ config FB_VOODOO1
options and other important info support.
config FB_TRIDENT
- tristate "Trident support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "Trident support"
+ depends on FB && PCI
---help---
This driver is supposed to support graphics boards with the
Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
@@ -767,8 +763,8 @@ config FB_TRIDENT
module, say M here and read <file:Documentation/modules.txt>.
config FB_PM3
- tristate "Permedia3 support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI
+ tristate "Permedia3 support"
+ depends on FB && PCI
help
This is the frame buffer device driver for the 3DLabs Permedia3
chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
@@ -875,8 +871,8 @@ config FB_68328
the Motorola 68328 CPU family.
config FB_VIRTUAL
- tristate "Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL
+ tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+ depends on FB
---help---
This is a `virtual' frame buffer device. It operates on a chunk of
unswappable kernel memory instead of on the memory of a graphics
@@ -894,262 +890,7 @@ config FB_VIRTUAL
If unsure, say N.
-config FBCON_ADVANCED
- bool "Advanced low level driver options"
- depends on FB
- ---help---
- The frame buffer console uses character drawing routines that are
- tailored to the specific organization of pixels in the memory of
- your graphics hardware. These are called the low level frame buffer
- console drivers. Note that they are used for text console output
- only; they are NOT needed for graphical applications.
-
- If you say N here, the needed low level drivers are automatically
- enabled, depending on what frame buffer devices you selected above.
- This is recommended for most users.
-
- If you say Y here, you have more fine-grained control over which low
- level drivers are enabled. You can e.g. leave out low level drivers
- for color depths you do not intend to use for text consoles.
-
- Low level frame buffer console drivers can be modules ( = code which
- can be inserted and removed from the running kernel whenever you
- want). The modules will be called fbcon-*.o. If you want to compile
- (some of) them as modules, read <file:Documentation/modules.txt>.
-
- If unsure, say N.
-
-config FBCON_MFB
- tristate "Monochrome support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && !FB_ACORN && FB_AMIGA!=y && !FB_ATARI && FB_CYBER!=y && !FB_BWTWO && FB_RETINAZ3!=y && !FB_VIRGE && FB_CLGEN!=y && (FB_AMIGA=m || FB_CYBER=m || FB_RETINAZ3=m || FB_CLGEN=m)
- default y if !FBCON_ADVANCED && (FB_ACORN || FB_AMIGA=y || FB_ATARI || FB_CYBER=y || FB_BWTWO || FB_RETINAZ3=y || FB_VIRGE || FB_CLGEN=y)
- help
- This is the low level frame buffer console driver for monochrome
- (2 colors) packed pixels.
-
-config FBCON_CFB2
- tristate "2 bpp packed pixels support" if FBCON_ADVANCED
- depends on FB
- default y if !FBCON_ADVANCED && (FB_ACORN || FB_SA1100)
- help
- This is the low level frame buffer console driver for 2 bits per
- pixel (4 colors) packed pixels.
-
-config FBCON_CFB4
- tristate "4 bpp packed pixels support" if FBCON_ADVANCED
- depends on FB
- default y if !FBCON_ADVANCED && (FB_ACORN || FB_SA1100)
- help
- This is the low level frame buffer console driver for 4 bits per
- pixel (16 colors) packed pixels.
-
-config FBCON_CFB8
- tristate "8 bpp packed pixels support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && !FB_ACORN && !FB_ATARI && !FB_P9100 && FB_CYBER2000!=y && FB_RADEON!=y && FB_TGA!=y && FB_SIS!=y && FB_PM3!=y && !FB_TCX && !FB_CGTHREE && !FB_CONTROL && FB_CLGEN!=y && !FB_CGFOURTEEN && FB_TRIDENT!=y && !FB_VIRGE && FB_CYBER!=y && !FB_VALKYRIE && !FB_PLATINUM && !FB_IGA && FB_MATROX!=y && !FB_CT65550 && FB_PM2!=y && !FB_SA1100 && (FB_CYBER2000=m || FB_RADEON=m || FB_TGA=m || FB_SIS=m || FB_PM3=m || FB_CLGEN=m || FB_TRIDENT=m || FB_CYBER=m || FB_MATROX=m || FB_PM2=m)
- default y if !FBCON_ADVANCED && (FB_ACORN || FB_ATARI || FB_P9100 || FB_CYBER2000=y || FB_RADEON=y || FB_TGA=y || FB_SIS=y || FB_PM3=y || FB_TCX || FB_CGTHREE || FB_CONTROL || FB_CLGEN=y || FB_CGFOURTEEN || FB_TRIDENT=y || FB_VIRGE || FB_CYBER=y || FB_VALKYRIE || FB_PLATINUM || FB_IGA || FB_MATROX=y || FB_CT65550 || FB_PM2=y || FB_SA1100)
- help
- This is the low level frame buffer console driver for 8 bits per
- pixel (256 colors) packed pixels.
-
-config FBCON_CFB16
- tristate "16 bpp packed pixels support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && !FB_ATARI && FB_PM3!=y && FB_SIS!=y && FB_PVR2!=y && FB_TRIDENT!=y && !FB_TBOX && FB_VOODOO1!=y && FB_RADEON!=y && !FB_CONTROL && FB_CLGEN!=y && !FB_VIRGE && FB_CYBER!=y && !FB_VALKYRIE && !FB_PLATINUM && !FB_CT65550 && FB_MATROX!=y && FB_PM2!=y && FB_CYBER2000!=y && !FB_SA1100 && (FB_SIS=m || FB_RADEON=m || FB_PVR2=m || FB_TRIDENT=m || FB_VOODOO1=m || FB_PM3=m || FB_CLGEN=m || FB_CYBER=m || FB_MATROX=m || FB_PM2=m || FB_CYBER2000=m || FB_SA1100)
- default y if !FBCON_ADVANCED && (FB_ATARI || FB_PM3=y || FB_SIS=y || FB_PVR2=y || FB_TRIDENT=y || FB_TBOX || FB_VOODOO1=y || FB_RADEON=y || FB_CONTROL || FB_CLGEN=y || FB_VIRGE || FB_CYBER=y || FB_VALKYRIE || FB_PLATINUM || FB_CT65550 || FB_MATROX=y || FB_PM2=y || FB_CYBER2000=y || FB_SA1100)
- help
- This is the low level frame buffer console driver for 15 or 16 bits
- per pixel (32K or 64K colors, also known as `hicolor') packed
- pixels.
-
-config FBCON_CFB24
- tristate "24 bpp packed pixels support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && FB_ATY!=y && FB_VIRTUAL!=y && FB_CLGEN!=y && !FB_VESA && FB_MATROX!=y && FB_PM2!=y && FB_ATY128!=y && FB_RADEON!=y && FB_CYBER2000!=y && FB_PVR2!=y && FB_VOODOO1!=y && FB_NEOMAGIC!=y && (FB_ATY=m || FB_VIRTUAL=m || FB_CLGEN=m || FB_MATROX=m || FB_PM2=m || FB_ATY128=m || FB_RADEON=m || FB_CYBER2000=m || FB_PVR2=m || FB_VOODOO1=m || FB_NEOMAGIC=y)
- default y if !FBCON_ADVANCED && (FB_ATY=y || FB_VIRTUAL=y || FB_CLGEN=y || FB_VESA || FB_MATROX=y || FB_PM2=y || FB_ATY128=y || FB_RADEON=y || FB_CYBER2000=y || FB_PVR2=y || FB_VOODOO1=y || FB_NEOMAGIC=y)
- help
- This is the low level frame buffer console driver for 24 bits per
- pixel (16M colors, also known as `truecolor') packed pixels. It is
- NOT for `sparse' 32 bits per pixel mode.
-
-config FBCON_CFB32
- tristate "32 bpp packed pixels support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && !FB_ATARI && FB_RADEON!=y && FB_VOODOO1!=y && FB_TRIDENT!=y && !FB_CONTROL && FB_CLGEN!=y && FB_TGA!=y && !FB_PLATINUM && FB_MATROX!=y && FB_PM2!=y && FB_PVR2!=y && FB_PM3!=y && FB_SIS!=y && (FB_RADEON=m || FB_VOODOO1=m || FB_TRIDENT=m || FB_CLGEN=m || FB_TGA=m || FB_MATROX=m || FB_PM2=m || FB_SIS=m || FB_PVR2=m || FB_PM3=m)
- default y if !FBCON_ADVANCED && (FB_ATARI || FB_RADEON=y || FB_VOODOO1=y || FB_TRIDENT=y || FB_CONTROL || FB_CLGEN=y || FB_TGA=y || FB_PLATINUM || FB_MATROX=y || FB_PM2=y || FB_PVR2=y || FB_PM3=y || FB_SIS=y)
- help
- This is the low level frame buffer console driver for 32 bits per
- pixel (16M colors, also known as `truecolor') sparse packed pixels.
-
-config FBCON_ACCEL
- tristate "Hardware acceleration support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && !FB_MAC && FB_RIVA!=y && !FB_OF && FB_SGIVW!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m)
- default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y)
-
-config FBCON_AFB
- tristate "Amiga bitplanes support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && FB_AMIGA=m
- default y if !FBCON_ADVANCED && FB_AMIGA=y
- help
- This is the low level frame buffer console driver for 1 to 8
- bitplanes (2 to 256 colors) on Amiga.
-
-config FBCON_ILBM
- tristate "Amiga interleaved bitplanes support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && FB_AMIGA=m
- default y if !FBCON_ADVANCED && FB_AMIGA=y
- help
- This is the low level frame buffer console driver for 1 to 8
- interleaved bitplanes (2 to 256 colors) on Amiga.
-
-config FBCON_IPLAN2P2
- tristate "Atari interleaved bitplanes (2 planes) support" if FBCON_ADVANCED
- depends on FB
- default y if !FBCON_ADVANCED && FB_ATARI
- help
- This is the low level frame buffer console driver for 2 interleaved
- bitplanes (4 colors) on Atari.
-
-config FBCON_IPLAN2P4
- tristate "Atari interleaved bitplanes (4 planes) support" if FBCON_ADVANCED
- depends on FB
- default y if !FBCON_ADVANCED && FB_ATARI
- help
- This is the low level frame buffer console driver for 4 interleaved
- bitplanes (16 colors) on Atari.
-
-config FBCON_IPLAN2P8
- tristate "Atari interleaved bitplanes (8 planes) support" if FBCON_ADVANCED
- depends on FB
- default y if !FBCON_ADVANCED && FB_ATARI
- help
- This is the low level frame buffer console driver for 8 interleaved
- bitplanes (256 colors) on Atari.
-
-# tristate ' Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16
-config FBCON_VGA_PLANES
- tristate "VGA 16-color planar support" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && FB_VGA16=m
- default y if !FBCON_ADVANCED && FB_VGA16=y
- help
- This low level frame buffer console driver enable the kernel to use
- the 16-color planar modes of the old VGA cards where the bits of
- each pixel are separated into 4 planes.
-
- Only answer Y here if you have a (very old) VGA card that isn't VESA
- 2 compatible.
-
-config FBCON_HGA
- tristate "HGA monochrome support (EXPERIMENTAL)" if FBCON_ADVANCED
- depends on FB
- default m if !FBCON_ADVANCED && FB_HGA=m
- default y if !FBCON_ADVANCED && FB_HGA=y
- help
- This is the low level frame buffer console driver for Hercules mono
- graphics cards.
-
-# Guess what we need
-config FBCON_STI
- tristate
- depends on !FBCON_ADVANCED && FB_STI
- default y
-
-config FBCON_FONTWIDTH8_ONLY
- bool "Support only 8 pixels wide fonts"
- depends on FB
- help
- Answer Y here will make the kernel provide only the 8x8 fonts (these
- are the less readable).
-
- If unsure, say N.
-
-config FONT_SUN8x16
- bool "Sparc console 8x16 font"
- depends on FB && (!SPARC32 && !SPARC64 && FBCON_FONTS || SPARC32 || SPARC64)
- help
- This is the high resolution console font for Sun machines. Say Y.
-
-config FONT_SUN12x22
- bool "Sparc console 12x22 font (not supported by all drivers)"
- depends on FB && !FBCON_FONTWIDTH8_ONLY && (!SPARC32 && !SPARC64 && FBCON_FONTS || SPARC32 || SPARC64)
- help
- This is the high resolution console font for Sun machines with very
- big letters (like the letters used in the SPARC PROM). If the
- standard font is unreadable for you, say Y, otherwise say N.
-
-config FBCON_FONTS
- bool "Select other fonts" if SPARC32 || SPARC64
- depends on FB
- help
- Say Y here if you would like to use fonts other than the default
- your frame buffer console usually use.
-
- Note that the answer to this question won't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about foreign fonts.
-
- If unsure, say N (the default choices are safe).
-
-config FBCON_FONTS
- prompt "Select compiled-in fonts"
- depends on FB && !SPARC32 && !SPARC64
-
-config FONT_8x8
- bool "VGA 8x8 font" if FBCON_FONTS
- depends on FB
- default y if !SPARC32 && !SPARC64 && !FBCON_FONTS
- help
- This is the "high resolution" font for the VGA frame buffer (the one
- provided by the text console 80x50 (and higher) modes).
-
- Note that this is a poor quality font. The VGA 8x16 font is quite a
- lot more readable.
-
- Given the resolution provided by the frame buffer device, answer N
- here is safe.
-
-config FONT_8x16
- bool "VGA 8x16 font" if FBCON_FONTS
- depends on FB
- default y if !SPARC32 && !SPARC64 && !FBCON_FONTS
- help
- This is the "high resolution" font for the VGA frame buffer (the one
- provided by the VGA text console 80x25 mode.
-
- If unsure, say Y.
-
-config FONT_6x11
- bool "Mac console 6x11 font (not supported by all drivers)" if FBCON_FONTS
- depends on FB && !FBCON_FONTWIDTH8_ONLY
- default y if !SPARC32 && !SPARC64 && !FBCON_FONTS && MAC
- help
- Small console font with Macintosh-style high-half glyphs. Some Mac
- framebuffer drivers don't support this one at all.
-
-config FONT_PEARL_8x8
- bool "Pearl (old m68k) console 8x8 font" if FBCON_FONTS
- depends on FB
- default y if !SPARC32 && !SPARC64 && !FBCON_FONTS && AMIGA
- help
- Small console font with PC-style control-character and high-half
- glyphs.
-
-config FONT_ACORN_8x8
- bool "Acorn console 8x8 font" if FBCON_FONTS
- depends on FB
- default y if !SPARC32 && !SPARC64 && !FBCON_FONTS && ARM && ARCH_ACORN
- help
- Small console font with PC-style control characters and high-half
- glyphs.
-
-config FONT_MINI_4x6
- bool "Mini 4x6 font"
- depends on !SPARC32 && !SPARC64 && FBCON_FONTS
+source "drivers/video/console/Kconfig"
endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 9eb41edb4a49..21d7f402a86c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -5,33 +5,15 @@
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-export-objs := fbmem.o fbcmap.o fbcon.o fbmon.o modedb.o \
- fbcon-afb.o fbcon-ilbm.o fbcon-accel.o cyber2000fb.o \
- fbcon-iplan2p2.o fbcon-iplan2p4.o fbgen.o \
- fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
- fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
- fbcon-cfb8.o fbcon-mfb.o fbcon-hga.o
+export-objs := fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o \
+ cfbcopyarea.o cfbimgblt.o cyber2000fb.o vgastate.o
# Each configuration option enables a list of files.
-obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o
-obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o
-obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
-obj-$(CONFIG_STI_CONSOLE) += sticon.o sticon-bmode.o sticore.o
-obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
-obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
-
-obj-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o
-obj-$(CONFIG_FONT_SUN12x22) += font_sun12x22.o
-obj-$(CONFIG_FONT_8x8) += font_8x8.o
-obj-$(CONFIG_FONT_8x16) += font_8x16.o
-obj-$(CONFIG_FONT_6x11) += font_6x11.o
-obj-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
-obj-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
-obj-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
+obj-$(CONFIG_VT) += console/
# Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x
-obj-$(CONFIG_FB) += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o fbgen.o
+obj-$(CONFIG_FB) += fbmem.o fbcmap.o modedb.o softcursor.o
# Only include macmodes.o if we have FB support and are PPC
ifeq ($(CONFIG_FB),y)
obj-$(CONFIG_PPC) += macmodes.o
@@ -44,10 +26,10 @@ obj-$(CONFIG_FB_PM3) += pm3fb.o
obj-$(CONFIG_FB_APOLLO) += dnfb.o cfbfillrect.o cfbimgblt.o
obj-$(CONFIG_FB_Q40) += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_ATARI) += atafb.o
-obj-$(CONFIG_FB_ATY128) += aty128fb.o
+obj-$(CONFIG_FB_ATY128) += aty128fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_RADEON) += radeonfb.o
obj-$(CONFIG_FB_NEOMAGIC) += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_IGA) += igafb.o
+obj-$(CONFIG_FB_IGA) += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblit.o
obj-$(CONFIG_FB_CONTROL) += controlfb.o
obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
@@ -68,7 +50,8 @@ obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
obj-$(CONFIG_FB_TGA) += tgafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_VGA16) += vga16fb.o fbcon-vga-planes.o
+obj-$(CONFIG_FB_VGA16) += vga16fb.o cfbfillrect.o cfbcopyarea.o \
+ cfbimgblt.o vgastate.o
obj-$(CONFIG_FB_VIRGE) += virgefb.o
obj-$(CONFIG_FB_G364) += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -80,20 +63,21 @@ obj-$(CONFIG_FB_TCX) += tcxfb.o sbusfb.o
obj-$(CONFIG_FB_CGFOURTEEN) += cgfourteenfb.o sbusfb.o
obj-$(CONFIG_FB_P9100) += p9100fb.o sbusfb.o
obj-$(CONFIG_FB_LEO) += leofb.o sbusfb.o
-obj-$(CONFIG_FB_STI) += stifb.o sticore.o
+obj-$(CONFIG_FB_STI) += stifb.o console/sticore.o
obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_MAXINE) += maxinefb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_TX3912) += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_MATROX) += matrox/
-obj-$(CONFIG_FB_RIVA) += riva/
+obj-$(CONFIG_FB_RIVA) += riva/ cfbfillrect.o cfbcopyarea.o \
+ cfbimgblt.o vgastate.o
obj-$(CONFIG_FB_SIS) += sis/
obj-$(CONFIG_FB_ATY) += aty/ cfbimgblt.o
obj-$(CONFIG_FB_SUN3) += sun3fb.o
obj-$(CONFIG_FB_BWTWO) += bwtwofb.o
-obj-$(CONFIG_FB_HGA) += hgafb.o
+obj-$(CONFIG_FB_HGA) += hgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o
obj-$(CONFIG_FB_VIRTUAL) += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_HIT) += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -101,24 +85,6 @@ obj-$(CONFIG_FB_E1355) += epson1355fb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
-# Generic Low Level Drivers
-
-obj-$(CONFIG_FBCON_AFB) += fbcon-afb.o
-obj-$(CONFIG_FBCON_CFB2) += fbcon-cfb2.o
-obj-$(CONFIG_FBCON_CFB4) += fbcon-cfb4.o
-obj-$(CONFIG_FBCON_CFB8) += fbcon-cfb8.o
-obj-$(CONFIG_FBCON_CFB16) += fbcon-cfb16.o
-obj-$(CONFIG_FBCON_CFB24) += fbcon-cfb24.o
-obj-$(CONFIG_FBCON_CFB32) += fbcon-cfb32.o
-obj-$(CONFIG_FBCON_ILBM) += fbcon-ilbm.o
-obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
-obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o
-obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o
-obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o
-obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
-obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
-obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
-
# Files generated that shall be removed upon make clean
clean-files := promcon_tbl.c
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index 0a7ea6ec1f79..07863a5ee58b 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -542,7 +542,7 @@ static void __init s3triofb_of_init(struct device_node *dp)
return;
printk("fb%d: S3 Trio frame buffer device on %s\n",
- GET_FB_IDX(fb_info.node), dp->full_name);
+ minor(fb_info.node), dp->full_name);
}
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 357ce2571f66..a98aa38199b8 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1771,7 +1771,7 @@ default_chipset:
}
printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.node), fb_info.modename,
+ minor(fb_info.node), fb_info.modename,
videomemorysize>>10);
return 0;
diff --git a/drivers/video/anakinfb.c b/drivers/video/anakinfb.c
index 340a90c23efe..90c47bb310a4 100644
--- a/drivers/video/anakinfb.c
+++ b/drivers/video/anakinfb.c
@@ -20,35 +20,32 @@
#include <asm/io.h>
-#include <video/fbcon.h>
-
-static u32 colreg[16];
+static u32 colreg[17];
static struct fb_info fb_info;
-static struct display display;
static struct fb_var_screeninfo anakinfb_var = {
- .xres = 400,
- .yres = 234,
- .xres_virtual = 400,
- .yres_virtual = 234,
- .bits_per_pixel =16,
- .red = { 11, 5, 0 },
- .green = { 5, 6, 0 },
- .blue = { 0, 5, 0 },
- .activate FB_ACTIVATE_NOW,
- .height -1,
- .width -1,
- .vmode FB_VMODE_NONINTERLACED,
+ .xres = 400,
+ .yres = 234,
+ .xres_virtual = 400,
+ .yres_virtual = 234,
+ .bits_per_pixel = 16,
+ .red = { 11, 5, 0 },
+ .green = { 5, 6, 0 },
+ .blue = { 0, 5, 0 },
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .vmode = FB_VMODE_NONINTERLACED,
};
static struct fb_fix_screeninfo anakinfb_fix = {
- .id = "AnakinFB",
- .smem_start = VGA_START,
- .smem_len = VGA_SIZE,
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_TRUECOLOR,
- .line_length = 400*2,
- .accel = FB_ACCEL_NONE,
+ .id = "AnakinFB",
+ .smem_start = VGA_START,
+ .smem_len = VGA_SIZE,
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .line_length = 400*2,
+ .accel = FB_ACCEL_NONE,
};
static int
@@ -58,40 +55,30 @@ anakinfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
if (regno > 15)
return 1;
- colreg[regno] = (red & 0xf800) | (green & 0xfc00 >> 5) |
- (blue & 0xf800 >> 11);
+ ((u16 *)(info->pseudo_palette))[regno] = (red & 0xf800) | (green & 0xfc00 >> 5) | (blue & 0xf800 >> 11);
return 0;
}
static struct fb_ops anakinfb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = anakinfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
int __init
anakinfb_init(void)
{
memset(&fb_info, 0, sizeof(struct fb_info));
- memset(&display, 0, sizeof(struct display));
- strcpy(fb_info.modename, anakinfb_fix.id);
fb_info.node = NODEV;
- fb_info.currcon = -1;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.fbops = &anakinfb_ops;
fb_info.var = anakinfb_var;
fb_info.fix = anakinfb_fix;
- fb_info.disp = &display;
- strcpy(fb_info.fontname, "VGA8x16");
- fb_info.changevar = NULL;
- fb_info.switch_con = gen_switch_con;
- fb_info.updatevar = gen_update_var;
+ fb_info.psuedo_palette = colreg;
if (!(request_mem_region(VGA_START, VGA_SIZE, "vga")))
return -ENOMEM;
if (fb_info.screen_base = ioremap(VGA_START, VGA_SIZE)) {
@@ -100,10 +87,9 @@ anakinfb_init(void)
}
fb_alloc_cmap(&fb_info.cmap, 16, 0);
- gen_set_disp(-1, &fb_info);
if (register_framebuffer(&fb_info) < 0) {
- iounmap(display.screen_base);
+ iounmap(fb_info.screen_base);
release_mem_region(VGA_START, VGA_SIZE);
return -EINVAL;
}
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 33ea709cefa1..fd55dbcabf6f 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2816,7 +2816,7 @@ int __init atafb_init(void)
printk(" virtual %dx%d\n",
disp.var.xres_virtual, disp.var.yres_virtual);
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);
+ minor(fb_info.node), fb_info.modename, screen_len>>10);
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index 8342386c4a47..27a6a4f2f98a 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -3,8 +3,6 @@
*/
#include <linux/config.h>
-#include <video/fbcon.h>
-
/*
* Elements of the hardware specific atyfb_par structure
*/
@@ -59,19 +57,9 @@ union aty_pll {
*/
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];
u8 *ram;
- struct timer_list *timer;
};
struct atyfb_par {
@@ -93,8 +81,6 @@ struct atyfb_par {
u8 blitter_may_be_busy;
#ifdef __sparc__
struct pci_mmap_map *mmap_map;
- int consolecnt;
- int vtconsole;
u8 mmaped;
int open;
#endif
@@ -251,11 +237,9 @@ extern void aty_calc_pll_ct(const struct fb_info *info,
*/
extern struct aty_cursor *aty_init_cursor(struct fb_info *info);
-extern void atyfb_cursor(struct display *p, int mode, int x, int y);
+extern int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
extern void aty_set_cursor_color(struct fb_info *info);
extern void aty_set_cursor_shape(struct fb_info *info);
-extern int atyfb_set_font(struct display *d, int width, int height);
-
/*
* Hardware acceleration
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index d7e50db324ec..0f4bc997dc24 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -65,9 +65,6 @@
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <video/fbcon.h>
-#include "../fbcon-accel.h"
-
#include <video/mach64.h>
#include "atyfb.h"
@@ -149,11 +146,11 @@ static int atyfb_check_var(struct fb_var_screeninfo *var,
static int atyfb_set_par(struct fb_info *info);
static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
-static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int atyfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
static int atyfb_blank(int blank, 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);
+ u_long arg, struct fb_info *info);
extern void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
extern void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
extern void atyfb_imageblit(struct fb_info *info, struct fb_image *image);
@@ -161,7 +158,7 @@ extern void atyfb_imageblit(struct fb_info *info, struct fb_image *image);
static int atyfb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma);
#endif
-static int atyfb_rasterimg(struct fb_info *info, int start);
+static int atyfb_sync(struct fb_info *info);
/*
* Internal routines
@@ -198,21 +195,12 @@ int atyfb_init(void);
int atyfb_setup(char *);
#endif
-int gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
- *var = info->var;
- return 0;
-}
-
static struct fb_ops atyfb_ops = {
.owner = THIS_MODULE,
.fb_open = atyfb_open,
.fb_release = atyfb_release,
- .fb_set_var = gen_set_var,
.fb_check_var = atyfb_check_var,
.fb_set_par = atyfb_set_par,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = atyfb_setcolreg,
.fb_pan_display = atyfb_pan_display,
.fb_blank = atyfb_blank,
@@ -220,13 +208,13 @@ static struct fb_ops atyfb_ops = {
.fb_fillrect = atyfb_fillrect,
.fb_copyarea = atyfb_copyarea,
.fb_imageblit = atyfb_imageblit,
+ .fb_cursor = soft_cursor,
#ifdef __sparc__
.fb_mmap = atyfb_mmap,
#endif
- .fb_rasterimg = atyfb_rasterimg,
+ .fb_sync = atyfb_sync,
};
-static char fontname[40] __initdata = { 0 };
static char curblink __initdata = 1;
static char noaccel __initdata = 0;
static u32 default_vram __initdata = 0;
@@ -944,9 +932,6 @@ static int atyfb_open(struct fb_info *info, int user)
if (user) {
par->open++;
par->mmaped = 0;
- par->vtconsole = -1;
- } else {
- par->consolecnt++;
}
#endif
return (0);
@@ -973,9 +958,6 @@ static int atyfb_release(struct fb_info *info, int user)
int was_mmaped = par->mmaped;
par->mmaped = 0;
- if (par->vtconsole != -1)
- vt_cons[par->vtconsole]->vc_mode = KD_TEXT;
- par->vtconsole = -1;
if (was_mmaped) {
struct fb_var_screeninfo var;
@@ -1005,9 +987,7 @@ static int atyfb_release(struct fb_info *info, int user)
gen_set_var(&var, -1, info);
}
}
- } else {
- par->consolecnt--;
- }
+ }
#endif
return (0);
}
@@ -1018,7 +998,7 @@ static int atyfb_release(struct fb_info *info, int user)
* This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
*/
-static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int atyfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -1060,7 +1040,7 @@ struct atyclk {
#endif
static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, int con, struct fb_info *info)
+ u_long arg, struct fb_info *info)
{
#if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -1150,7 +1130,7 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
return 0;
}
-static int atyfb_rasterimg(struct fb_info *info, int start)
+static int atyfb_sync(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -1228,18 +1208,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
vma->vm_flags |= VM_IO;
- if (!par->mmaped) {
- int lastconsole = 0;
-
- if (info->display_fg)
- lastconsole = info->display_fg->vc_num;
+ if (!par->mmaped)
par->mmaped = 1;
- if (par->consolecnt
- && fb_display[lastconsole].fb_info == info) {
- par->vtconsole = lastconsole;
- vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
- }
- }
return 0;
}
@@ -1562,7 +1532,6 @@ static int __init aty_init(struct fb_info *info, const char *name)
const char *chipname = NULL, *ramname = NULL, *xtal;
int j, pll, mclk, gtb_memsize;
struct fb_var_screeninfo var;
- struct display *disp;
u32 chip_id, i;
u16 type;
u8 rev;
@@ -1843,18 +1812,9 @@ static int __init aty_init(struct fb_info *info, const char *name)
fb_memset((void *) info->screen_base, 0,
info->fix.smem_len);
- disp = info->disp;
-
- strcpy(info->modename, info->fix.id);
info->node = NODEV;
info->fbops = &atyfb_ops;
- info->disp = disp;
info->pseudo_palette = pseudo_palette;
- info->currcon = -1;
- strcpy(info->fontname, fontname);
- info->changevar = NULL;
- info->switch_con = gen_switch;
- info->updatevar = gen_update_var;
info->flags = FBINFO_FLAG_DEFAULT;
#ifdef CONFIG_PMAC_BACKLIGHT
@@ -1965,29 +1925,20 @@ static int __init aty_init(struct fb_info *info, const char *name)
#endif
#ifdef CONFIG_FB_ATY_CT
- if (curblink && M64_HAS(INTEGRATED)) {
+ if (curblink && M64_HAS(INTEGRATED))
par->cursor = aty_init_cursor(info);
- if (par->cursor) {
- /*
- disp->dispsw.cursor = atyfb_cursor;
- disp->dispsw.set_font = atyfb_set_font;
- */
- }
- }
#endif /* CONFIG_FB_ATY_CT */
info->var = var;
fb_alloc_cmap(&info->cmap, 256, 0);
- gen_set_var(&var, -1, info);
-
if (register_framebuffer(info) < 0)
return 0;
fb_list = info;
printk("fb%d: %s frame buffer device on %s\n",
- GET_FB_IDX(info->node), info->fix.id, name);
+ minor(info->node), info->fix.id, name);
return 1;
}
@@ -2028,16 +1979,13 @@ int __init atyfb_init(void)
continue;
info =
- kmalloc(sizeof(struct fb_info) +
- sizeof(struct display), GFP_ATOMIC);
+ kmalloc(sizeof(struct fb_info), GFP_ATOMIC);
if (!info) {
printk
("atyfb_init: can't alloc fb_info\n");
return -ENXIO;
}
- memset(info, 0,
- sizeof(struct fb_info) +
- sizeof(struct display));
+ memset(info, 0, sizeof(struct fb_info));
default_par =
kmalloc(sizeof(struct atyfb_par), GFP_ATOMIC);
@@ -2049,7 +1997,6 @@ int __init atyfb_init(void)
}
memset(default_par, 0, sizeof(struct atyfb_par));
- info->disp = (struct display *) (info + 1);
info->fix = atyfb_fix;
info->par = default_par;
@@ -2460,17 +2407,7 @@ int __init atyfb_setup(char *options)
return 0;
while ((this_opt = strsep(&options, ",")) != 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;
- } else if (!strncmp(this_opt, "noblink", 7)) {
+ if (!strncmp(this_opt, "noblink", 7)) {
curblink = 0;
} else if (!strncmp(this_opt, "noaccel", 7)) {
noaccel = 1;
@@ -2694,12 +2631,8 @@ void cleanup_module(void)
iounmap(info->cursor->ram);
#endif
#endif
-
- if (info->cursor) {
- if (info->cursor->timer)
- kfree(info->cursor->timer);
+ if (info->cursor)
kfree(info->cursor);
- }
#ifdef __sparc__
if (par->mmap_map)
kfree(par->mmap_map);
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index 3d83d8e175d7..921b7dc0200b 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -7,8 +7,6 @@
#include <asm/io.h>
-#include <video/fbcon.h>
-
#include <video/mach64.h>
#include "atyfb.h"
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index b67e6f90967b..985090bf8e5b 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -11,8 +11,6 @@
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <video/fbcon.h>
-
#ifdef __sparc__
#include <asm/pbm.h>
#include <asm/fbio.h>
@@ -21,11 +19,6 @@
#include <video/mach64.h>
#include "atyfb.h"
-
-#define DEFAULT_CURSOR_BLINK_RATE (20)
-#define CURSOR_DRAW_DELAY (2)
-
-
/*
* Hardware Cursor support.
*/
@@ -51,50 +44,48 @@ void aty_set_cursor_color(struct fb_info *info)
const u8 *red = cursor_color_map;
const u8 *green = cursor_color_map;
const u8 *blue = cursor_color_map;
- int i;
+ u32 fg_color, bg_color;
if (!c)
return;
#ifdef __sparc__
- if (par->mmaped && (!info->display_fg
- || info->display_fg->vc_num ==
- par->vtconsole))
+ if (par->mmaped)
return;
#endif
+ fg_color = (u32) red[0] << 24;
+ fg_color |= (u32) green[0] << 16;
+ fg_color |= (u32) blue[0] << 8;
+ fg_color |= (u32) pixel[0];
- 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];
- }
+ bg_color = (u32) red[1] << 24;
+ bg_color |= (u32) green[1] << 16;
+ bg_color |= (u32) blue[1] << 8;
+ bg_color |= (u32) pixel[1];
wait_for_fifo(2, par);
- aty_st_le32(CUR_CLR0, c->color[0], par);
- aty_st_le32(CUR_CLR1, c->color[1], par);
+ aty_st_le32(CUR_CLR0, fg_color, par);
+ aty_st_le32(CUR_CLR1, bg_color, par);
}
void aty_set_cursor_shape(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
+ struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
u8 *ram, m, b;
int x, y;
if (!c)
return;
-
#ifdef __sparc__
- if (par->mmaped && (!info->display_fg
- || info->display_fg->vc_num ==
- par->vtconsole))
+ if (par->mmaped)
return;
#endif
ram = c->ram;
- for (y = 0; y < c->size.y; y++) {
- for (x = 0; x < c->size.x >> 2; x++) {
+ for (y = 0; y < cursor->image.height; y++) {
+ for (x = 0; x < cursor->image.width >> 2; x++) {
m = c->mask[x][y];
b = c->bits[x][y];
fb_writeb(cursor_mask_lookup[m >> 4] |
@@ -108,12 +99,13 @@ void aty_set_cursor_shape(struct fb_info *info)
fb_writeb(0xaa, ram++);
}
}
- fb_memset(ram, 0xaa, (64 - c->size.y) * 16);
+ fb_memset(ram, 0xaa, (64 - cursor->image.height) * 16);
}
-static void aty_set_cursor(struct fb_info *info, int on)
+static void aty_set_cursor(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
+ struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
u16 xoff, yoff;
int x, y;
@@ -122,14 +114,12 @@ static void aty_set_cursor(struct fb_info *info, int on)
return;
#ifdef __sparc__
- if (par->mmaped && (!info->display_fg
- || info->display_fg->vc_num ==
- par->vtconsole))
+ if (par->mmaped)
return;
#endif
- if (on) {
- x = c->pos.x - c->hot.x - info->var.xoffset;
+ if (cursor->enable) {
+ x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
if (x < 0) {
xoff = -x;
x = 0;
@@ -137,7 +127,7 @@ static void aty_set_cursor(struct fb_info *info, int on)
xoff = 0;
}
- y = c->pos.y - c->hot.y - info->var.yoffset;
+ y = cursor->image.dy - cursor->hot.y - info->var.yoffset;
if (y < 0) {
yoff = -y;
y = 0;
@@ -146,10 +136,10 @@ static void aty_set_cursor(struct fb_info *info, int on)
}
wait_for_fifo(4, par);
- aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1),
+ aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1),
par);
aty_st_le32(CUR_HORZ_VERT_OFF,
- ((u32) (64 - c->size.y + yoff) << 16) | xoff,
+ ((u32) (64 - cursor->image.height + yoff) << 16) | xoff,
par);
aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par);
aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
@@ -164,70 +154,25 @@ static void aty_set_cursor(struct fb_info *info, int on)
wait_for_idle(par);
}
-static void aty_cursor_timer_handler(unsigned long dev_addr)
+int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
- struct fb_info *info = (struct fb_info *) dev_addr;
- struct atyfb_par *par = (struct atyfb_par *) info->par;
-
- if (!par->cursor)
- return;
-
- if (!par->cursor->enable)
- goto out;
-
- if (par->cursor->vbl_cnt && --par->cursor->vbl_cnt == 0) {
- par->cursor->on ^= 1;
- aty_set_cursor(info, par->cursor->on);
- par->cursor->vbl_cnt = par->cursor->blink_rate;
- }
-
- out:
- par->cursor->timer->expires = jiffies + (HZ / 50);
- add_timer(par->cursor->timer);
-}
-
-void atyfb_cursor(struct display *p, int mode, int x, int y)
-{
- struct fb_info *info = p->fb_info;
struct atyfb_par *par = (struct atyfb_par *) info->par;
struct aty_cursor *c = par->cursor;
if (!c)
- return;
+ return -1;
#ifdef __sparc__
- if (par->mmaped && (!info->display_fg
- || info->display_fg->vc_num ==
- par->vtconsole))
+ if (par->mmaped)
return;
#endif
- x *= fontwidth(p);
- y *= fontheight(p);
- if (c->pos.x == x && c->pos.y == y
- && (mode == CM_ERASE) == !c->enable)
- return;
+ aty_set_cursor(info);
+ cursor->image.dx = info->cursor.image.dx;
+ cursor->image.dy = info->cursor.image.dy;
- c->enable = 0;
- if (c->on)
- aty_set_cursor(info, 0);
- c->pos.x = x;
- c->pos.y = y;
-
- switch (mode) {
- case CM_ERASE:
- c->on = 0;
- break;
-
- case CM_DRAW:
- case CM_MOVE:
- if (c->on)
- aty_set_cursor(info, 1);
- else
- c->vbl_cnt = CURSOR_DRAW_DELAY;
- c->enable = 1;
- break;
- }
+ aty_set_cursor(info);
+ return 0;
}
struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
@@ -240,47 +185,31 @@ struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
return 0;
memset(cursor, 0, sizeof(*cursor));
- cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
- if (!cursor->timer) {
- kfree(cursor);
- return 0;
- }
- memset(cursor->timer, 0, sizeof(*cursor->timer));
-
- cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
info->fix.smem_len -= PAGE_SIZE;
- cursor->offset = info->fix.smem_len;
#ifdef __sparc__
- addr = (unsigned long) info->screen_base - 0x800000 + cursor->offset;
+ addr = info->screen_base - 0x800000 + info->fix.smem_len;
cursor->ram = (u8 *) addr;
#else
#ifdef __BIG_ENDIAN
- addr = info->fix.smem_start - 0x800000 + cursor->offset;
+ addr = info->fix.smem_start - 0x800000 + info->fix.smem_len;
cursor->ram = (u8 *) ioremap(addr, 1024);
#else
- addr = (unsigned long) info->screen_base + cursor->offset;
+ addr = (unsigned long) info->screen_base + info->fix.smem_len;
cursor->ram = (u8 *) addr;
#endif
#endif
-
if (!cursor->ram) {
kfree(cursor);
return NULL;
}
-
- init_timer(cursor->timer);
- cursor->timer->expires = jiffies + (HZ / 50);
- cursor->timer->data = (unsigned long) info;
- cursor->timer->function = aty_cursor_timer_handler;
- add_timer(cursor->timer);
return cursor;
}
-int atyfb_set_font(struct display *d, int width, int height)
+int atyfb_set_font(struct fb_info *info, int width, int height)
{
- struct fb_info *info = d->fb_info;
struct atyfb_par *par = (struct atyfb_par *) info->par;
+ struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
int i, j;
@@ -290,10 +219,10 @@ int atyfb_set_font(struct display *d, int width, int height)
height = 16;
}
- c->hot.x = 0;
- c->hot.y = 0;
- c->size.x = width;
- c->size.y = height;
+ cursor->hot.x = 0;
+ cursor->hot.y = 0;
+ cursor->image.width = width;
+ cursor->image.height = height;
memset(c->bits, 0xff, sizeof(c->bits));
memset(c->mask, 0, sizeof(c->mask));
diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/aty/mach64_gx.c
index d11e58454b29..f85f0a052784 100644
--- a/drivers/video/aty/mach64_gx.c
+++ b/drivers/video/aty/mach64_gx.c
@@ -9,8 +9,6 @@
#include <asm/io.h>
-#include <video/fbcon.h>
-
#include <video/mach64.h>
#include "atyfb.h"
diff --git a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c
index ae43cc8ea62e..69f2d8d618c3 100644
--- a/drivers/video/aty128fb.c
+++ b/drivers/video/aty128fb.c
@@ -7,13 +7,26 @@
* Ani Joshi / Jeff Garzik
* - Code cleanup
*
+ * Michel Dänzer <michdaen@iiic.ethz.ch>
+ * - 15/16 bit cleanup
+ * - fix panning
+ *
+ * Benjamin Herrenschmidt
+ * - pmac-specific PM stuff
+ *
* Andreas Hundt <andi@convergence.de>
* - FB_ACTIVATE fixes
*
+ * Paul Mackerras <paulus@samba.org>
+ * - Convert to new framebuffer API,
+ * fix colormap setting at 16 bits/pixel (565)
+ *
+ * Paul Mundt
+ * - PCI hotplug
+ *
* Based off of Geert's atyfb.c and vfb.c.
*
* TODO:
- * - panning
* - monitor sensing (DDC)
* - virtual display
* - other platform support (only ppc/x86 supported)
@@ -49,7 +62,7 @@
#include <linux/ioport.h>
#include <asm/io.h>
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <video/macmodes.h>
@@ -71,12 +84,6 @@
#include <asm/btext.h>
#endif /* CONFIG_BOOTX_TEXT */
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
@@ -92,27 +99,27 @@
#define DBG(fmt, args...)
#endif
-#ifndef CONFIG_PPC
+#ifndef CONFIG_ALL_PPC
/* default mode */
static struct fb_var_screeninfo default_var __initdata = {
- /* 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
+ /* 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
};
-#else /* CONFIG_PPC */
+#else /* CONFIG_ALL_PPC */
/* default to 1024x768 at 75Hz on PPC - this will work
* on the iMac, the usual 640x480 @ 60Hz doesn't. */
static struct fb_var_screeninfo default_var = {
- /* 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, 160, 32, 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) */
+ 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, 160, 32, 28, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
};
-#endif /* CONFIG_PPC */
+#endif /* CONFIG_ALL_PPC */
/* default modedb mode */
/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
@@ -131,13 +138,6 @@ static struct fb_videomode defaultmode __initdata = {
.vmode = FB_VMODE_NONINTERLACED
};
-/* struct to hold chip description information */
-struct aty128_chip_info {
- const char *name;
- unsigned short device;
- int chip_gen;
-};
-
/* Chip generations */
enum {
rage_128,
@@ -145,20 +145,46 @@ enum {
rage_M3
};
+/*
+ * PCI driver prototypes
+ */
+static int aty128_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static void aty128_remove(struct pci_dev *pdev);
+
/* supported Rage128 chipsets */
-static struct aty128_chip_info aty128_pci_probe_list[] __initdata =
-{
- {"Rage128 RE (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RE, rage_128},
- {"Rage128 RF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RF, rage_128},
- {"Rage128 RK (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RK, rage_128},
- {"Rage128 RL (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RL, rage_128},
- {"Rage128 Pro PF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_PF, rage_128_pro},
- {"Rage128 Pro PR (PCI)", PCI_DEVICE_ID_ATI_RAGE128_PR, rage_128_pro},
- {"Rage128 Pro TR (AGP)", PCI_DEVICE_ID_ATI_RAGE128_U3, rage_128_pro},
- {"Rage Mobility M3 (PCI)", PCI_DEVICE_ID_ATI_RAGE128_LE, rage_M3},
- {"Rage Mobility M3 (AGP)", PCI_DEVICE_ID_ATI_RAGE128_LF, rage_M3},
- {NULL, 0, rage_128}
- };
+static struct pci_device_id aty128_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U3,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U1,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, aty128_pci_tbl);
+
+static struct pci_driver aty128fb_driver = {
+ name: "aty128fb",
+ id_table: aty128_pci_tbl,
+ probe: aty128_probe,
+ remove: __devexit_p(aty128_remove),
+};
/* packed BIOS settings */
#ifndef CONFIG_PPC
@@ -190,241 +216,190 @@ typedef struct {
/* onboard memory information */
struct aty128_meminfo {
- u8 ML;
- u8 MB;
- u8 Trcd;
- u8 Trp;
- u8 Twr;
- u8 CL;
- u8 Tr2w;
- u8 LoopLatency;
- u8 DspOn;
- u8 Rloop;
- const char *name;
+ u8 ML;
+ u8 MB;
+ u8 Trcd;
+ u8 Trp;
+ u8 Twr;
+ u8 CL;
+ u8 Tr2w;
+ u8 LoopLatency;
+ u8 DspOn;
+ u8 Rloop;
+ const char *name;
};
/* various memory configurations */
static const struct aty128_meminfo sdr_128 =
- { 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
+ { 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
static const struct aty128_meminfo sdr_64 =
- { 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
+ { 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
static const struct aty128_meminfo sdr_sgram =
- { 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
+ { 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
static const struct aty128_meminfo ddr_sgram =
- { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
-
-static const char *aty128fb_name = "ATY Rage128";
-static char fontname[40] __initdata = { 0 };
+ { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
+
+static struct fb_fix_screeninfo aty128fb_fix __initdata = {
+ .id = "ATY Rage128",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 8,
+ .ypanstep = 1,
+ .mmio_len = 0x2000,
+ .accel = FB_ACCEL_ATI_RAGE128,
+};
-static int noaccel __initdata = 0;
#ifdef MODULE
-static char *font __initdata = NULL;
static char *mode __initdata = NULL;
#ifdef CONFIG_MTRR
static int nomtrr __initdata = 0;
-#endif
+#endif /* CONFIG_MTRR */
#endif /* MODULE */
static char *mode_option __initdata = NULL;
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
static int default_vmode __initdata = VMODE_1024_768_60;
static int default_cmode __initdata = CMODE_8;
#endif
+#ifdef CONFIG_PMAC_PBOOK
+static int default_crt_on __initdata = 0;
+static int default_lcd_on __initdata = 1;
+#endif
+
#ifdef CONFIG_MTRR
static int mtrr = 1;
#endif
/* PLL constants */
struct aty128_constants {
- u32 dotclock;
- u32 ppll_min;
- u32 ppll_max;
- u32 ref_divider;
- u32 xclk;
- u32 fifo_width;
- u32 fifo_depth;
+ u32 dotclock;
+ u32 ppll_min;
+ u32 ppll_max;
+ u32 ref_divider;
+ u32 xclk;
+ u32 fifo_width;
+ u32 fifo_depth;
};
struct aty128_crtc {
- u32 gen_cntl;
- u32 ext_cntl;
- u32 h_total, h_sync_strt_wid;
- u32 v_total, v_sync_strt_wid;
- u32 pitch;
- u32 offset, offset_cntl;
- u32 xoffset, yoffset;
- u32 vxres, vyres;
- u32 bpp;
+ u32 gen_cntl;
+ u32 ext_cntl;
+ u32 h_total, h_sync_strt_wid;
+ u32 v_total, v_sync_strt_wid;
+ u32 pitch;
+ u32 offset, offset_cntl;
+ u32 xoffset, yoffset;
+ u32 vxres, vyres;
+ u32 depth, bpp;
};
struct aty128_pll {
- u32 post_divider;
- u32 feedback_divider;
- u32 vclk;
+ u32 post_divider;
+ u32 feedback_divider;
+ u32 vclk;
};
struct aty128_ddafifo {
- u32 dda_config;
- u32 dda_on_off;
+ u32 dda_config;
+ u32 dda_on_off;
};
/* register values for a specific mode */
struct aty128fb_par {
- struct aty128_crtc crtc;
- struct aty128_pll pll;
- struct aty128_ddafifo fifo_reg;
- u32 accel_flags;
-};
-
-struct fb_info_aty128 {
- struct fb_info fb_info;
- struct fb_info_aty128 *next;
- struct aty128_constants constants; /* PLL and others */
- unsigned long regbase_phys; /* physical mmio */
- void *regbase; /* remapped mmio */
- unsigned long frame_buffer_phys; /* physical fb memory */
- void *frame_buffer; /* remaped framebuffer */
- u32 vram_size; /* onboard video ram */
- int chip_gen;
- const struct aty128_meminfo *mem; /* onboard mem info */
- struct aty128fb_par default_par, current_par;
- struct display disp;
- struct { u8 red, green, blue, pad; } palette[256];
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
- u32 cfb24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
-#endif
- } fbcon_cmap;
-#ifdef CONFIG_PCI
- struct pci_dev *pdev;
-#endif
+ struct aty128_crtc crtc;
+ struct aty128_pll pll;
+ struct aty128_ddafifo fifo_reg;
+ u32 accel_flags;
+ struct aty128_constants constants; /* PLL and others */
+ void *regbase; /* remapped mmio */
+ u32 vram_size; /* onboard video ram */
+ int chip_gen;
+ const struct aty128_meminfo *mem; /* onboard mem info */
#ifdef CONFIG_MTRR
- struct { int vram; int vram_valid; } mtrr;
+ struct { int vram; int vram_valid; } mtrr;
+#endif
+ int blitter_may_be_busy;
+ int fifo_slots; /* free slots in FIFO (64 max) */
+#ifdef CONFIG_PMAC_PBOOK
+ unsigned char *save_framebuffer;
+ int pm_reg;
+ int crt_on, lcd_on;
#endif
- int blitter_may_be_busy;
- int fifo_slots; /* free slots in FIFO (64 max) */
+ unsigned char red[64]; /* see comments in aty128fb_setcolreg */
+ unsigned char green[64];
+ unsigned char blue[64];
};
-static struct fb_info_aty128 *board_list = NULL;
+#ifdef CONFIG_PMAC_PBOOK
+int aty128_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier aty128_sleep_notifier = {
+ aty128_sleep_notify, SLEEP_LEVEL_VIDEO,
+};
+#endif
#define round_div(n, d) ((n+(d/2))/d)
/*
* Interface used by the world
*/
-
+int aty128fb_init(void);
int aty128fb_setup(char *options);
-static int aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int aty128fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int aty128fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
+static int aty128fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+static int aty128fb_set_par(struct fb_info *info);
static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
-static int aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int aty128fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fb);
static int aty128fb_blank(int blank, struct fb_info *fb);
-static int aty128fb_rasterimg(struct fb_info *info, int start);
-
- /*
- * Interface to the low level console driver
- */
-
-int aty128fb_init(void);
-static int aty128fbcon_switch(int con, struct fb_info *fb);
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, struct fb_info *info);
+static int aty128fb_sync(struct fb_info *info);
/*
* Internal routines
*/
-static void aty128_encode_fix(struct fb_fix_screeninfo *fix,
- struct aty128fb_par *par,
- const struct fb_info_aty128 *info);
-static void aty128_set_dispsw(struct display *disp,
- struct fb_info_aty128 *info, int bpp, int accel);
-static int aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
static int aty128_encode_var(struct fb_var_screeninfo *var,
- const struct aty128fb_par *par,
- const struct fb_info_aty128 *info);
+ const struct aty128fb_par *par);
static int aty128_decode_var(struct fb_var_screeninfo *var,
- struct aty128fb_par *par,
- const struct fb_info_aty128 *info);
-static int aty128_pci_register(struct pci_dev *pdev,
- const struct aty128_chip_info *aci);
-static struct fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128
- *board_list, struct fb_info_aty128 *new_node);
+ struct aty128fb_par *par);
#if !defined(CONFIG_PPC) && !defined(__sparc__)
-static void __init aty128_get_pllinfo(struct fb_info_aty128 *info,
- char *bios_seg);
-static char __init *aty128find_ROM(struct fb_info_aty128 *info);
-#endif
-static void aty128_timings(struct fb_info_aty128 *info);
-static void aty128_init_engine(const struct aty128fb_par *par,
- struct fb_info_aty128 *info);
-static void aty128_reset_engine(const struct fb_info_aty128 *info);
-static void aty128_flush_pixel_cache(const struct fb_info_aty128 *info);
-static void do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
-static void wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
-static void wait_for_idle(struct fb_info_aty128 *info);
-static u32 bpp_to_depth(u32 bpp);
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_aty128_8;
-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 FBCON_HAS_CFB16
-static struct display_switch fbcon_aty128_16;
-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_aty128_24;
-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_aty128_32;
-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);
+static void __init aty128_get_pllinfo(struct aty128fb_par *par,
+ char *bios_seg);
+static char __init *aty128find_ROM(void);
#endif
+static void aty128_timings(struct aty128fb_par *par);
+static void aty128_init_engine(struct aty128fb_par *par);
+static void aty128_reset_engine(const struct aty128fb_par *par);
+static void aty128_flush_pixel_cache(const struct aty128fb_par *par);
+static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
+static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
+static void wait_for_idle(struct aty128fb_par *par);
+static u32 depth_to_dst(u32 depth);
static struct fb_ops aty128fb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = aty128fb_get_fix,
- .fb_get_var = aty128fb_get_var,
- .fb_set_var = aty128fb_set_var,
- .fb_get_cmap = aty128fb_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = aty128fb_setcolreg,
- .fb_pan_display =aty128fb_pan_display,
- .fb_blank = aty128fb_blank,
- .fb_rasterimg = aty128fb_rasterimg,
+ .owner = THIS_MODULE,
+ .fb_check_var = aty128fb_check_var,
+ .fb_set_par = aty128fb_set_par,
+ .fb_setcolreg = aty128fb_setcolreg,
+ .fb_pan_display = aty128fb_pan_display,
+ .fb_blank = aty128fb_blank,
+ .fb_ioctl = aty128fb_ioctl,
+ .fb_sync = aty128fb_sync,
+#if 0
+ .fb_fillrect = aty128fb_fillrect,
+ .fb_copyarea = aty128fb_copyarea,
+ .fb_imageblit = aty128fb_imageblit,
+#else
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+#endif
+ .fb_cursor = soft_cursor,
};
#ifdef CONFIG_PMAC_BACKLIGHT
@@ -443,1379 +418,1208 @@ static struct backlight_controller aty128_backlight_controller = {
* using the other register aperture. TODO.
*/
static inline u32
-_aty_ld_le32(volatile unsigned int regindex,
- const struct fb_info_aty128 *info)
+_aty_ld_le32(volatile unsigned int regindex, const struct aty128fb_par *par)
{
- u32 val;
+ u32 val;
#if defined(__powerpc__)
- asm("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b"(regindex), "r"(info->regbase));
+ asm("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b"(regindex), "r"(par->regbase));
#else
- val = readl (info->regbase + regindex);
+ val = readl (par->regbase + regindex);
#endif
- return val;
+ return val;
}
static inline void
_aty_st_le32(volatile unsigned int regindex, u32 val,
- const struct fb_info_aty128 *info)
+ const struct aty128fb_par *par)
{
#if defined(__powerpc__)
- asm("stwbrx %0,%1,%2;eieio" : : "r"(val), "b"(regindex),
- "r"(info->regbase) : "memory");
+ asm("stwbrx %0,%1,%2;eieio" : : "r"(val), "b"(regindex),
+ "r"(par->regbase) : "memory");
#else
- writel (val, info->regbase + regindex);
+ writel (val, par->regbase + regindex);
#endif
}
static inline u8
-_aty_ld_8(unsigned int regindex, const struct fb_info_aty128 *info)
+_aty_ld_8(unsigned int regindex, const struct aty128fb_par *par)
{
- return readb (info->regbase + regindex);
+ return readb (par->regbase + regindex);
}
static inline void
-_aty_st_8(unsigned int regindex, u8 val, const struct fb_info_aty128 *info)
+_aty_st_8(unsigned int regindex, u8 val, const struct aty128fb_par *par)
{
- writeb (val, info->regbase + regindex);
+ writeb (val, par->regbase + regindex);
}
-#define aty_ld_le32(regindex) _aty_ld_le32(regindex, info)
-#define aty_st_le32(regindex, val) _aty_st_le32(regindex, val, info)
-#define aty_ld_8(regindex) _aty_ld_8(regindex, info)
-#define aty_st_8(regindex, val) _aty_st_8(regindex, val, info)
+#define aty_ld_le32(regindex) _aty_ld_le32(regindex, par)
+#define aty_st_le32(regindex, val) _aty_st_le32(regindex, val, par)
+#define aty_ld_8(regindex) _aty_ld_8(regindex, par)
+#define aty_st_8(regindex, val) _aty_st_8(regindex, val, par)
/*
* Functions to read from/write to the pll registers
*/
-#define aty_ld_pll(pll_index) _aty_ld_pll(pll_index, info)
-#define aty_st_pll(pll_index, val) _aty_st_pll(pll_index, val, info)
+#define aty_ld_pll(pll_index) _aty_ld_pll(pll_index, par)
+#define aty_st_pll(pll_index, val) _aty_st_pll(pll_index, val, par)
static u32
_aty_ld_pll(unsigned int pll_index,
- const struct fb_info_aty128 *info)
+ const struct aty128fb_par *par)
{
- aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x1F);
- return aty_ld_le32(CLOCK_CNTL_DATA);
+ aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x3F);
+ return aty_ld_le32(CLOCK_CNTL_DATA);
}
static void
_aty_st_pll(unsigned int pll_index, u32 val,
- const struct fb_info_aty128 *info)
+ const struct aty128fb_par *par)
{
- aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x1F) | PLL_WR_EN);
- aty_st_le32(CLOCK_CNTL_DATA, val);
+ aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x3F) | PLL_WR_EN);
+ aty_st_le32(CLOCK_CNTL_DATA, val);
}
/* return true when the PLL has completed an atomic update */
static int
-aty_pll_readupdate(const struct fb_info_aty128 *info)
+aty_pll_readupdate(const struct aty128fb_par *par)
{
- return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
+ return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
}
static void
-aty_pll_wait_readupdate(const struct fb_info_aty128 *info)
+aty_pll_wait_readupdate(const struct aty128fb_par *par)
{
- unsigned long timeout = jiffies + HZ/100; // should be more than enough
- int reset = 1;
+ unsigned long timeout = jiffies + HZ/100; // should be more than enough
+ int reset = 1;
- while (time_before(jiffies, timeout))
- if (aty_pll_readupdate(info)) {
- reset = 0;
- break;
- }
+ while (time_before(jiffies, timeout))
+ if (aty_pll_readupdate(par)) {
+ reset = 0;
+ break;
+ }
- if (reset) /* reset engine?? */
- printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
+ if (reset) /* reset engine?? */
+ printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
}
/* tell PLL to update */
static void
-aty_pll_writeupdate(const struct fb_info_aty128 *info)
+aty_pll_writeupdate(const struct aty128fb_par *par)
{
- aty_pll_wait_readupdate(info);
+ aty_pll_wait_readupdate(par);
- aty_st_pll(PPLL_REF_DIV,
- aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
+ aty_st_pll(PPLL_REF_DIV,
+ aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
}
/* write to the scratch register to test r/w functionality */
static int __init
-register_test(const struct fb_info_aty128 *info)
+register_test(const struct aty128fb_par *par)
{
- u32 val;
- int flag = 0;
+ u32 val;
+ int flag = 0;
- val = aty_ld_le32(BIOS_0_SCRATCH);
+ val = aty_ld_le32(BIOS_0_SCRATCH);
- aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
- if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
- aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
+ aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
+ if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
+ aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
- if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
- flag = 1;
- }
+ if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
+ flag = 1;
+ }
- aty_st_le32(BIOS_0_SCRATCH, val); // restore value
- return flag;
+ aty_st_le32(BIOS_0_SCRATCH, val); // restore value
+ return flag;
}
- /*
- * Accelerator engine functions
- */
+/*
+ * Accelerator engine functions
+ */
static void
-do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
+do_wait_for_fifo(u16 entries, struct aty128fb_par *par)
{
- int i;
-
- for (;;) {
- for (i = 0; i < 2000000; i++) {
- info->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
- if (info->fifo_slots >= entries)
- return;
- }
- aty128_reset_engine(info);
- }
+ int i;
+
+ for (;;) {
+ for (i = 0; i < 2000000; i++) {
+ par->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
+ if (par->fifo_slots >= entries)
+ return;
+ }
+ aty128_reset_engine(par);
+ }
}
static void
-wait_for_idle(struct fb_info_aty128 *info)
+wait_for_idle(struct aty128fb_par *par)
{
- int i;
-
- do_wait_for_fifo(64, info);
-
- for (;;) {
- for (i = 0; i < 2000000; i++) {
- if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
- aty128_flush_pixel_cache(info);
- info->blitter_may_be_busy = 0;
- return;
- }
- }
- aty128_reset_engine(info);
- }
+ int i;
+
+ do_wait_for_fifo(64, par);
+
+ for (;;) {
+ for (i = 0; i < 2000000; i++) {
+ if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
+ aty128_flush_pixel_cache(par);
+ par->blitter_may_be_busy = 0;
+ return;
+ }
+ }
+ aty128_reset_engine(par);
+ }
}
static void
-wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
+wait_for_fifo(u16 entries, struct aty128fb_par *par)
{
- if (info->fifo_slots < entries)
- do_wait_for_fifo(64, info);
- info->fifo_slots -= entries;
+ if (par->fifo_slots < entries)
+ do_wait_for_fifo(64, par);
+ par->fifo_slots -= entries;
}
static void
-aty128_flush_pixel_cache(const struct fb_info_aty128 *info)
+aty128_flush_pixel_cache(const struct aty128fb_par *par)
{
- int i;
- u32 tmp;
+ int i;
+ u32 tmp;
- tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
- tmp &= ~(0x00ff);
- tmp |= 0x00ff;
- aty_st_le32(PC_NGUI_CTLSTAT, tmp);
+ tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
+ tmp &= ~(0x00ff);
+ tmp |= 0x00ff;
+ aty_st_le32(PC_NGUI_CTLSTAT, tmp);
- for (i = 0; i < 2000000; i++)
- if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
- break;
+ for (i = 0; i < 2000000; i++)
+ if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
+ break;
}
static void
-aty128_reset_engine(const struct fb_info_aty128 *info)
+aty128_reset_engine(const struct aty128fb_par *par)
{
- u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
+ u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
- aty128_flush_pixel_cache(info);
+ aty128_flush_pixel_cache(par);
- clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
- mclk_cntl = aty_ld_pll(MCLK_CNTL);
+ clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
+ mclk_cntl = aty_ld_pll(MCLK_CNTL);
- aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
+ aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
- gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
- aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
- aty_ld_le32(GEN_RESET_CNTL);
- aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
- aty_ld_le32(GEN_RESET_CNTL);
+ gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
+ aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
+ aty_ld_le32(GEN_RESET_CNTL);
+ aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
+ aty_ld_le32(GEN_RESET_CNTL);
- aty_st_pll(MCLK_CNTL, mclk_cntl);
- aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
- aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
+ aty_st_pll(MCLK_CNTL, mclk_cntl);
+ aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
+ aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
- /* use old pio mode */
- aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
+ /* use old pio mode */
+ aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
- DBG("engine reset");
+ DBG("engine reset");
}
static void
-aty128_init_engine(const struct aty128fb_par *par,
- struct fb_info_aty128 *info)
+aty128_init_engine(struct aty128fb_par *par)
{
- u32 pitch_value;
+ u32 pitch_value;
- wait_for_idle(info);
+ wait_for_idle(par);
- /* 3D scaler not spoken here */
- wait_for_fifo(1, info);
- aty_st_le32(SCALE_3D_CNTL, 0x00000000);
+ /* 3D scaler not spoken here */
+ wait_for_fifo(1, par);
+ aty_st_le32(SCALE_3D_CNTL, 0x00000000);
- aty128_reset_engine(info);
-
- pitch_value = par->crtc.pitch;
- if (par->crtc.bpp == 24) {
- pitch_value = pitch_value * 3;
- }
-
- wait_for_fifo(4, info);
- /* setup engine offset registers */
- aty_st_le32(DEFAULT_OFFSET, 0x00000000);
-
- /* setup engine pitch registers */
- aty_st_le32(DEFAULT_PITCH, pitch_value);
-
- /* set the default scissor register to max dimensions */
- aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
-
- /* set the drawing controls registers */
- aty_st_le32(DP_GUI_MASTER_CNTL,
- GMC_SRC_PITCH_OFFSET_DEFAULT |
- GMC_DST_PITCH_OFFSET_DEFAULT |
- GMC_SRC_CLIP_DEFAULT |
- GMC_DST_CLIP_DEFAULT |
- GMC_BRUSH_SOLIDCOLOR |
- (bpp_to_depth(par->crtc.bpp) << 8) |
- GMC_SRC_DSTCOLOR |
- GMC_BYTE_ORDER_MSB_TO_LSB |
- GMC_DP_CONVERSION_TEMP_6500 |
- ROP3_PATCOPY |
- GMC_DP_SRC_RECT |
- GMC_3D_FCN_EN_CLR |
- GMC_DST_CLR_CMP_FCN_CLEAR |
- GMC_AUX_CLIP_CLEAR |
- GMC_WRITE_MASK_SET);
-
- wait_for_fifo(8, info);
- /* clear the line drawing registers */
- aty_st_le32(DST_BRES_ERR, 0);
- aty_st_le32(DST_BRES_INC, 0);
- aty_st_le32(DST_BRES_DEC, 0);
-
- /* set brush color registers */
- aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
- aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
-
- /* set source color registers */
- aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF); /* white */
- aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000); /* black */
-
- /* default write mask */
- aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
-
- /* Wait for all the writes to be completed before returning */
- wait_for_idle(info);
-}
+ aty128_reset_engine(par);
+ pitch_value = par->crtc.pitch;
+ if (par->crtc.bpp == 24) {
+ pitch_value = pitch_value * 3;
+ }
-/* convert bpp values to their register representation */
+ wait_for_fifo(4, par);
+ /* setup engine offset registers */
+ aty_st_le32(DEFAULT_OFFSET, 0x00000000);
+
+ /* setup engine pitch registers */
+ aty_st_le32(DEFAULT_PITCH, pitch_value);
+
+ /* set the default scissor register to max dimensions */
+ aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
+
+ /* set the drawing controls registers */
+ aty_st_le32(DP_GUI_MASTER_CNTL,
+ GMC_SRC_PITCH_OFFSET_DEFAULT |
+ GMC_DST_PITCH_OFFSET_DEFAULT |
+ GMC_SRC_CLIP_DEFAULT |
+ GMC_DST_CLIP_DEFAULT |
+ GMC_BRUSH_SOLIDCOLOR |
+ (depth_to_dst(par->crtc.depth) << 8) |
+ GMC_SRC_DSTCOLOR |
+ GMC_BYTE_ORDER_MSB_TO_LSB |
+ GMC_DP_CONVERSION_TEMP_6500 |
+ ROP3_PATCOPY |
+ GMC_DP_SRC_RECT |
+ GMC_3D_FCN_EN_CLR |
+ GMC_DST_CLR_CMP_FCN_CLEAR |
+ GMC_AUX_CLIP_CLEAR |
+ GMC_WRITE_MASK_SET);
+
+ wait_for_fifo(8, par);
+ /* clear the line drawing registers */
+ aty_st_le32(DST_BRES_ERR, 0);
+ aty_st_le32(DST_BRES_INC, 0);
+ aty_st_le32(DST_BRES_DEC, 0);
+
+ /* set brush color registers */
+ aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
+ aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
+
+ /* set source color registers */
+ aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF); /* white */
+ aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000); /* black */
+
+ /* default write mask */
+ aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
+
+ /* Wait for all the writes to be completed before returning */
+ wait_for_idle(par);
+}
+
+
+/* convert depth values to their register representation */
static u32
-bpp_to_depth(u32 bpp)
-{
- if (bpp <= 8)
- return DST_8BPP;
- else if (bpp <= 16)
- return DST_15BPP;
- else if (bpp <= 24)
- return DST_24BPP;
- else if (bpp <= 32)
- return DST_32BPP;
-
- return -EINVAL;
+depth_to_dst(u32 depth)
+{
+ if (depth <= 8)
+ return DST_8BPP;
+ else if (depth <= 15)
+ return DST_15BPP;
+ else if (depth == 16)
+ return DST_16BPP;
+ else if (depth <= 24)
+ return DST_24BPP;
+ else if (depth <= 32)
+ return DST_32BPP;
+
+ return -EINVAL;
}
- /*
+/*
* CRTC programming
*/
/* Program the CRTC registers */
static void
aty128_set_crtc(const struct aty128_crtc *crtc,
- const struct fb_info_aty128 *info)
+ const struct aty128fb_par *par)
{
- aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
- aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
- aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
- aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
- aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
- aty_st_le32(CRTC_PITCH, crtc->pitch);
- aty_st_le32(CRTC_OFFSET, crtc->offset);
- aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
- /* Disable ATOMIC updating. Is this the right place?
- * -- BenH: Breaks on my G4
- */
-#if 0
- aty_st_le32(PPLL_CNTL, aty_ld_le32(PPLL_CNTL) & ~(0x00030000));
-#endif
+ aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
+ aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
+ aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
+ aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
+ aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
+ aty_st_le32(CRTC_PITCH, crtc->pitch);
+ aty_st_le32(CRTC_OFFSET, crtc->offset);
+ aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
+ /* Disable ATOMIC updating. Is this the right place? */
+ aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000));
}
static int
aty128_var_to_crtc(const struct fb_var_screeninfo *var,
- struct aty128_crtc *crtc,
- const struct fb_info_aty128 *info)
-{
- 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_wid, h_sync_pol;
- u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
- u32 depth, bytpp;
- u8 hsync_strt_pix[5] = { 0, 0x12, 9, 6, 5 };
- u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
-
- /* 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;
-
- /* check for mode eligibility
- * accept only non interlaced modes */
- if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
- return -EINVAL;
+ struct aty128_crtc *crtc,
+ const struct aty128fb_par *par)
+{
+ u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp, dst;
+ u32 left, right, upper, lower, hslen, vslen, sync, vmode;
+ u32 h_total, h_disp, h_sync_strt, h_sync_wid, h_sync_pol;
+ u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
+ u32 depth, bytpp;
+ u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
+
+ /* 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;
+
+ if (bpp != 16)
+ depth = bpp;
+ else
+ depth = (var->green.length == 6) ? 16 : 15;
- /* convert (and round up) and validate */
- xres = (xres + 7) & ~7;
- xoffset = (xoffset + 7) & ~7;
+ /* check for mode eligibility
+ * accept only non interlaced modes */
+ if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+ return -EINVAL;
- if (vxres < xres + xoffset)
- vxres = xres + xoffset;
+ /* convert (and round up) and validate */
+ xres = (xres + 7) & ~7;
+ xoffset = (xoffset + 7) & ~7;
- if (vyres < yres + yoffset)
- vyres = yres + yoffset;
+ if (vxres < xres + xoffset)
+ vxres = xres + xoffset;
- /* convert bpp into ATI register depth */
- depth = bpp_to_depth(bpp);
+ if (vyres < yres + yoffset)
+ vyres = yres + yoffset;
- /* make sure we didn't get an invalid depth */
- if (depth == -EINVAL) {
- printk(KERN_ERR "aty128fb: Invalid depth\n");
- return -EINVAL;
- }
+ /* convert depth into ATI register depth */
+ dst = depth_to_dst(depth);
- /* convert depth to bpp */
- bytpp = mode_bytpp[depth];
+ if (dst == -EINVAL) {
+ printk(KERN_ERR "aty128fb: Invalid depth or RGBA\n");
+ return -EINVAL;
+ }
- /* make sure there is enough video ram for the mode */
- if ((u32)(vxres * vyres * bytpp) > info->vram_size) {
- printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
- return -EINVAL;
- }
+ /* convert register depth to bytes per pixel */
+ bytpp = mode_bytpp[dst];
- h_disp = (xres >> 3) - 1;
- h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
+ /* make sure there is enough video ram for the mode */
+ if ((u32)(vxres * vyres * bytpp) > par->vram_size) {
+ printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
+ return -EINVAL;
+ }
- v_disp = yres - 1;
- v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
+ h_disp = (xres >> 3) - 1;
+ h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
- /* check to make sure h_total and v_total are in range */
- if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
- printk(KERN_ERR "aty128fb: invalid width ranges\n");
- return -EINVAL;
- }
+ v_disp = yres - 1;
+ v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
- h_sync_wid = (hslen + 7) >> 3;
- if (h_sync_wid == 0)
- h_sync_wid = 1;
- else if (h_sync_wid > 0x3f) /* 0x3f = max hwidth */
- h_sync_wid = 0x3f;
+ /* check to make sure h_total and v_total are in range */
+ if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
+ printk(KERN_ERR "aty128fb: invalid width ranges\n");
+ return -EINVAL;
+ }
+
+ h_sync_wid = (hslen + 7) >> 3;
+ if (h_sync_wid == 0)
+ h_sync_wid = 1;
+ else if (h_sync_wid > 0x3f) /* 0x3f = max hwidth */
+ h_sync_wid = 0x3f;
- h_sync_strt = h_disp + (right >> 3);
+ h_sync_strt = (h_disp << 3) + right;
- v_sync_wid = vslen;
- if (v_sync_wid == 0)
- v_sync_wid = 1;
- else if (v_sync_wid > 0x1f) /* 0x1f = max vwidth */
- v_sync_wid = 0x1f;
+ v_sync_wid = vslen;
+ if (v_sync_wid == 0)
+ v_sync_wid = 1;
+ else if (v_sync_wid > 0x1f) /* 0x1f = max vwidth */
+ v_sync_wid = 0x1f;
- v_sync_strt = v_disp + lower;
+ v_sync_strt = v_disp + lower;
- h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
- v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+ h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+ v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
- c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
+ c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
- crtc->gen_cntl = 0x3000000L | c_sync | (depth << 8);
+ crtc->gen_cntl = 0x3000000L | c_sync | (dst << 8);
- crtc->h_total = h_total | (h_disp << 16);
- crtc->v_total = v_total | (v_disp << 16);
+ crtc->h_total = h_total | (h_disp << 16);
+ crtc->v_total = v_total | (v_disp << 16);
- crtc->h_sync_strt_wid = hsync_strt_pix[bytpp] | (h_sync_strt << 3) |
- (h_sync_wid << 16) | (h_sync_pol << 23);
- crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
+ crtc->h_sync_strt_wid = h_sync_strt | (h_sync_wid << 16) |
+ (h_sync_pol << 23);
+ crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
(v_sync_pol << 23);
- crtc->pitch = vxres >> 3;
+ crtc->pitch = vxres >> 3;
- crtc->offset = 0;
+ crtc->offset = 0;
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
- crtc->offset_cntl = 0x00010000;
- else
- crtc->offset_cntl = 0;
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+ crtc->offset_cntl = 0x00010000;
+ else
+ crtc->offset_cntl = 0;
- crtc->vxres = vxres;
- crtc->vyres = vyres;
- crtc->xoffset = xoffset;
- crtc->yoffset = yoffset;
- crtc->bpp = bpp;
+ crtc->vxres = vxres;
+ crtc->vyres = vyres;
+ crtc->xoffset = xoffset;
+ crtc->yoffset = yoffset;
+ crtc->depth = depth;
+ crtc->bpp = bpp;
- return 0;
+ return 0;
}
static int
-aty128_bpp_to_var(int pix_width, struct fb_var_screeninfo *var)
+aty128_pix_width_to_var(int pix_width, struct fb_var_screeninfo *var)
{
- /* fill in pixel info */
- switch (pix_width) {
- case CRTC_PIX_WIDTH_8BPP:
- 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 CRTC_PIX_WIDTH_15BPP:
- case CRTC_PIX_WIDTH_16BPP:
- var->bits_per_pixel = 16;
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
+ /* fill in pixel info */
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
var->blue.offset = 0;
- var->blue.length = 5;
+ var->blue.msb_right = 0;
var->transp.offset = 0;
var->transp.length = 0;
- break;
- case CRTC_PIX_WIDTH_24BPP:
- var->bits_per_pixel = 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:
- 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:
- printk(KERN_ERR "aty128fb: Invalid pixel width\n");
- return -EINVAL;
- }
+ var->transp.msb_right = 0;
+ switch (pix_width) {
+ case CRTC_PIX_WIDTH_8BPP:
+ var->bits_per_pixel = 8;
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ case CRTC_PIX_WIDTH_15BPP:
+ var->bits_per_pixel = 16;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.length = 5;
+ break;
+ case CRTC_PIX_WIDTH_16BPP:
+ var->bits_per_pixel = 16;
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ break;
+ case CRTC_PIX_WIDTH_24BPP:
+ var->bits_per_pixel = 24;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ case CRTC_PIX_WIDTH_32BPP:
+ var->bits_per_pixel = 32;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ break;
+ default:
+ printk(KERN_ERR "aty128fb: Invalid pixel width\n");
+ return -EINVAL;
+ }
- return 0;
+ return 0;
}
static int
aty128_crtc_to_var(const struct aty128_crtc *crtc,
- struct fb_var_screeninfo *var)
+ struct fb_var_screeninfo *var)
+{
+ u32 xres, yres, 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, c_sync;
+ u32 pix_width;
+
+ /* fun with masking */
+ h_total = crtc->h_total & 0x1ff;
+ h_disp = (crtc->h_total >> 16) & 0xff;
+ h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
+ h_sync_dly = crtc->h_sync_strt_wid & 0x7;
+ h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x3f;
+ h_sync_pol = (crtc->h_sync_strt_wid >> 23) & 0x1;
+ v_total = crtc->v_total & 0x7ff;
+ v_disp = (crtc->v_total >> 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 >> 23) & 0x1;
+ c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
+ pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
+
+ /* do conversions */
+ xres = (h_disp + 1) << 3;
+ yres = v_disp + 1;
+ left = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
+ right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
+ hslen = h_sync_wid << 3;
+ 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) |
+ (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
+
+ aty128_pix_width_to_var(pix_width, var);
+
+ var->xres = xres;
+ var->yres = yres;
+ var->xres_virtual = crtc->vxres;
+ var->yres_virtual = crtc->vyres;
+ 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;
+
+ return 0;
+}
+
+#ifdef CONFIG_PMAC_PBOOK
+static void
+aty128_set_crt_enable(struct aty128fb_par *par, int on)
{
- u32 xres, yres, 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, c_sync;
- u32 pix_width;
-
- /* fun with masking */
- h_total = crtc->h_total & 0x1ff;
- h_disp = (crtc->h_total >> 16) & 0xff;
- h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
- h_sync_dly = crtc->h_sync_strt_wid & 0x7;
- h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x3f;
- h_sync_pol = (crtc->h_sync_strt_wid >> 23) & 0x1;
- v_total = crtc->v_total & 0x7ff;
- v_disp = (crtc->v_total >> 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 >> 23) & 0x1;
- c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
- pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
-
- /* do conversions */
- xres = (h_disp + 1) << 3;
- yres = v_disp + 1;
- left = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
- right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
- hslen = h_sync_wid << 3;
- 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) |
- (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
-
- aty128_bpp_to_var(pix_width, var);
-
- var->xres = xres;
- var->yres = yres;
- var->xres_virtual = crtc->vxres;
- var->yres_virtual = crtc->vyres;
- 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;
-
- return 0;
+ if (on) {
+ aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) | CRT_CRTC_ON);
+ aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | DAC_PALETTE2_SNOOP_EN));
+ } else
+ aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON);
+}
+
+static void
+aty128_set_lcd_enable(struct aty128fb_par *par, int on)
+{
+ u32 reg;
+
+ if (on) {
+ reg = aty_ld_le32(LVDS_GEN_CNTL);
+ reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION;
+ reg &= ~LVDS_DISPLAY_DIS;
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef CONFIG_PMAC_BACKLIGHT
+ aty128_set_backlight_enable(get_backlight_enable(),
+ get_backlight_level(), par);
+#endif
+ } else {
+#ifdef CONFIG_PMAC_BACKLIGHT
+ aty128_set_backlight_enable(0, 0, par);
+#endif
+ reg = aty_ld_le32(LVDS_GEN_CNTL);
+ reg |= LVDS_DISPLAY_DIS;
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+ mdelay(100);
+ reg &= ~(LVDS_ON /*| LVDS_EN*/);
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+ }
}
+#endif
static void
-aty128_set_pll(struct aty128_pll *pll, const struct fb_info_aty128 *info)
+aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par)
{
- u32 div3;
+ u32 div3;
- unsigned char post_conv[] = /* register values for post dividers */
+ unsigned char post_conv[] = /* register values for post dividers */
{ 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 };
- /* select PPLL_DIV_3 */
- aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
+ /* select PPLL_DIV_3 */
+ aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
- /* reset PLL */
- aty_st_pll(PPLL_CNTL,
- aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
+ /* reset PLL */
+ aty_st_pll(PPLL_CNTL,
+ aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
- /* write the reference divider */
- aty_pll_wait_readupdate(info);
- aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider & 0x3ff);
- aty_pll_writeupdate(info);
+ /* write the reference divider */
+ aty_pll_wait_readupdate(par);
+ aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider & 0x3ff);
+ aty_pll_writeupdate(par);
- div3 = aty_ld_pll(PPLL_DIV_3);
- div3 &= ~PPLL_FB3_DIV_MASK;
- div3 |= pll->feedback_divider;
- div3 &= ~PPLL_POST3_DIV_MASK;
- div3 |= post_conv[pll->post_divider] << 16;
+ div3 = aty_ld_pll(PPLL_DIV_3);
+ div3 &= ~PPLL_FB3_DIV_MASK;
+ div3 |= pll->feedback_divider;
+ div3 &= ~PPLL_POST3_DIV_MASK;
+ div3 |= post_conv[pll->post_divider] << 16;
- /* write feedback and post dividers */
- aty_pll_wait_readupdate(info);
- aty_st_pll(PPLL_DIV_3, div3);
- aty_pll_writeupdate(info);
+ /* write feedback and post dividers */
+ aty_pll_wait_readupdate(par);
+ aty_st_pll(PPLL_DIV_3, div3);
+ aty_pll_writeupdate(par);
- aty_pll_wait_readupdate(info);
- aty_st_pll(HTOTAL_CNTL, 0); /* no horiz crtc adjustment */
- aty_pll_writeupdate(info);
+ aty_pll_wait_readupdate(par);
+ aty_st_pll(HTOTAL_CNTL, 0); /* no horiz crtc adjustment */
+ aty_pll_writeupdate(par);
- /* clear the reset, just in case */
- aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
+ /* clear the reset, just in case */
+ aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
}
static int
aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
- const struct fb_info_aty128 *info)
-{
- const struct aty128_constants c = info->constants;
- unsigned char post_dividers[] = {1,2,4,8,3,6,12};
- u32 output_freq;
- u32 vclk; /* in .01 MHz */
- int i;
- u32 n, d;
-
- vclk = 100000000 / period_in_ps; /* convert units to 10 kHz */
-
- /* adjust pixel clock if necessary */
- if (vclk > c.ppll_max)
- vclk = c.ppll_max;
- if (vclk * 12 < c.ppll_min)
- vclk = c.ppll_min/12;
-
- /* now, find an acceptable divider */
- for (i = 0; i < sizeof(post_dividers); i++) {
- output_freq = post_dividers[i] * vclk;
- if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
- break;
- }
+ const struct aty128fb_par *par)
+{
+ const struct aty128_constants c = par->constants;
+ unsigned char post_dividers[] = {1,2,4,8,3,6,12};
+ u32 output_freq;
+ u32 vclk; /* in .01 MHz */
+ int i;
+ u32 n, d;
+
+ vclk = 100000000 / period_in_ps; /* convert units to 10 kHz */
+
+ /* adjust pixel clock if necessary */
+ if (vclk > c.ppll_max)
+ vclk = c.ppll_max;
+ if (vclk * 12 < c.ppll_min)
+ vclk = c.ppll_min/12;
+
+ /* now, find an acceptable divider */
+ for (i = 0; i < sizeof(post_dividers); i++) {
+ output_freq = post_dividers[i] * vclk;
+ if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
+ break;
+ }
- /* calculate feedback divider */
- n = c.ref_divider * output_freq;
- d = c.dotclock;
+ /* calculate feedback divider */
+ n = c.ref_divider * output_freq;
+ d = c.dotclock;
- pll->post_divider = post_dividers[i];
- pll->feedback_divider = round_div(n, d);
- pll->vclk = vclk;
+ pll->post_divider = post_dividers[i];
+ pll->feedback_divider = round_div(n, d);
+ pll->vclk = vclk;
- DBG("post %d feedback %d vlck %d output %d ref_divider %d "
- "vclk_per: %d\n", pll->post_divider,
- pll->feedback_divider, vclk, output_freq,
- c.ref_divider, period_in_ps);
+ DBG("post %d feedback %d vlck %d output %d ref_divider %d "
+ "vclk_per: %d\n", pll->post_divider,
+ pll->feedback_divider, vclk, output_freq,
+ c.ref_divider, period_in_ps);
- return 0;
+ return 0;
}
static int
-aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var,
- const struct fb_info_aty128 *info)
+aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var)
{
- var->pixclock = 100000000 / pll->vclk;
+ var->pixclock = 100000000 / pll->vclk;
- return 0;
+ return 0;
}
static void
aty128_set_fifo(const struct aty128_ddafifo *dsp,
- const struct fb_info_aty128 *info)
+ const struct aty128fb_par *par)
{
- aty_st_le32(DDA_CONFIG, dsp->dda_config);
- aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
+ aty_st_le32(DDA_CONFIG, dsp->dda_config);
+ aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
}
static int
aty128_ddafifo(struct aty128_ddafifo *dsp,
- const struct aty128_pll *pll,
- u32 bpp,
- const struct fb_info_aty128 *info)
-{
- const struct aty128_meminfo *m = info->mem;
- u32 xclk = info->constants.xclk;
- u32 fifo_width = info->constants.fifo_width;
- u32 fifo_depth = info->constants.fifo_depth;
- s32 x, b, p, ron, roff;
- u32 n, d;
-
- /* 15bpp is really 16bpp */
- if (bpp == 15)
- bpp = 16;
-
- n = xclk * fifo_width;
- d = pll->vclk * bpp;
- x = round_div(n, d);
-
- ron = 4 * m->MB +
- 3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
- 2 * m->Trp +
- m->Twr +
- m->CL +
- m->Tr2w +
- x;
-
- DBG("x %x\n", x);
-
- b = 0;
- while (x) {
- x >>= 1;
- b++;
- }
- p = b + 1;
+ const struct aty128_pll *pll,
+ u32 depth,
+ const struct aty128fb_par *par)
+{
+ const struct aty128_meminfo *m = par->mem;
+ u32 xclk = par->constants.xclk;
+ u32 fifo_width = par->constants.fifo_width;
+ u32 fifo_depth = par->constants.fifo_depth;
+ s32 x, b, p, ron, roff;
+ u32 n, d, bpp;
+
+ /* round up to multiple of 8 */
+ bpp = (depth+7) & ~7;
+
+ n = xclk * fifo_width;
+ d = pll->vclk * bpp;
+ x = round_div(n, d);
+
+ ron = 4 * m->MB +
+ 3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
+ 2 * m->Trp +
+ m->Twr +
+ m->CL +
+ m->Tr2w +
+ x;
+
+ DBG("x %x\n", x);
+
+ b = 0;
+ while (x) {
+ x >>= 1;
+ b++;
+ }
+ p = b + 1;
- ron <<= (11 - p);
+ ron <<= (11 - p);
- n <<= (11 - p);
- x = round_div(n, d);
- roff = x * (fifo_depth - 4);
+ n <<= (11 - p);
+ x = round_div(n, d);
+ roff = x * (fifo_depth - 4);
- if ((ron + m->Rloop) >= roff) {
- printk(KERN_ERR "aty128fb: Mode out of range!\n");
- return -EINVAL;
- }
+ if ((ron + m->Rloop) >= roff) {
+ printk(KERN_ERR "aty128fb: Mode out of range!\n");
+ return -EINVAL;
+ }
- DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
- p, m->Rloop, x, ron, roff);
+ DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
+ p, m->Rloop, x, ron, roff);
- dsp->dda_config = p << 16 | m->Rloop << 20 | x;
- dsp->dda_on_off = ron << 16 | roff;
+ dsp->dda_config = p << 16 | m->Rloop << 20 | x;
+ dsp->dda_on_off = ron << 16 | roff;
- return 0;
+ return 0;
}
/*
* This actually sets the video mode.
*/
-static void
-aty128_set_par(struct aty128fb_par *par,
- struct fb_info_aty128 *info)
+static int
+aty128fb_set_par(struct fb_info *info)
{
- u32 config;
-
- info->current_par = *par;
+ struct aty128fb_par *par = info->par;
+ u32 config;
- if (info->blitter_may_be_busy)
- wait_for_idle(info);
-
- /* clear all registers that may interfere with mode setting */
- aty_st_le32(OVR_CLR, 0);
- aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
- aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
- aty_st_le32(OV0_SCALE_CNTL, 0);
- aty_st_le32(MPP_TB_CONFIG, 0);
- aty_st_le32(MPP_GP_CONFIG, 0);
- aty_st_le32(SUBPIC_CNTL, 0);
- aty_st_le32(VIPH_CONTROL, 0);
- aty_st_le32(I2C_CNTL_1, 0); /* turn off i2c */
- aty_st_le32(GEN_INT_CNTL, 0); /* turn off interrupts */
- aty_st_le32(CAP0_TRIG_CNTL, 0);
- aty_st_le32(CAP1_TRIG_CNTL, 0);
-
- aty_st_8(CRTC_EXT_CNTL + 1, 4); /* turn video off */
-
- aty128_set_crtc(&par->crtc, info);
- aty128_set_pll(&par->pll, info);
- aty128_set_fifo(&par->fifo_reg, info);
-
- config = aty_ld_le32(CONFIG_CNTL) & ~3;
+ if (par->blitter_may_be_busy)
+ wait_for_idle(par);
+
+ /* clear all registers that may interfere with mode setting */
+ aty_st_le32(OVR_CLR, 0);
+ aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
+ aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
+ aty_st_le32(OV0_SCALE_CNTL, 0);
+ aty_st_le32(MPP_TB_CONFIG, 0);
+ aty_st_le32(MPP_GP_CONFIG, 0);
+ aty_st_le32(SUBPIC_CNTL, 0);
+ aty_st_le32(VIPH_CONTROL, 0);
+ aty_st_le32(I2C_CNTL_1, 0); /* turn off i2c */
+ aty_st_le32(GEN_INT_CNTL, 0); /* turn off interrupts */
+ aty_st_le32(CAP0_TRIG_CNTL, 0);
+ aty_st_le32(CAP1_TRIG_CNTL, 0);
+
+ aty_st_8(CRTC_EXT_CNTL + 1, 4); /* turn video off */
+
+ aty128_set_crtc(&par->crtc, par);
+ aty128_set_pll(&par->pll, par);
+ aty128_set_fifo(&par->fifo_reg, par);
+
+ config = aty_ld_le32(CONFIG_CNTL) & ~3;
#if defined(__BIG_ENDIAN)
- if (par->crtc.bpp >= 24)
- config |= 2; /* make aperture do 32 byte swapping */
- else if (par->crtc.bpp > 8)
- config |= 1; /* make aperture do 16 byte swapping */
+ if (par->crtc.bpp == 32)
+ config |= 2; /* make aperture do 32 bit swapping */
+ else if (par->crtc.bpp == 16)
+ config |= 1; /* make aperture do 16 bit swapping */
#endif
- aty_st_le32(CONFIG_CNTL, config);
- aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */
+ aty_st_le32(CONFIG_CNTL, config);
+ aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */
+
+ info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
+ info->fix.visual = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR
+ : FB_VISUAL_DIRECTCOLOR;
- if (par->accel_flags & FB_ACCELF_TEXT)
- aty128_init_engine(par, info);
+#ifdef CONFIG_PMAC_PBOOK
+ if (par->chip_gen == rage_M3) {
+ aty128_set_crt_enable(par, par->crt_on);
+ aty128_set_lcd_enable(par, par->lcd_on);
+ }
+#endif
+ if (par->accel_flags & FB_ACCELF_TEXT)
+ aty128_init_engine(par);
-#if defined(CONFIG_BOOTX_TEXT)
- btext_update_display(info->frame_buffer_phys,
- (((par->crtc.h_total>>16) & 0xff)+1)*8,
- ((par->crtc.v_total>>16) & 0x7ff)+1,
- par->crtc.bpp,
- par->crtc.vxres*par->crtc.bpp/8);
+#ifdef CONFIG_BOOTX_TEXT
+ btext_update_display(info->fix.smem_start,
+ (((par->crtc.h_total>>16) & 0xff)+1)*8,
+ ((par->crtc.v_total>>16) & 0x7ff)+1,
+ par->crtc.bpp,
+ par->crtc.vxres*par->crtc.bpp/8);
#endif /* CONFIG_BOOTX_TEXT */
+
+ return 0;
}
- /*
- * encode/decode the User Defined Part of the Display
- */
+/*
+ * encode/decode the User Defined Part of the Display
+ */
static int
-aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par,
- const struct fb_info_aty128 *info)
+aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par)
{
- int err;
-
- if ((err = aty128_var_to_crtc(var, &par->crtc, info)))
- return err;
+ int err;
- if ((err = aty128_var_to_pll(var->pixclock, &par->pll, info)))
- return err;
+ if ((err = aty128_var_to_crtc(var, &par->crtc, par)))
+ return err;
- if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.bpp, info)))
- return err;
+ if ((err = aty128_var_to_pll(var->pixclock, &par->pll, par)))
+ return err;
- if (var->accel_flags & FB_ACCELF_TEXT)
- par->accel_flags = FB_ACCELF_TEXT;
- else
- par->accel_flags = 0;
+ if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.depth, par)))
+ return err;
+ par->accel_flags = var->accel_flags;
- return 0;
+ return 0;
}
static int
aty128_encode_var(struct fb_var_screeninfo *var,
- const struct aty128fb_par *par,
- const struct fb_info_aty128 *info)
+ const struct aty128fb_par *par)
{
- int err;
-
- if ((err = aty128_crtc_to_var(&par->crtc, var)))
- return err;
+ int err;
- if ((err = aty128_pll_to_var(&par->pll, var, info)))
- return err;
+ if ((err = aty128_crtc_to_var(&par->crtc, var)))
+ return err;
- var->red.msb_right = 0;
- var->green.msb_right = 0;
- var->blue.msb_right = 0;
- var->transp.msb_right = 0;
+ if ((err = aty128_pll_to_var(&par->pll, var)))
+ return err;
- var->nonstd = 0;
- var->activate = 0;
+ var->nonstd = 0;
+ var->activate = 0;
- var->height = -1;
- var->width = -1;
- var->accel_flags = par->accel_flags;
+ var->height = -1;
+ var->width = -1;
+ var->accel_flags = par->accel_flags;
- return 0;
+ return 0;
}
- /*
- * Get the User Defined Part of the Display
- */
-
-static int
-aty128fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
-{
- const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
-
- if (con == -1)
- aty128_encode_var(var, &info->default_par, info);
- else
- *var = fb_display[con].var;
- return 0;
-}
-
-
- /*
- * Set the User Defined Part of the Display
- */
-
static int
-aty128fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- struct aty128fb_par par;
- struct display *display;
- int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
- int accel, err;
-
- display = (con >= 0) ? &fb_display[con] : fb->disp;
-
- /* basic (in)sanity checks */
- if (!var->xres)
- var->xres = 1;
- if (!var->yres)
- var->yres = 1;
- if (var->xres > var->xres_virtual)
- var->xres_virtual = var->xres;
- if (var->yres > var->yres_virtual)
- var->yres_virtual = var->yres;
-
- switch (var->bits_per_pixel) {
- case 0 ... 8:
- var->bits_per_pixel = 8;
- break;
- case 9 ... 16:
- var->bits_per_pixel = 16;
- break;
- case 17 ... 24:
- var->bits_per_pixel = 24;
- break;
- case 25 ... 32:
- var->bits_per_pixel = 32;
- break;
- default:
- return -EINVAL;
- }
-
- if ((err = aty128_decode_var(var, &par, info)))
- return err;
-
- aty128_encode_var(var, &par, info);
+ struct aty128fb_par *par = info->par;
+ int err;
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
+ if ((err = aty128_decode_var(var, par)) != 0)
+ return err;
+ aty128_encode_var(var, par);
return 0;
-
- oldxres = display->var.xres;
- oldyres = display->var.yres;
- 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 || oldaccel != var->accel_flags) {
-
- struct fb_fix_screeninfo fix;
-
- aty128_encode_fix(&fix, &par, info);
- fb->screen_base = info->frame_buffer;
- 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 = 1;
- display->inverse = 0;
-
- accel = var->accel_flags & FB_ACCELF_TEXT;
- aty128_set_dispsw(display, info, par.crtc.bpp, accel);
-
- if (accel)
- display->scrollmode = SCROLL_YNOMOVE;
- else
- display->scrollmode = SCROLL_YREDRAW;
-
- if (info->fb_info.changevar)
- (*info->fb_info.changevar)(con);
- }
-
- if (!info->fb_info.display_fg || info->fb_info.display_fg->vc_num == con)
- aty128_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->fb_info);
- }
-
- return 0;
-}
-
-
-static void
-aty128_set_dispsw(struct display *disp,
- struct fb_info_aty128 *info, int bpp, int accel)
-{
- switch (bpp) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- disp->dispsw = accel ? &fbcon_aty128_8 : &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 15:
- case 16:
- disp->dispsw = accel ? &fbcon_aty128_16 : &fbcon_cfb16;
- disp->dispsw_data = info->fbcon_cmap.cfb16;
- break;
-#endif
-#ifdef FBCON_HAS_CFB24
- case 24:
- disp->dispsw = accel ? &fbcon_aty128_24 : &fbcon_cfb24;
- disp->dispsw_data = info->fbcon_cmap.cfb24;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- disp->dispsw = accel ? &fbcon_aty128_32 : &fbcon_cfb32;
- disp->dispsw_data = info->fbcon_cmap.cfb32;
- break;
-#endif
- default:
- disp->dispsw = &fbcon_dummy;
- }
-}
-
-
-static void
-aty128_encode_fix(struct fb_fix_screeninfo *fix,
- struct aty128fb_par *par,
- const struct fb_info_aty128 *info)
-{
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-
- strcpy(fix->id, aty128fb_name);
-
- fix->smem_start = (unsigned long)info->frame_buffer_phys;
- fix->mmio_start = (unsigned long)info->regbase_phys;
-
- fix->smem_len = info->vram_size;
- fix->mmio_len = 0x1fff;
-
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- fix->line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
- fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_DIRECTCOLOR;
- fix->ywrapstep = 0;
- fix->xpanstep = 8;
- fix->ypanstep = 1;
-
- fix->accel = FB_ACCEL_ATI_RAGE128;
-
- return;
}
- /*
- * Get the Fixed Part of the Display
- */
+/*
+ * Pan or Wrap the Display
+ */
static int
-aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *fb)
+aty128fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb)
{
- const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- struct aty128fb_par par;
+ struct aty128fb_par *par = fb->par;
+ u32 xoffset, yoffset;
+ u32 offset;
+ u32 xres, yres;
- if (con == -1)
- par = info->default_par;
- else
- aty128_decode_var(&fb_display[con].var, &par, info);
+ xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
+ yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
- aty128_encode_fix(fix, &par, info);
+ xoffset = (var->xoffset +7) & ~7;
+ yoffset = var->yoffset;
- return 0;
-}
+ if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
+ return -EINVAL;
+ par->crtc.xoffset = xoffset;
+ par->crtc.yoffset = yoffset;
- /*
- * Pan or Wrap the Display
- *
- * Not supported (yet!)
- */
-static int
-aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb)
-{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- struct aty128fb_par *par = &info->current_par;
- u32 xoffset, yoffset;
- u32 offset;
- u32 xres, yres;
-
- xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
- yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
-
- xoffset = (var->xoffset +7) & ~7;
- yoffset = var->yoffset;
-
- if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
- return -EINVAL;
+ offset = ((yoffset * par->crtc.vxres + xoffset)*(par->crtc.bpp >> 3)) & ~7;
- par->crtc.xoffset = xoffset;
- par->crtc.yoffset = yoffset;
+ if (par->crtc.bpp == 24)
+ offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */
- offset = ((yoffset * par->crtc.vxres + xoffset) * par->crtc.bpp) >> 6;
+ aty_st_le32(CRTC_OFFSET, offset);
- aty_st_le32(CRTC_OFFSET, offset);
-
- return 0;
+ return 0;
}
- /*
- * Get the Colormap
- */
-
-static int
-aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
+/*
+ * Helper function to store a single palette register
+ */
+static void
+aty128_st_pal(u_int regno, u_int red, u_int green, u_int blue,
+ struct aty128fb_par *par)
{
-#if 1
- fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
-#else
- struct fb_info_aty128 fb = (struct fb_info_aty128 *)info;
-
- if (con == info->currcon) /* current console? */
- return fb_get_cmap(cmap, kspc, aty128_getcolreg, info);
- else 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 <= 8) ? 256 : 32;
- fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
- }
+ if (par->chip_gen == rage_M3) {
+#if 0
+ /* Note: For now, on M3, we set palette on both heads, which may
+ * be useless. Can someone with a M3 check this ?
+ *
+ * This code would still be useful if using the second CRTC to
+ * do mirroring
+ */
+
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
+ aty_st_8(PALETTE_INDEX, regno);
+ aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
#endif
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
+ }
- return 0;
+ aty_st_8(PALETTE_INDEX, regno);
+ aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
}
static int
-aty128fb_rasterimg(struct fb_info *info, int start)
+aty128fb_sync(struct fb_info *info)
{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
+ struct aty128fb_par *par = info->par;
- return 0;
+ if (par->blitter_may_be_busy)
+ wait_for_idle(par);
+ return 0;
}
-
int __init
aty128fb_setup(char *options)
{
- char *this_opt;
+ char *this_opt;
- if (!options || !*options)
- return 0;
+ if (!options || !*options)
+ return 0;
- while ((this_opt = strsep(&options, ",")) != 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;
- } else if (!strncmp(this_opt, "noaccel", 7)) {
- noaccel = 1;
- }
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+#ifdef CONFIG_PMAC_PBOOK
+ if (!strncmp(this_opt, "lcd:", 4)) {
+ default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
+ } else if (!strncmp(this_opt, "crt:", 4)) {
+ default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
+ }
+#endif
#ifdef CONFIG_MTRR
- else if(!strncmp(this_opt, "nomtrr", 6)) {
- mtrr = 0;
- }
+ if(!strncmp(this_opt, "nomtrr", 6)) {
+ mtrr = 0;
+ }
#endif
-#ifdef CONFIG_PPC
- /* vmode and cmode depreciated */
- else if (!strncmp(this_opt, "vmode:", 6)) {
- unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
- if (vmode > 0 && vmode <= VMODE_MAX)
- default_vmode = vmode;
- } else if (!strncmp(this_opt, "cmode:", 6)) {
- unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
- switch (cmode) {
- case 0:
- case 8:
- default_cmode = CMODE_8;
- break;
- case 15:
- case 16:
- default_cmode = CMODE_16;
- break;
- case 24:
- case 32:
- default_cmode = CMODE_32;
- break;
- }
- }
-#endif /* CONFIG_PPC */
- else
- mode_option = this_opt;
- }
- return 0;
+#ifdef CONFIG_ALL_PPC
+ /* vmode and cmode depreciated */
+ if (!strncmp(this_opt, "vmode:", 6)) {
+ unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
+ if (vmode > 0 && vmode <= VMODE_MAX)
+ default_vmode = vmode;
+ } else if (!strncmp(this_opt, "cmode:", 6)) {
+ unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
+ switch (cmode) {
+ case 0:
+ case 8:
+ default_cmode = CMODE_8;
+ break;
+ case 15:
+ case 16:
+ default_cmode = CMODE_16;
+ break;
+ case 24:
+ case 32:
+ default_cmode = CMODE_32;
+ break;
+ }
+ }
+#endif /* CONFIG_ALL_PPC */
+ else
+ mode_option = this_opt;
+ }
+ return 0;
}
- /*
- * Initialisation
- */
+/*
+ * Initialisation
+ */
static int __init
-aty128_init(struct fb_info_aty128 *info, const char *name)
-{
- struct fb_var_screeninfo var;
- u32 dac;
- int j, k, size;
- u8 chip_rev;
- const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
- char *video_card = "Rage128";
-
- if (!info->vram_size) /* may have already been probed */
- info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
-
- /* Get the chip revision */
- chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
-
- /* put a name with the face */
- while (aci->name && info->pdev->device != aci->device) { aci++; }
- video_card = (char *)aci->name;
- info->chip_gen = aci->chip_gen;
-
- printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
-
- if (info->vram_size % (1024 * 1024) == 0)
- printk("%dM %s\n", info->vram_size / (1024*1024), info->mem->name);
- else
- printk("%dk %s\n", info->vram_size / 1024, info->mem->name);
-
- /* fill in info */
- strcpy(info->fb_info.modename, aty128fb_name);
- info->fb_info.node = NODEV;
- info->fb_info.fbops = &aty128fb_ops;
- info->fb_info.disp = &info->disp;
- strcpy(info->fb_info.fontname, fontname);
- info->fb_info.changevar = NULL;
- info->fb_info.switch_con = &aty128fbcon_switch;
- info->fb_info.updatevar = NULL;
- info->fb_info.flags = FBINFO_FLAG_DEFAULT;
-
- var = default_var;
-#ifdef CONFIG_PPC
- if (_machine == _MACH_Pmac) {
- if (mode_option) {
- if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
- var = default_var;
- } else {
- if (default_vmode <= 0 || default_vmode > VMODE_MAX)
- default_vmode = VMODE_1024_768_60;
-
- /* iMacs need that resolution
- * PowerMac2,1 first r128 iMacs
- * PowerMac2,2 summer 2000 iMacs
- * PowerMac4,1 january 2001 iMacs "flower power"
- */
- if (machine_is_compatible("PowerMac2,1") ||
- machine_is_compatible("PowerMac2,2") ||
- machine_is_compatible("PowerMac4,1"))
- default_vmode = VMODE_1024_768_75;
-
- /* iBook SE */
- if (machine_is_compatible("PowerBook2,2"))
- default_vmode = VMODE_800_600_60;
-
- /* PowerBook Firewire (Pismo), iBook Dual USB */
- if (machine_is_compatible("PowerBook3,1") ||
- machine_is_compatible("PowerBook4,1"))
- default_vmode = VMODE_1024_768_60;
-
- /* PowerBook Titanium */
- if (machine_is_compatible("PowerBook3,2"))
- default_vmode = VMODE_1152_768_60;
-
- 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
-#endif /* CONFIG_PPC */
- {
- if (fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0,
- &defaultmode, 8) == 0)
- var = default_var;
- }
-
- if (noaccel)
- var.accel_flags &= ~FB_ACCELF_TEXT;
- else
- var.accel_flags |= FB_ACCELF_TEXT;
-
- if (aty128_decode_var(&var, &info->default_par, info)) {
- printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
- return 0;
- }
+aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct fb_info *info = pci_get_drvdata(pdev);
+ struct aty128fb_par *par = info->par;
+ struct fb_var_screeninfo var;
+ char video_card[25];
+ u8 chip_rev;
+ u32 dac;
+
+ if (!par->vram_size) /* may have already been probed */
+ par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+
+ /* Get the chip revision */
+ chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
+
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_ATI_RAGE128_RE:
+ strcpy(video_card, "Rage128 RE (PCI)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_RF:
+ strcpy(video_card, "Rage128 RF (AGP)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_RK:
+ strcpy(video_card, "Rage128 RK (PCI)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_RL:
+ strcpy(video_card, "Rage128 RL (AGP)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_PF:
+ strcpy(video_card, "Rage128 Pro PF (AGP)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_PR:
+ strcpy(video_card, "Rage128 Pro PR (PCI)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_U3:
+ strcpy(video_card, "Rage128 Pro TR (AGP)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_U1:
+ strcpy(video_card, "Rage128 Pro TF (AGP)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_LE:
+ strcpy(video_card, "Rage Mobility M3 (PCI)");
+ break;
+ case PCI_DEVICE_ID_ATI_RAGE128_LF:
+ strcpy(video_card, "Rage Mobility M3 (AGP)");
+ break;
+ default:
+ return -ENODEV;
+ }
- /* load up the palette with default colors */
- 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];
- }
+ printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
- /* setup the DAC the way we like it */
- dac = aty_ld_le32(DAC_CNTL);
- dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
- dac |= DAC_MASK;
- aty_st_le32(DAC_CNTL, dac);
+ if (par->vram_size % (1024 * 1024) == 0)
+ printk("%dM %s\n", par->vram_size / (1024*1024), par->mem->name);
+ else
+ printk("%dk %s\n", par->vram_size / 1024, par->mem->name);
- /* turn off bus mastering, just in case */
- aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
+ par->chip_gen = ent->driver_data;
- aty128fb_set_var(&var, -1, &info->fb_info);
- aty128_init_engine(&info->default_par, info);
+ /* fill in info */
+ info->node = NODEV;
+ info->fbops = &aty128fb_ops;
+ info->flags = FBINFO_FLAG_DEFAULT;
- board_list = aty128_board_list_add(board_list, info);
+#ifdef CONFIG_PMAC_PBOOK
+ par->lcd_on = default_lcd_on;
+ par->crt_on = default_crt_on;
+#endif
- size = (var.bits_per_pixel <= 8) ? 256 : 32;
- fb_alloc_cmap(&info->fb_info.cmap, size, 0);
+ var = default_var;
+#ifdef CONFIG_ALL_PPC
+ if (_machine == _MACH_Pmac) {
+ if (mode_option) {
+ if (!mac_find_mode(&var, info, mode_option, 8))
+ var = default_var;
+ } else {
+ if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+ default_vmode = VMODE_1024_768_60;
+
+ /* iMacs need that resolution
+ * PowerMac2,1 first r128 iMacs
+ * PowerMac2,2 summer 2000 iMacs
+ * PowerMac4,1 january 2001 iMacs "flower power"
+ */
+ if (machine_is_compatible("PowerMac2,1") ||
+ machine_is_compatible("PowerMac2,2") ||
+ machine_is_compatible("PowerMac4,1"))
+ default_vmode = VMODE_1024_768_75;
+
+ /* iBook SE */
+ if (machine_is_compatible("PowerBook2,2"))
+ default_vmode = VMODE_800_600_60;
+
+ /* PowerBook Firewire (Pismo), iBook Dual USB */
+ if (machine_is_compatible("PowerBook3,1") ||
+ machine_is_compatible("PowerBook4,1"))
+ default_vmode = VMODE_1024_768_60;
+
+ /* PowerBook Titanium */
+ if (machine_is_compatible("PowerBook3,2"))
+ default_vmode = VMODE_1152_768_60;
+
+ if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
+ default_cmode = CMODE_8;
- if (register_framebuffer(&info->fb_info) < 0)
- return 0;
+ if (mac_vmode_to_var(default_vmode, default_cmode, &var))
+ var = default_var;
+ }
+ } else
+#endif /* CONFIG_ALL_PPC */
+ {
+ if (fb_find_mode(&var, info, mode_option, NULL, 0,
+ &defaultmode, 8) == 0)
+ var = default_var;
+ }
-#ifdef CONFIG_PMAC_BACKLIGHT
- /* Could be extended to Rage128Pro LVDS output too */
- if (info->chip_gen == rage_M3)
- register_backlight_controller(&aty128_backlight_controller, info, "ati");
-#endif /* CONFIG_PMAC_BACKLIGHT */
+ var.accel_flags &= ~FB_ACCELF_TEXT;
+// var.accel_flags |= FB_ACCELF_TEXT;/* FIXME Will add accel later */
- printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
- GET_FB_IDX(info->fb_info.node), aty128fb_name, name);
+ if (aty128fb_check_var(&var, info)) {
+ printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
+ return 0;
+ }
- return 1; /* success! */
-}
+ /* setup the DAC the way we like it */
+ dac = aty_ld_le32(DAC_CNTL);
+ dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
+ dac |= DAC_MASK;
+ if (par->chip_gen == rage_M3)
+ dac |= DAC_PALETTE2_SNOOP_EN;
+ aty_st_le32(DAC_CNTL, dac);
+ /* turn off bus mastering, just in case */
+ aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
-/* add a new card to the list ++ajoshi */
-static struct
-fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128 *board_list,
- struct fb_info_aty128 *new_node)
-{
- struct fb_info_aty128 *i_p = board_list;
+ info->var = var;
+ fb_alloc_cmap(&info->cmap, 256, 0);
- new_node->next = NULL;
- if(board_list == NULL)
- return new_node;
- while(i_p->next != NULL)
- i_p = i_p->next;
- i_p->next = new_node;
+ var.activate = FB_ACTIVATE_NOW;
- return board_list;
-}
+ aty128_init_engine(par);
+ if (register_framebuffer(info) < 0)
+ return 0;
-int __init
-aty128fb_init(void)
-{
-#ifdef CONFIG_PCI
- struct pci_dev *pdev = NULL;
- const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
-
- while (aci->name != NULL) {
- pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
- while (pdev != NULL) {
- if (aty128_pci_register(pdev, aci) == 0)
- return 0;
- pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
- }
- aci++;
- }
+#ifdef CONFIG_PMAC_BACKLIGHT
+ /* Could be extended to Rage128Pro LVDS output too */
+ if (par->chip_gen == rage_M3)
+ register_backlight_controller(&aty128_backlight_controller, par, "ati");
+#endif /* CONFIG_PMAC_BACKLIGHT */
+#ifdef CONFIG_PMAC_PBOOK
+ par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ pmu_register_sleep_notifier(&aty128_sleep_notifier);
#endif
- return 0;
-}
+ printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
+ minor(info->node), info->fix.id, video_card);
+ return 1; /* success! */
+}
#ifdef CONFIG_PCI
/* register a card ++ajoshi */
static int __init
-aty128_pci_register(struct pci_dev *pdev,
- const struct aty128_chip_info *aci)
+aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- struct fb_info_aty128 *info = NULL;
unsigned long fb_addr, reg_addr;
- int err;
+ struct aty128fb_par *par;
+ struct fb_info *info;
+ int err, size;
#if !defined(CONFIG_PPC) && !defined(__sparc__)
char *bios_seg = NULL;
#endif
@@ -1824,7 +1628,7 @@ aty128_pci_register(struct pci_dev *pdev,
if ((err = pci_enable_device(pdev))) {
printk(KERN_ERR "aty128fb: Cannot enable PCI device: %d\n",
err);
- goto err_out;
+ return -ENODEV;
}
fb_addr = pci_resource_start(pdev, 0);
@@ -1843,62 +1647,71 @@ aty128_pci_register(struct pci_dev *pdev,
}
/* We have the resources. Now virtualize them */
- if (!(info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC))) {
+ size = sizeof(struct fb_info) + sizeof(struct aty128fb_par) +
+ sizeof(u32)*16;
+ if (!(info = kmalloc(size, GFP_ATOMIC))) {
printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
goto err_unmap_out;
}
- memset(info, 0, sizeof(struct fb_info_aty128));
+ memset(info, 0, size);
- /* Copy PCI device info into info->pdev */
- info->pdev = pdev;
+ par = (struct aty128fb_par *)(info + 1);
+ info->pseudo_palette = (void *) (par + 1);
- info->fb_info.currcon = -1;
+ memset(info, 0, sizeof(struct fb_info));
- /* Virtualize mmio region */
- info->regbase_phys = reg_addr;
- info->regbase = ioremap(reg_addr, 0x1FFF);
+ info->par = par;
+ info->fix = aty128fb_fix;
- if (!info->regbase)
+ /* Virtualize mmio region */
+ info->fix.mmio_start = reg_addr;
+ par->regbase = ioremap(reg_addr, 0x2000);
+ if (!par->regbase)
goto err_free_info;
/* Grab memory size from the card */
- info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+ par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
/* Virtualize the framebuffer */
- info->frame_buffer_phys = fb_addr;
- info->frame_buffer = ioremap(fb_addr, info->vram_size);
-
- if (!info->frame_buffer) {
- iounmap((void *)info->regbase);
+ info->screen_base = ioremap(fb_addr, par->vram_size);
+ if (!info->screen_base) {
+ iounmap(par->regbase);
goto err_free_info;
}
+ /* Set up info->fix */
+ info->fix = aty128fb_fix;
+ info->fix.smem_start = fb_addr;
+ info->fix.smem_len = par->vram_size;
+ info->fix.mmio_start = reg_addr;
+
/* If we can't test scratch registers, something is seriously wrong */
- if (!register_test(info)) {
+ if (!register_test(par)) {
printk(KERN_ERR "aty128fb: Can't write to video register!\n");
goto err_out;
}
#if !defined(CONFIG_PPC) && !defined(__sparc__)
- if (!(bios_seg = aty128find_ROM(info)))
+ if (!(bios_seg = aty128find_ROM()))
printk(KERN_INFO "aty128fb: Rage128 BIOS not located. "
"Guessing...\n");
else {
printk(KERN_INFO "aty128fb: Rage128 BIOS located at "
"segment %4.4X\n", (unsigned int)bios_seg);
- aty128_get_pllinfo(info, bios_seg);
+ aty128_get_pllinfo(par, bios_seg);
}
#endif
- aty128_timings(info);
+ aty128_timings(par);
+ pci_set_drvdata(pdev, info);
- if (!aty128_init(info, "PCI"))
+ if (!aty128_init(pdev, ent))
goto err_out;
#ifdef CONFIG_MTRR
if (mtrr) {
- info->mtrr.vram = mtrr_add(info->frame_buffer_phys,
- info->vram_size, MTRR_TYPE_WRCOMB, 1);
- info->mtrr.vram_valid = 1;
+ par->mtrr.vram = mtrr_add(info->fix.smem_start,
+ par->vram_size, MTRR_TYPE_WRCOMB, 1);
+ par->mtrr.vram_valid = 1;
/* let there be speed */
printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
}
@@ -1906,8 +1719,8 @@ aty128_pci_register(struct pci_dev *pdev,
return 0;
err_out:
- iounmap(info->frame_buffer);
- iounmap(info->regbase);
+ iounmap(info->screen_base);
+ iounmap(par->regbase);
err_free_info:
kfree(info);
err_unmap_out:
@@ -1921,21 +1734,48 @@ err_free_fb:
pci_resource_len(pdev, 1));
return -ENODEV;
}
-#endif /* CONFIG_PCI */
+static void __devexit aty128_remove(struct pci_dev *pdev)
+{
+ struct fb_info *info = pci_get_drvdata(pdev);
+ struct aty128fb_par *par = info->par;
+
+ if (!info)
+ return;
+
+ unregister_framebuffer(info);
+#ifdef CONFIG_MTRR
+ if (par->mtrr.vram_valid)
+ mtrr_del(par->mtrr.vram, info->fix.smem_start,
+ par->vram_size);
+#endif /* CONFIG_MTRR */
+ iounmap(par->regbase);
+ iounmap(info->screen_base);
+
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ release_mem_region(pci_resource_start(pdev, 1),
+ pci_resource_len(pdev, 1));
+ release_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ kfree(info);
+}
+#endif /* CONFIG_PCI */
/* PPC and Sparc cannot read video ROM */
#if !defined(CONFIG_PPC) && !defined(__sparc__)
-static char __init
-*aty128find_ROM(struct fb_info_aty128 *info)
+static char * __init aty128find_ROM(void)
{
u32 segstart;
char *rom_base;
char *rom;
int stage;
- int i;
+ int i, j;
char aty_rom_sig[] = "761295520"; /* ATI ROM Signature */
- char R128_sig[] = "R128"; /* Rage128 ROM identifier */
+ char *R128_sig[] = {
+ "R128", /* Rage128 ROM identifier */
+ "128b"
+ };
for (segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
stage = 1;
@@ -1966,26 +1806,28 @@ static char __init
/* ATI signature found. Let's see if it's a Rage128 */
for (i = 0; (i < 512) && (stage != 4); i++) {
- if (R128_sig[0] == *rom)
- if (strncmp(R128_sig, rom,
- strlen(R128_sig)) == 0)
- stage = 4;
+ for (j = 0; j < sizeof(R128_sig)/sizeof(char *);j++) {
+ if (R128_sig[j][0] == *rom)
+ if (strncmp(R128_sig[j], rom,
+ strlen(R128_sig[j])) == 0) {
+ stage = 4;
+ break;
+ }
+ }
rom++;
}
if (stage != 4) {
iounmap(rom_base);
continue;
}
-
return rom_base;
}
-
return NULL;
}
static void __init
-aty128_get_pllinfo(struct fb_info_aty128 *info, char *bios_seg)
+aty128_get_pllinfo(struct aty128fb_par *par, char *bios_seg)
{
void *bios_header;
void *header_ptr;
@@ -2005,16 +1847,16 @@ aty128_get_pllinfo(struct fb_info_aty128 *info, char *bios_seg)
memcpy_fromio(&pll, header_ptr, 50);
- info->constants.ppll_max = pll.PCLK_max_freq;
- info->constants.ppll_min = pll.PCLK_min_freq;
- info->constants.xclk = (u32)pll.XCLK;
- info->constants.ref_divider = (u32)pll.PCLK_ref_divider;
- info->constants.dotclock = (u32)pll.PCLK_ref_freq;
+ par->constants.ppll_max = pll.PCLK_max_freq;
+ par->constants.ppll_min = pll.PCLK_min_freq;
+ par->constants.xclk = (u32)pll.XCLK;
+ par->constants.ref_divider = (u32)pll.PCLK_ref_divider;
+ par->constants.dotclock = (u32)pll.PCLK_ref_freq;
DBG("ppll_max %d ppll_min %d xclk %d ref_divider %d dotclock %d\n",
- info->constants.ppll_max, info->constants.ppll_min,
- info->constants.xclk, info->constants.ref_divider,
- info->constants.dotclock);
+ par->constants.ppll_max, par->constants.ppll_min,
+ par->constants.xclk, par->constants.ref_divider,
+ par->constants.dotclock);
}
#endif /* !CONFIG_PPC */
@@ -2022,244 +1864,212 @@ aty128_get_pllinfo(struct fb_info_aty128 *info, char *bios_seg)
/* fill in known card constants if pll_block is not available */
static void __init
-aty128_timings(struct fb_info_aty128 *info)
+aty128_timings(struct aty128fb_par *par)
{
-#ifdef CONFIG_PPC
- /* instead of a table lookup, assume OF has properly
- * setup the PLL registers and use their values
- * to set the XCLK values and reference divider values */
-
- u32 x_mpll_ref_fb_div;
- u32 xclk_cntl;
- u32 Nx, M;
- unsigned PostDivSet[] =
- { 0, 1, 2, 4, 8, 3, 6, 12 };
-#endif
-
- if (!info->constants.dotclock)
- info->constants.dotclock = 2950;
+#ifdef CONFIG_ALL_PPC
+ /* instead of a table lookup, assume OF has properly
+ * setup the PLL registers and use their values
+ * to set the XCLK values and reference divider values */
-#ifdef CONFIG_PPC
- x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
- xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
- Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
- M = x_mpll_ref_fb_div & 0x0000ff;
-
- info->constants.xclk = round_div((2 * Nx *
- info->constants.dotclock), (M * PostDivSet[xclk_cntl]));
-
- info->constants.ref_divider =
- aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
+ u32 x_mpll_ref_fb_div;
+ u32 xclk_cntl;
+ u32 Nx, M;
+ unsigned PostDivSet[] = { 0, 1, 2, 4, 8, 3, 6, 12 };
#endif
- if (!info->constants.ref_divider) {
- info->constants.ref_divider = 0x3b;
-
- aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
- aty_pll_writeupdate(info);
- }
- aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider);
- aty_pll_writeupdate(info);
-
- /* from documentation */
- if (!info->constants.ppll_min)
- info->constants.ppll_min = 12500;
- if (!info->constants.ppll_max)
- info->constants.ppll_max = 25000; /* 23000 on some cards? */
- if (!info->constants.xclk)
- info->constants.xclk = 0x1d4d; /* same as mclk */
-
- info->constants.fifo_width = 128;
- info->constants.fifo_depth = 32;
-
- switch (aty_ld_le32(MEM_CNTL) & 0x3) {
- case 0:
- info->mem = &sdr_128;
- break;
- case 1:
- info->mem = &sdr_sgram;
- break;
- case 2:
- info->mem = &ddr_sgram;
- break;
- default:
- info->mem = &sdr_sgram;
- }
-}
-
+ if (!par->constants.dotclock)
+ par->constants.dotclock = 2950;
-static int
-aty128fbcon_switch(int con, struct fb_info *fb)
-{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- struct aty128fb_par par;
-
- /* Do we have to save the colormap? */
- if (fb_display[fb->currcon].cmap.len)
- fb_get_cmap(&fb_display[fb->currcon].cmap, 1,
- aty128_getcolreg, fb);
-
- /* set the current console */
- fb->currcon = con;
+#ifdef CONFIG_ALL_PPC
+ x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
+ xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
+ Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
+ M = x_mpll_ref_fb_div & 0x0000ff;
- aty128_decode_var(&fb_display[con].var, &par, info);
- aty128_set_par(&par, info);
+ par->constants.xclk = round_div((2 * Nx * par->constants.dotclock),
+ (M * PostDivSet[xclk_cntl]));
- aty128_set_dispsw(&fb_display[con], info, par.crtc.bpp,
- par.accel_flags & FB_ACCELF_TEXT);
+ par->constants.ref_divider =
+ aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
+#endif
- do_install_cmap(con, fb);
+ if (!par->constants.ref_divider) {
+ par->constants.ref_divider = 0x3b;
- return 1;
+ aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
+ aty_pll_writeupdate(par);
+ }
+ aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider);
+ aty_pll_writeupdate(par);
+
+ /* from documentation */
+ if (!par->constants.ppll_min)
+ par->constants.ppll_min = 12500;
+ if (!par->constants.ppll_max)
+ par->constants.ppll_max = 25000; /* 23000 on some cards? */
+ if (!par->constants.xclk)
+ par->constants.xclk = 0x1d4d; /* same as mclk */
+
+ par->constants.fifo_width = 128;
+ par->constants.fifo_depth = 32;
+
+ switch (aty_ld_le32(MEM_CNTL) & 0x3) {
+ case 0:
+ par->mem = &sdr_128;
+ break;
+ case 1:
+ par->mem = &sdr_sgram;
+ break;
+ case 2:
+ par->mem = &ddr_sgram;
+ break;
+ default:
+ par->mem = &sdr_sgram;
+ }
}
/*
* Blank the display.
*/
-static int
+static int
aty128fb_blank(int blank, struct fb_info *fb)
{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- u8 state = 0;
+ struct aty128fb_par *par = fb->par;
+ u8 state = 0;
#ifdef CONFIG_PMAC_BACKLIGHT
- if ((_machine == _MACH_Pmac) && blank)
- set_backlight_enable(0);
+ if ((_machine == _MACH_Pmac) && blank)
+ set_backlight_enable(0);
#endif /* CONFIG_PMAC_BACKLIGHT */
- if (blank & VESA_VSYNC_SUSPEND)
- state |= 2;
- if (blank & VESA_HSYNC_SUSPEND)
- state |= 1;
- if (blank & VESA_POWERDOWN)
- state |= 4;
+ if (blank & VESA_VSYNC_SUSPEND)
+ state |= 2;
+ if (blank & VESA_HSYNC_SUSPEND)
+ state |= 1;
+ if (blank & VESA_POWERDOWN)
+ state |= 4;
- aty_st_8(CRTC_EXT_CNTL+1, state);
+ aty_st_8(CRTC_EXT_CNTL+1, state);
+#ifdef CONFIG_PMAC_PBOOK
+ if (par->chip_gen == rage_M3) {
+ aty128_set_crt_enable(par, par->crt_on && !blank);
+ aty128_set_lcd_enable(par, par->lcd_on && !blank);
+ }
+#endif
#ifdef CONFIG_PMAC_BACKLIGHT
- if ((_machine == _MACH_Pmac) && !blank)
- set_backlight_enable(1);
+ if ((_machine == _MACH_Pmac) && !blank)
+ set_backlight_enable(1);
#endif /* CONFIG_PMAC_BACKLIGHT */
- return 0;
-}
-
- /*
- * Read a single color register and split it into
- * colors/transparent. Return != 0 for invalid regno.
- */
-static int
-aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *fb)
-{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *) fb;
-
- if (regno > 255)
- return 1;
-
- *red = (info->palette[regno].red<<8) | info->palette[regno].red;
- *green = (info->palette[regno].green<<8) | info->palette[regno].green;
- *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
- *transp = 0;
-
- return 0;
+ 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.
- */
+/*
+ * 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
aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *fb)
-{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- u32 col;
-
- if (regno > 255)
- return 1;
-
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- info->palette[regno].red = red;
- info->palette[regno].green = green;
- info->palette[regno].blue = blue;
-
- /* Note: For now, on M3, we set palette on both heads, which may
- * be useless. Can someone with a M3 check this ? */
-
- /* initialize gamma ramp for hi-color+ */
-
- if ((info->current_par.crtc.bpp > 8) && (regno == 0)) {
- int i;
-
- if (info->chip_gen == rage_M3)
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
+ u_int transp, struct fb_info *info)
+{
+ struct aty128fb_par *par = info->par;
+
+ if (regno > 255
+ || (par->crtc.depth == 16 && regno > 63)
+ || (par->crtc.depth == 15 && regno > 31))
+ return 1;
+
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ if (regno < 16) {
+ int i;
+ switch (par->crtc.depth) {
+ case 15:
+ ((u16 *) (info->pseudo_palette))[regno] =
+ (regno << 10) | (regno << 5) | regno;
+ break;
+ case 16:
+ ((u16 *) (info->pseudo_palette))[regno] =
+ (regno << 11) | (regno << 6) | regno;
+ break;
+ case 24:
+ ((u32 *) (info->pseudo_palette))[regno] =
+ (regno << 16) | (regno << 8) | regno;
+ break;
+ case 32:
+ i = (regno << 8) | regno;
+ ((u32 *) (info->pseudo_palette))[regno] =
+ (i << 16) | i;
+ break;
+ }
+ }
- for (i=16; i<256; i++) {
- aty_st_8(PALETTE_INDEX, i);
- col = (i << 16) | (i << 8) | i;
- aty_st_le32(PALETTE_DATA, col);
- }
+ if (par->crtc.depth == 16) {
+ /*
+ * With the 5-6-5 split of bits for RGB at 16 bits/pixel, we
+ * have 32 slots for R and B values but 64 slots for G values.
+ * Thus the R and B values go in one slot but the G value
+ * goes in a different slot, and we have to avoid disturbing
+ * the other fields in the slots we touch.
+ */
+ par->red[regno] = red;
+ par->green[regno] = green;
+ par->blue[regno] = blue;
+ if (regno > 0 && regno < 32)
+ aty128_st_pal(regno * 8, red, par->green[regno*2],
+ blue, par);
+ red = par->red[regno/2];
+ blue = par->blue[regno/2];
+ regno <<= 2;
+ } else if (par->crtc.bpp == 16)
+ regno <<= 3;
+ aty128_st_pal(regno, red, green, blue, par);
- if (info->chip_gen == rage_M3) {
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
+ return 0;
+}
- for (i=16; i<256; i++) {
- aty_st_8(PALETTE_INDEX, i);
- col = (i << 16) | (i << 8) | i;
- aty_st_le32(PALETTE_DATA, col);
- }
- }
- }
+#define ATY_MIRROR_LCD_ON 0x00000001
+#define ATY_MIRROR_CRT_ON 0x00000002
- /* initialize palette */
-
- if (info->chip_gen == rage_M3)
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
-
- if (info->current_par.crtc.bpp == 16)
- aty_st_8(PALETTE_INDEX, (regno << 3));
- else
- aty_st_8(PALETTE_INDEX, regno);
- col = (red << 16) | (green << 8) | blue;
- aty_st_le32(PALETTE_DATA, col);
- if (info->chip_gen == rage_M3) {
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
- if (info->current_par.crtc.bpp == 16)
- aty_st_8(PALETTE_INDEX, (regno << 3));
- else
- aty_st_8(PALETTE_INDEX, regno);
- aty_st_le32(PALETTE_DATA, col);
- }
+/* out param: u32* backlight value: 0 to 15 */
+#define FBIO_ATY128_GET_MIRROR _IOR('@', 1, sizeof(__u32*))
+/* in param: u32* backlight value: 0 to 15 */
+#define FBIO_ATY128_SET_MIRROR _IOW('@', 2, sizeof(__u32*))
- if (regno < 16)
- switch (info->current_par.crtc.bpp) {
-#ifdef FBCON_HAS_CFB16
- case 9 ... 16:
- info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
- regno;
- break;
-#endif
-#ifdef FBCON_HAS_CFB24
- case 17 ... 24:
- info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
- regno;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 25 ... 32: {
- u32 i;
-
- i = (regno << 8) | regno;
- info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
- break;
- }
-#endif
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, struct fb_info *info)
+{
+#ifdef CONFIG_PMAC_PBOOK
+ struct aty128fb_par *par = info->par;
+ u32 value;
+ int rc;
+
+ switch (cmd) {
+ case FBIO_ATY128_SET_MIRROR:
+ if (par->chip_gen != rage_M3)
+ return -EINVAL;
+ rc = get_user(value, (__u32*)arg);
+ if (rc)
+ return rc;
+ par->lcd_on = (value & 0x01) != 0;
+ par->crt_on = (value & 0x02) != 0;
+ if (!par->crt_on && !par->lcd_on)
+ par->lcd_on = 1;
+ aty128_set_crt_enable(par, par->crt_on);
+ aty128_set_lcd_enable(par, par->lcd_on);
+ return 0;
+ case FBIO_ATY128_GET_MIRROR:
+ if (par->chip_gen != rage_M3)
+ return -EINVAL;
+ value = (par->crt_on << 1) | par->lcd_on;
+ return put_user(value, (__u32*)arg);
}
- return 0;
+#endif
+ return -EINVAL;
}
#ifdef CONFIG_PMAC_BACKLIGHT
@@ -2268,21 +2078,58 @@ static int backlight_conv[] = {
0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
};
+/* We turn off the LCD completely instead of just dimming the backlight.
+ * This provides greater power saving and the display is useless without
+ * backlight anyway
+ */
+#define BACKLIGHT_LVDS_OFF
+/* That one prevents proper CRT output with LCD off */
+#undef BACKLIGHT_DAC_OFF
+
static int
-aty128_set_backlight_enable(int on, int level, void* data)
+aty128_set_backlight_enable(int on, int level, void *data)
{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *)data;
+ struct aty128fb_par *par = data;
unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
-
+
+ if (!par->lcd_on)
+ on = 0;
reg |= LVDS_BL_MOD_EN | LVDS_BLON;
if (on && level > BACKLIGHT_OFF) {
+ reg |= LVDS_DIGION;
+ if (!reg & LVDS_ON) {
+ reg &= ~LVDS_BLON;
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+ (void)aty_ld_le32(LVDS_GEN_CNTL);
+ mdelay(10);
+ reg |= LVDS_BLON;
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+ }
reg &= ~LVDS_BL_MOD_LEVEL_MASK;
reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);
+#ifdef BACKLIGHT_LVDS_OFF
+ reg |= LVDS_ON | LVDS_EN;
+ reg &= ~LVDS_DISPLAY_DIS;
+#endif
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef BACKLIGHT_DAC_OFF
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));
+#endif
} else {
reg &= ~LVDS_BL_MOD_LEVEL_MASK;
reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);
+#ifdef BACKLIGHT_LVDS_OFF
+ reg |= LVDS_DISPLAY_DIS;
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+ (void)aty_ld_le32(LVDS_GEN_CNTL);
+ udelay(10);
+ reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);
+#endif
+ aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef BACKLIGHT_DAC_OFF
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);
+#endif
}
- aty_st_le32(LVDS_GEN_CNTL, reg);
return 0;
}
@@ -2294,6 +2141,7 @@ aty128_set_backlight_level(int level, void* data)
}
#endif /* CONFIG_PMAC_BACKLIGHT */
+#if 0
/*
* Accelerated functions
*/
@@ -2301,39 +2149,39 @@ aty128_set_backlight_level(int level, void* data)
static inline void
aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
u_int width, u_int height,
- struct fb_info_aty128 *info)
+ struct fb_info_aty128 *par)
{
- u32 save_dp_datatype, save_dp_cntl, bppval;
+ u32 save_dp_datatype, save_dp_cntl, dstval;
if (!width || !height)
return;
- bppval = bpp_to_depth(info->current_par.crtc.bpp);
- if (bppval == DST_24BPP) {
+ dstval = depth_to_dst(par->current_par.crtc.depth);
+ if (dstval == DST_24BPP) {
srcx *= 3;
dstx *= 3;
width *= 3;
- } else if (bppval == -EINVAL) {
- printk("aty128fb: invalid depth\n");
+ } else if (dstval == -EINVAL) {
+ printk("aty128fb: invalid depth or RGBA\n");
return;
}
- wait_for_fifo(2, info);
+ wait_for_fifo(2, par);
save_dp_datatype = aty_ld_le32(DP_DATATYPE);
save_dp_cntl = aty_ld_le32(DP_CNTL);
- wait_for_fifo(6, info);
+ wait_for_fifo(6, par);
aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);
aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);
aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
- aty_st_le32(DP_DATATYPE, save_dp_datatype | bppval | SRC_DSTCOLOR);
+ aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR);
aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
- info->blitter_may_be_busy = 1;
+ par->blitter_may_be_busy = 1;
- wait_for_fifo(2, info);
+ wait_for_fifo(2, par);
aty_st_le32(DP_DATATYPE, save_dp_datatype);
aty_st_le32(DP_CNTL, save_dp_cntl);
}
@@ -2357,209 +2205,129 @@ fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx,
aty128_rectcopy(sx, sy, dx, dy, width, height,
(struct fb_info_aty128 *)p->fb_info);
}
+#endif /* 0 */
-
-#ifdef FBCON_HAS_CFB8
-static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
- int c, int yy, int xx)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb8_putc(conp, p, c, yy, xx);
-}
-
-
-static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count,
- int yy, int xx)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
-}
-
-
-static void fbcon_aty8_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb8_clear_margins(conp, p, bottom_only);
-}
-
-static struct display_switch fbcon_aty128_8 = {
- setup: fbcon_cfb8_setup,
- bmove: fbcon_aty128_bmove,
- clear: fbcon_cfb8_clear,
- putc: fbcon_aty8_putc,
- putcs: fbcon_aty8_putcs,
- revc: fbcon_cfb8_revc,
- clear_margins: fbcon_aty8_clear_margins,
- fontwidthmask: 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)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb16_putc(conp, p, c, yy, xx);
-}
-
-
-static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count,
- int yy, int xx)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
-}
-
-
-static void fbcon_aty16_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb16_clear_margins(conp, p, bottom_only);
-}
-
-static struct display_switch fbcon_aty128_16 = {
- setup: fbcon_cfb16_setup,
- bmove: fbcon_aty128_bmove,
- clear: fbcon_cfb16_clear,
- putc: fbcon_aty16_putc,
- putcs: fbcon_aty16_putcs,
- revc: fbcon_cfb16_revc,
- clear_margins: fbcon_aty16_clear_margins,
- fontwidthmask: 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)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- 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)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
+#ifdef CONFIG_PMAC_PBOOK
+static void
+aty128_set_suspend(struct aty128fb_par *par, int suspend)
+{
+ u32 pmgt;
+ u16 pwr_command;
+
+ if (!par->pm_reg)
+ return;
+
+ /* Set the chip into the appropriate suspend mode (we use D2,
+ * D3 would require a complete re-initialisation of the chip,
+ * including PCI config registers, clocks, AGP configuration, ...)
+ */
+ if (suspend) {
+ /* Make sure CRTC2 is reset. Remove that the day we decide to
+ * actually use CRTC2 and replace it with real code for disabling
+ * the CRTC2 output during sleep
+ */
+ aty_st_le32(CRTC2_GEN_CNTL, aty_ld_le32(CRTC2_GEN_CNTL) &
+ ~(CRTC2_EN));
+
+ /* Set the power management mode to be PCI based */
+ /* Use this magic value for now */
+ pmgt = 0x0c005407;
+ aty_st_pll(POWER_MANAGEMENT, pmgt);
+ (void)aty_ld_pll(POWER_MANAGEMENT);
+ aty_st_le32(BUS_CNTL1, 0x00000010);
+ aty_st_le32(MEM_POWER_MISC, 0x0c830000);
+ mdelay(100);
+ pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+ /* Switch PCI power management to D2 */
+ pci_write_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL,
+ (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
+ pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+ } else {
+ /* Switch back PCI power management to D0 */
+ mdelay(100);
+ pci_write_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, 0);
+ mdelay(100);
+ pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+ mdelay(100);
+ }
}
-
-static void fbcon_aty24_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only)
+/*
+ * Save the contents of the frame buffer when we go to sleep,
+ * and restore it when we wake up again.
+ */
+int
+aty128_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb24_clear_margins(conp, p, bottom_only);
-}
+ int result = PBOOK_SLEEP_OK, nb;
+ struct fb_info *info = info; /* FIXME!!! How do find which framebuffer */
+ struct aty128fb_par *par = info->par;
-static struct display_switch fbcon_aty128_24 = {
- setup: fbcon_cfb24_setup,
- bmove: fbcon_aty128_bmove,
- clear: fbcon_cfb24_clear,
- putc: fbcon_aty24_putc,
- putcs: fbcon_aty24_putcs,
- revc: fbcon_cfb24_revc,
- clear_margins: fbcon_aty24_clear_margins,
- fontwidthmask: 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)
-{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+ nb = info->var.yres * info->fix.line_length;
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
+ switch (when) {
+ case PBOOK_SLEEP_REQUEST:
+ par->save_framebuffer = vmalloc(nb);
+ if (par->save_framebuffer == NULL)
+ return PBOOK_SLEEP_REFUSE;
+ break;
+ case PBOOK_SLEEP_REJECT:
+ if (par->save_framebuffer) {
+ vfree(par->save_framebuffer);
+ par->save_framebuffer = 0;
+ }
+ break;
+ case PBOOK_SLEEP_NOW:
+ wait_for_idle(par);
+ aty128_reset_engine(par);
+ wait_for_idle(par);
+
+ /* Backup fb content */
+ if (par->save_framebuffer)
+ memcpy_fromio(par->save_framebuffer,
+ info->screen_base, nb);
+
+ /* Blank display and LCD */
+ aty128fb_blank(VESA_POWERDOWN, info);
+
+ /* Sleep the chip */
+ aty128_set_suspend(par, 1);
- fbcon_cfb32_putc(conp, p, c, yy, xx);
+ break;
+ case PBOOK_WAKE:
+ /* Wake the chip */
+ aty128_set_suspend(par, 0);
+
+ aty128_reset_engine(par);
+ wait_for_idle(par);
+
+ /* Restore fb content */
+ if (par->save_framebuffer) {
+ memcpy_toio(info->screen_base,
+ par->save_framebuffer, nb);
+ vfree(par->save_framebuffer);
+ par->save_framebuffer = 0;
+ }
+ aty128fb_blank(0, info);
+ break;
+ }
+ return result;
}
+#endif /* CONFIG_PMAC_PBOOK */
-
-static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count,
- int yy, int xx)
+int __init aty128fb_init(void)
{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
+ return pci_module_init(&aty128fb_driver);
}
-
-static void fbcon_aty32_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only)
+static void __exit aty128fb_exit(void)
{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb32_clear_margins(conp, p, bottom_only);
+ pci_unregister_driver(&aty128fb_driver);
}
-static struct display_switch fbcon_aty128_32 = {
- setup: fbcon_cfb32_setup,
- bmove: fbcon_aty128_bmove,
- clear: fbcon_cfb32_clear,
- putc: fbcon_aty32_putc,
- putcs: fbcon_aty32_putcs,
- revc: fbcon_cfb32_revc,
- clear_margins: fbcon_aty32_clear_margins,
- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-
-#ifdef MODULE
MODULE_AUTHOR("(c)1999-2000 Brad Douglas <brad@neruo.com>");
MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
MODULE_LICENSE("GPL");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel, "Disable hardware acceleration (0 or 1=disabled) (default=0)");
-MODULE_PARM(font, "s");
-MODULE_PARM_DESC(font, "Specify one of the compiled-in fonts (default=none)");
MODULE_PARM(mode, "s");
MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
#ifdef CONFIG_MTRR
@@ -2567,58 +2335,3 @@ MODULE_PARM(nomtrr, "i");
MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
#endif
-int __init
-init_module(void)
-{
- if (noaccel) {
- noaccel = 1;
- printk(KERN_INFO "aty128fb: Parameter NOACCEL set\n");
- }
- if (font) {
- strncpy(fontname, font, sizeof(fontname)-1);
- printk(KERN_INFO "aty128fb: Parameter FONT set to %s\n", font);
- }
- if (mode) {
- mode_option = mode;
- printk(KERN_INFO "aty128fb: Parameter MODE set to %s\n", mode);
- }
-#ifdef CONFIG_MTRR
- if (nomtrr) {
- mtrr = 0;
- printk(KERN_INFO "aty128fb: Parameter NOMTRR set\n");
- }
-#endif
-
- aty128fb_init();
- return 0;
-}
-
-void __exit
-cleanup_module(void)
-{
- struct fb_info_aty128 *info = board_list;
-
- while (board_list) {
- info = board_list;
- board_list = board_list->next;
-
- unregister_framebuffer(&info->fb_info);
-#ifdef CONFIG_MTRR
- if (info->mtrr.vram_valid)
- mtrr_del(info->mtrr.vram, info->frame_buffer_phys,
- info->vram_size);
-#endif /* CONFIG_MTRR */
- iounmap(info->regbase);
- iounmap(info->frame_buffer);
-
- release_mem_region(pci_resource_start(info->pdev, 0),
- pci_resource_len(info->pdev, 0));
- release_mem_region(pci_resource_start(info->pdev, 1),
- pci_resource_len(info->pdev, 1));
- release_mem_region(pci_resource_start(info->pdev, 2),
- pci_resource_len(info->pdev, 2));
-
- kfree(info);
- }
-}
-#endif /* MODULE */
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index a57643eb7b32..43c030ff9ad7 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -20,30 +20,322 @@
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
+#include <linux/config.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
-#include <video/fbcon.h>
+
+#define LONG_MASK (BITS_PER_LONG - 1)
#if BITS_PER_LONG == 32
-#define FB_READ fb_readl
-#define FB_WRITE fb_writel
+#define FB_WRITEL fb_writel
+#define FB_READL fb_readl
+#define SHIFT_PER_LONG 5
+#define BYTES_PER_LONG 4
#else
-#define FB_READ fb_readq
-#define FB_WRITE fb_writeq
+#define FB_WRITEL fb_writeq
+#define FB_READL fb_readq(x)
+#define SHIFT_PER_LONG 6
+#define BYTES_PER_LONG 8
#endif
+static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
+ int src_idx, unsigned long n)
+{
+ unsigned long first, last;
+ int shift = dst_idx-src_idx, left, right;
+ unsigned long d0, d1;
+ int m;
+
+ if (!n)
+ return;
+
+ shift = dst_idx-src_idx;
+ first = ~0UL >> dst_idx;
+ last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+ if (!shift) {
+ // Same alignment for source and dest
+
+ if (dst_idx+n <= BITS_PER_LONG) {
+ // Single word
+ if (last)
+ first &= last;
+ FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+ } else {
+ // Multiple destination words
+ // Leading bits
+ if (first) {
+
+ FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+ dst++;
+ src++;
+ n -= BITS_PER_LONG-dst_idx;
+ }
+
+ // Main chunk
+ n /= BITS_PER_LONG;
+ while (n >= 8) {
+ FB_WRITEL(*src++, dst++);
+ FB_WRITEL(*src++, dst++);
+ FB_WRITEL(*src++, dst++);
+ FB_WRITEL(*src++, dst++);
+ FB_WRITEL(*src++, dst++);
+ FB_WRITEL(*src++, dst++);
+ FB_WRITEL(*src++, dst++);
+ FB_WRITEL(*src++, dst++);
+ n -= 8;
+ }
+ while (n--)
+ FB_WRITEL(*src++, dst++);
+ // Trailing bits
+ if (last)
+ FB_WRITEL((*src & last) | (FB_READL(dst) & ~last), dst);
+ }
+ } else {
+ // Different alignment for source and dest
+
+ right = shift & (BITS_PER_LONG-1);
+ left = -shift & (BITS_PER_LONG-1);
+
+ if (dst_idx+n <= BITS_PER_LONG) {
+ // Single destination word
+ if (last)
+ first &= last;
+ if (shift > 0) {
+ // Single source word
+ FB_WRITEL(((*src >> right) & first) | (FB_READL(dst) & ~first), dst);
+ } else if (src_idx+n <= BITS_PER_LONG) {
+ // Single source word
+ FB_WRITEL(((*src << left) & first) | (FB_READL(dst) & ~first), dst);
+ } else {
+ // 2 source words
+ d0 = *src++;
+ d1 = *src;
+ FB_WRITEL(((d0 << left | d1 >> right) & first) | (FB_READL(dst) & ~first), dst);
+ }
+ } else {
+ // Multiple destination words
+ d0 = *src++;
+ // Leading bits
+ if (shift > 0) {
+ // Single source word
+ FB_WRITEL(((d0 >> right) & first) | (FB_READL(dst) & ~first), dst);
+ dst++;
+ n -= BITS_PER_LONG-dst_idx;
+ } else {
+ // 2 source words
+ d1 = *src++;
+ FB_WRITEL(((d0 << left | d1 >> right) & first) | (FB_READL(dst) & ~first), dst);
+ d0 = d1;
+ dst++;
+ n -= BITS_PER_LONG-dst_idx;
+ }
+
+ // Main chunk
+ m = n % BITS_PER_LONG;
+ n /= BITS_PER_LONG;
+ while (n >= 4) {
+ d1 = *src++;
+ FB_WRITEL(d0 << left | d1 >> right, dst++);
+ d0 = d1;
+ d1 = *src++;
+ FB_WRITEL(d0 << left | d1 >> right, dst++);
+ d0 = d1;
+ d1 = *src++;
+ FB_WRITEL(d0 << left | d1 >> right, dst++);
+ d0 = d1;
+ d1 = *src++;
+ FB_WRITEL(d0 << left | d1 >> right, dst++);
+ d0 = d1;
+ n -= 4;
+ }
+ while (n--) {
+ d1 = *src++;
+ FB_WRITEL(d0 << left | d1 >> right, dst++);
+ d0 = d1;
+ }
+
+ // Trailing bits
+ if (last) {
+ if (m <= right) {
+ // Single source word
+ FB_WRITEL(((d0 << left) & last) | (FB_READL(dst) & ~last), dst);
+ } else {
+ // 2 source words
+ d1 = *src;
+ FB_WRITEL(((d0 << left | d1 >> right) & last) | (FB_READL(dst) & ~last), dst);
+ }
+ }
+ }
+ }
+}
+
+static void bitcpy_rev(unsigned long *dst, int dst_idx,
+ const unsigned long *src, int src_idx, unsigned long n)
+{
+ unsigned long first, last;
+ int shift = dst_idx-src_idx, left, right;
+ unsigned long d0, d1;
+ int m;
+
+ if (!n)
+ return;
+
+ dst += (n-1)/BITS_PER_LONG;
+ src += (n-1)/BITS_PER_LONG;
+ if ((n-1) % BITS_PER_LONG) {
+ dst_idx += (n-1) % BITS_PER_LONG;
+ dst += dst_idx >> SHIFT_PER_LONG;
+ dst_idx &= BITS_PER_LONG-1;
+ src_idx += (n-1) % BITS_PER_LONG;
+ src += src_idx >> SHIFT_PER_LONG;
+ src_idx &= BITS_PER_LONG-1;
+ }
+
+ shift = dst_idx-src_idx;
+ first = ~0UL << (BITS_PER_LONG-1-dst_idx);
+ last = ~(~0UL << (BITS_PER_LONG-1-((dst_idx-n) % BITS_PER_LONG)));
+
+ if (!shift) {
+ // Same alignment for source and dest
+
+ if ((unsigned long)dst_idx+1 >= n) {
+ // Single word
+ if (last)
+ first &= last;
+ FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+ } else {
+ // Multiple destination words
+ // Leading bits
+ if (first) {
+ FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+ dst--;
+ src--;
+ n -= dst_idx+1;
+ }
+
+ // Main chunk
+ n /= BITS_PER_LONG;
+ while (n >= 8) {
+ FB_WRITEL(*src--, dst--);
+ FB_WRITEL(*src--, dst--);
+ FB_WRITEL(*src--, dst--);
+ FB_WRITEL(*src--, dst--);
+ FB_WRITEL(*src--, dst--);
+ FB_WRITEL(*src--, dst--);
+ FB_WRITEL(*src--, dst--);
+ FB_WRITEL(*src--, dst--);
+ n -= 8;
+ }
+ while (n--)
+ FB_WRITEL(*src--, dst--);
+
+ // Trailing bits
+ if (last)
+ FB_WRITEL((*src & last) | (FB_READL(dst) & ~last), dst);
+ }
+ } else {
+ // Different alignment for source and dest
+
+ right = shift & (BITS_PER_LONG-1);
+ left = -shift & (BITS_PER_LONG-1);
+
+ if ((unsigned long)dst_idx+1 >= n) {
+ // Single destination word
+ if (last)
+ first &= last;
+ if (shift < 0) {
+ // Single source word
+ FB_WRITEL((*src << left & first) | (FB_READL(dst) & ~first), dst);
+ } else if (1+(unsigned long)src_idx >= n) {
+ // Single source word
+ FB_WRITEL(((*src >> right) & first) | (FB_READL(dst) & ~first), dst);
+ } else {
+ // 2 source words
+ d0 = *src--;
+ d1 = *src;
+ FB_WRITEL(((d0 >> right | d1 << left) & first) | (FB_READL(dst) & ~first), dst);
+ }
+ } else {
+ // Multiple destination words
+ d0 = *src--;
+ // Leading bits
+ if (shift < 0) {
+ // Single source word
+ FB_WRITEL(((d0 << left) & first) | (FB_READL(dst) & ~first), dst);
+ dst--;
+ n -= dst_idx+1;
+ } else {
+ // 2 source words
+ d1 = *src--;
+ FB_WRITEL(((d0 >> right | d1 << left) & first) | (FB_READL(dst) & ~first), dst);
+ d0 = d1;
+ dst--;
+ n -= dst_idx+1;
+ }
+
+ // Main chunk
+ m = n % BITS_PER_LONG;
+ n /= BITS_PER_LONG;
+ while (n >= 4) {
+ d1 = *src--;
+ FB_WRITEL(d0 >> right | d1 << left, dst--);
+ d0 = d1;
+ d1 = *src--;
+ FB_WRITEL(d0 >> right | d1 << left, dst--);
+ d0 = d1;
+ d1 = *src--;
+ FB_WRITEL(d0 >> right | d1 << left, dst--);
+ d0 = d1;
+ d1 = *src--;
+ FB_WRITEL(d0 >> right | d1 << left, dst--);
+ d0 = d1;
+ n -= 4;
+ }
+ while (n--) {
+ d1 = *src--;
+ FB_WRITEL(d0 >> right | d1 << left, dst--);
+ d0 = d1;
+ }
+
+ // Trailing bits
+ if (last) {
+ if (m <= left) {
+ // Single source word
+ FB_WRITEL(((d0 >> right) & last) | (FB_READL(dst) & ~last), dst);
+ } else {
+ // 2 source words
+ d1 = *src;
+ FB_WRITEL(((d0 >> right | d1 << left) & last) |
+ (FB_READL(dst) & ~last), dst);
+ }
+ }
+ }
+ }
+}
+
void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
{
- int x2, y2, lineincr, shift, shift_right, shift_left, old_dx, old_dy;
- int j, linesize = p->fix.line_length, bpl = sizeof(unsigned long);
- unsigned long start_index, end_index, start_mask, end_mask, last;
+ int x2, y2, old_dx, old_dy, vxres, vyres;
+ unsigned long next_line = p->fix.line_length;
+ int dst_idx = 0, src_idx = 0, rev_copy = 0;
unsigned long *dst = NULL, *src = NULL;
- char *src1, *dst1;
- int tmp, height;
+
+ /* We want rotation but lack hardware to do it for us. */
+ if (!p->fbops->fb_rotate && p->var.rotate) {
+ }
+
+ vxres = p->var.xres_virtual;
+ vyres = p->var.yres_virtual;
+
+ if (area->dx > vxres || area->sx > vxres ||
+ area->dy > vyres || area->sy > vyres)
+ return;
/* clip the destination */
old_dx = area->dx;
@@ -57,8 +349,8 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
y2 = area->dy + area->height;
area->dx = area->dx > 0 ? area->dx : 0;
area->dy = area->dy > 0 ? area->dy : 0;
- x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
- y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
+ x2 = x2 < vxres ? x2 : vxres;
+ y2 = y2 < vyres ? y2 : vyres;
area->width = x2 - area->dx;
area->height = y2 - area->dy;
@@ -66,165 +358,56 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
area->sx += (area->dx - old_dx);
area->sy += (area->dy - old_dy);
- height = area->height;
-
/* the source must be completely inside the virtual screen */
if (area->sx < 0 || area->sy < 0 ||
- (area->sx + area->width) > p->var.xres_virtual ||
- (area->sy + area->height) > p->var.yres_virtual)
+ (area->sx + area->width) > vxres ||
+ (area->sy + area->height) > vyres)
return;
+
+ if (area->dy > area->sy || (area->dy == area->sy && area->dx > area->sx)) {
+ area->dy += area->height;
+ area->sy += area->height;
+ rev_copy = 1;
+ }
- if (area->dy < area->sy
- || (area->dy == area->sy && area->dx < area->sx)) {
- /* start at the top */
- src1 = p->screen_base + area->sy * linesize +
- ((area->sx * p->var.bits_per_pixel) >> 3);
- dst1 = p->screen_base + area->dy * linesize +
- ((area->dx * p->var.bits_per_pixel) >> 3);
- lineincr = linesize;
+ dst = src = (unsigned long *)((unsigned long)p->screen_base & ~(BYTES_PER_LONG-1));
+ dst_idx = src_idx = (unsigned long)p->screen_base & (BYTES_PER_LONG-1);
+ dst_idx += area->dy*next_line*8 + area->dx*p->var.bits_per_pixel;
+ src_idx += area->sy*next_line*8 + area->sx*p->var.bits_per_pixel;
+
+ if (rev_copy) {
+ while (area->height--) {
+ dst_idx -= next_line*8;
+ src_idx -= next_line*8;
+ dst += dst_idx >> SHIFT_PER_LONG;
+ dst_idx &= (BYTES_PER_LONG-1);
+ src += src_idx >> SHIFT_PER_LONG;
+ src_idx &= (BYTES_PER_LONG-1);
+ bitcpy_rev((unsigned long*)dst, dst_idx, (unsigned long *)src,
+ src_idx, area->width*p->var.bits_per_pixel);
+ }
} else {
- /* start at the bottom */
- src1 = p->screen_base + (area->sy + area->height-1) * linesize
- + (((area->sx + area->width - 1) * p->var.bits_per_pixel) >> 3);
- dst1 = p->screen_base + (area->dy + area->height-1) * linesize
- + (((area->dx + area->width - 1) * p->var.bits_per_pixel) >> 3);
- lineincr = -linesize;
+ while (area->height--) {
+ dst += dst_idx >> SHIFT_PER_LONG;
+ dst_idx &= (BYTES_PER_LONG-1);
+ src += src_idx >> SHIFT_PER_LONG;
+ src_idx &= (BYTES_PER_LONG-1);
+ bitcpy((unsigned long*)dst, dst_idx, (unsigned long *)src,
+ src_idx, area->width*p->var.bits_per_pixel);
+ dst_idx += next_line*8;
+ src_idx += next_line*8;
+ }
}
+}
- if ((BITS_PER_LONG % p->var.bits_per_pixel) == 0) {
- int ppw = BITS_PER_LONG / p->var.bits_per_pixel;
- int n = ((area->width * p->var.bits_per_pixel) >> 3);
-
- start_index = ((unsigned long) src1 & (bpl - 1));
- end_index = ((unsigned long) (src1 + n) & (bpl - 1));
- shift = ((unsigned long) dst1 & (bpl - 1)) -
- ((unsigned long) src1 & (bpl - 1));
- start_mask = end_mask = 0;
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
- if (start_index) {
- start_mask = -1 >> (start_index << 3);
- n -= (bpl - start_index);
- }
+EXPORT_SYMBOL(cfb_copyarea);
- if (end_index) {
- end_mask = -1 << ((bpl - end_index) << 3);
- n -= end_index;
- }
- n /= bpl;
-
- if (n <= 0) {
- if (start_mask) {
- if (end_mask)
- end_mask &= start_mask;
- else
- end_mask = start_mask;
- start_mask = 0;
- }
- n = 0;
- }
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software accelerated copyarea");
+MODULE_LICENSE("GPL");
- if (shift) {
- if (shift > 0) {
- /* dest is over to right more */
- shift_right =
- shift * p->var.bits_per_pixel;
- shift_left =
- (ppw - shift) * p->var.bits_per_pixel;
- } else {
- /* source is to the right more */
- shift_right =
- (ppw + shift) * p->var.bits_per_pixel;
- shift_left =
- -shift * p->var.bits_per_pixel;
- }
- /* general case, positive increment */
- if (lineincr > 0) {
- if (shift < 0)
- n++;
- do {
- dst = (unsigned long *) dst1;
- src = (unsigned long *) src1;
-
- last = (FB_READ(src) & start_mask);
-
- if (shift > 0)
- FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
- for (j = 0; j < n; j++) {
- dst++;
- tmp = FB_READ(src);
- src++;
- FB_WRITE((last << shift_left) | (tmp >> shift_right), dst);
- last = tmp;
- src++;
- }
- FB_WRITE(FB_READ(dst) | (last << shift_left), dst);
- src1 += lineincr;
- dst1 += lineincr;
- } while (--height);
- } else {
- /* general case, negative increment */
- if (shift > 0)
- n++;
- do {
- dst = (unsigned long *) dst1;
- src = (unsigned long *) src1;
-
- last = (FB_READ(src) & end_mask);
-
- if (shift < 0)
- FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
- for (j = 0; j < n; j++) {
- dst--;
- tmp = FB_READ(src);
- src--;
- FB_WRITE((tmp << shift_left) | (last >> shift_right), dst);
- last = tmp;
- src--;
- }
- FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
- src1 += lineincr;
- dst1 += lineincr;
- } while (--height);
- }
- } else {
- /* no shift needed */
- if (lineincr > 0) {
- /* positive increment */
- do {
- dst = (unsigned long *) (dst1 - start_index);
- src = (unsigned long *) (src1 - start_index);
-
- if (start_mask)
- FB_WRITE(FB_READ(src) | start_mask, dst);
-
- for (j = 0; j < n; j++) {
- FB_WRITE(FB_READ(src), dst);
- dst++;
- src++;
- }
-
- if (end_mask)
- FB_WRITE(FB_READ(src) | end_mask, dst);
- src1 += lineincr;
- dst1 += lineincr;
- } while (--height);
- } else {
- /* negative increment */
- do {
- dst = (unsigned long *) dst1;
- src = (unsigned long *) src1;
-
- if (start_mask)
- FB_WRITE(FB_READ(src) | start_mask, dst);
- for (j = 0; j < n; j++) {
- FB_WRITE(FB_READ(src), dst);
- dst--;
- src--;
- }
- src1 += lineincr;
- dst1 += lineincr;
- } while (--height);
- }
- }
- }
-}
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index d052a89bd5eb..fd272386e6c3 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -17,173 +17,439 @@
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
+#include <linux/config.h>
+#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
-#include <video/fbcon.h>
#if BITS_PER_LONG == 32
-#define FB_READ fb_readl
-#define FB_WRITE fb_writel
+#define FB_WRITEL fb_writel
+#define FB_READL fb_readl
+#define BYTES_PER_LONG 4
+#define SHIFT_PER_LONG 5
#else
-#define FB_READ fb_readq
-#define FB_WRITE fb_writeq
+#define FB_WRITEL fb_writeq
+#define FB_READL fb_readq
+#define BYTES_PER_LONG 8
+#define SHIFT_PER_LONG 6
#endif
-void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
+#define EXP1(x) 0xffffffffU*x
+#define EXP2(x) 0x55555555U*x
+#define EXP4(x) 0x11111111U*0x ## x
+
+typedef u32 pixel_t;
+
+static const u32 bpp1tab[2] = {
+ EXP1(0), EXP1(1)
+};
+
+static const u32 bpp2tab[4] = {
+ EXP2(0), EXP2(1), EXP2(2), EXP2(3)
+};
+
+static const u32 bpp4tab[16] = {
+ EXP4(0), EXP4(1), EXP4(2), EXP4(3), EXP4(4), EXP4(5), EXP4(6), EXP4(7),
+ EXP4(8), EXP4(9), EXP4(a), EXP4(b), EXP4(c), EXP4(d), EXP4(e), EXP4(f)
+};
+
+ /*
+ * Compose two values, using a bitmask as decision value
+ * This is equivalent to (a & mask) | (b & ~mask)
+ */
+
+static inline unsigned long comp(unsigned long a, unsigned long b,
+ unsigned long mask)
{
- unsigned long start_index, end_index, start_mask = 0, end_mask = 0;
- unsigned long height, ppw, fg, fgcolor;
- int i, n, x2, y2, linesize = p->fix.line_length;
- int bpl = sizeof(unsigned long);
- unsigned long *dst;
- char *dst1;
+ return ((a ^ b) & mask) ^ b;
+}
- if (!rect->width || !rect->height)
- return;
+static inline u32 pixel_to_pat32(const struct fb_info *p, pixel_t pixel)
+{
+ u32 pat = pixel;
- /* We could use hardware clipping but on many cards you get around
- * hardware clipping by writing to framebuffer directly. */
- x2 = rect->dx + rect->width;
- y2 = rect->dy + rect->height;
- x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
- y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
- rect->width = x2 - rect->dx;
- height = y2 - rect->dy;
+ switch (p->var.bits_per_pixel) {
+ case 1:
+ pat = bpp1tab[pat];
+ break;
- /* Size of the scanline in bytes */
- n = (rect->width * (p->var.bits_per_pixel >> 3));
- ppw = BITS_PER_LONG / p->var.bits_per_pixel;
+ case 2:
+ pat = bpp2tab[pat];
+ break;
- dst1 = p->screen_base + (rect->dy * linesize) +
- (rect->dx * (p->var.bits_per_pixel >> 3));
- start_index = ((unsigned long) dst1 & (bpl - 1));
- end_index = ((unsigned long) (dst1 + n) & (bpl - 1));
+ case 4:
+ pat = bpp4tab[pat];
+ break;
- if (p->fix.visual == FB_VISUAL_TRUECOLOR)
- fg = fgcolor = ((u32 *) (p->pseudo_palette))[rect->color];
- else
- fg = fgcolor = rect->color;
+ case 8:
+ pat |= pat << 8;
+ // Fall through
+ case 16:
+ pat |= pat << 16;
+ // Fall through
+ case 32:
+ break;
+ }
+ return pat;
+}
+
+ /*
+ * Expand a pixel value to a generic 32/64-bit pattern and rotate it to
+ * the correct start position
+ */
+
+static inline unsigned long pixel_to_pat(const struct fb_info *p, pixel_t pixel, int left)
+{
+ unsigned long pat = pixel;
+ u32 bpp = p->var.bits_per_pixel;
+ int i;
+
+ /* expand pixel value */
+ for (i = bpp; i < BITS_PER_LONG; i *= 2)
+ pat |= pat << i;
- for (i = 0; i < ppw - 1; i++) {
- fg <<= p->var.bits_per_pixel;
- fg |= fgcolor;
+ /* rotate pattern to correct start position */
+ pat = pat << left | pat >> (bpp-left);
+ return pat;
+}
+
+ /*
+ * Unaligned 32-bit pattern fill using 32/64-bit memory accesses
+ */
+
+void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
+{
+ unsigned long val = pat;
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+#if BITS_PER_LONG == 64
+ val |= val << 32;
+#endif
+
+ first = ~0UL >> dst_idx;
+ last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+ if (dst_idx+n <= BITS_PER_LONG) {
+ // Single word
+ if (last)
+ first &= last;
+ FB_WRITEL(comp(val, FB_READL(dst), first), dst);
+ } else {
+ // Multiple destination words
+ // Leading bits
+ if (first) {
+ FB_WRITEL(comp(val, FB_READL(dst), first), dst);
+ dst++;
+ n -= BITS_PER_LONG-dst_idx;
+ }
+
+ // Main chunk
+ n /= BITS_PER_LONG;
+ while (n >= 8) {
+ FB_WRITEL(val, dst++);
+ FB_WRITEL(val, dst++);
+ FB_WRITEL(val, dst++);
+ FB_WRITEL(val, dst++);
+ FB_WRITEL(val, dst++);
+ FB_WRITEL(val, dst++);
+ FB_WRITEL(val, dst++);
+ FB_WRITEL(val, dst++);
+ n -= 8;
+ }
+ while (n--)
+ FB_WRITEL(val, dst++);
+
+ // Trailing bits
+ if (last)
+ FB_WRITEL(comp(val, FB_READL(dst), first), dst);
}
+}
+
- if (start_index) {
- start_mask = fg << (start_index << 3);
- n -= (bpl - start_index);
+ /*
+ * Unaligned generic pattern fill using 32/64-bit memory accesses
+ * The pattern must have been expanded to a full 32/64-bit value
+ * Left/right are the appropriate shifts to convert to the pattern to be
+ * used for the next 32/64-bit word
+ */
+
+void bitfill(unsigned long *dst, int dst_idx, unsigned long pat, int left,
+ int right, u32 n)
+{
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = ~0UL >> dst_idx;
+ last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+ if (dst_idx+n <= BITS_PER_LONG) {
+ // Single word
+ if (last)
+ first &= last;
+ FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
+ } else {
+ // Multiple destination words
+ // Leading bits
+ if (first) {
+ FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
+ dst++;
+ pat = pat << left | pat >> right;
+ n -= BITS_PER_LONG-dst_idx;
+ }
+
+ // Main chunk
+ n /= BITS_PER_LONG;
+ while (n >= 4) {
+ FB_WRITEL(pat, dst++);
+ pat = pat << left | pat >> right;
+ FB_WRITEL(pat, dst++);
+ pat = pat << left | pat >> right;
+ FB_WRITEL(pat, dst++);
+ pat = pat << left | pat >> right;
+ FB_WRITEL(pat, dst++);
+ pat = pat << left | pat >> right;
+ n -= 4;
+ }
+ while (n--) {
+ FB_WRITEL(pat, dst++);
+ pat = pat << left | pat >> right;
+ }
+
+ // Trailing bits
+ if (last)
+ FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
}
+}
- if (end_index) {
- end_mask = fg >> ((bpl - end_index) << 3);
- n -= end_index;
+void bitfill32_rev(unsigned long *dst, int dst_idx, u32 pat, u32 n)
+{
+ unsigned long val = pat, dat;
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+#if BITS_PER_LONG == 64
+ val |= val << 32;
+#endif
+
+ first = ~0UL >> dst_idx;
+ last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+ if (dst_idx+n <= BITS_PER_LONG) {
+ // Single word
+ if (last)
+ first &= last;
+ dat = FB_READL(dst);
+ FB_WRITEL(comp(dat ^ val, dat, first), dst);
+ } else {
+ // Multiple destination words
+ // Leading bits
+ if (first) {
+ dat = FB_READL(dst);
+ FB_WRITEL(comp(dat ^ val, dat, first), dst);
+ dst++;
+ n -= BITS_PER_LONG-dst_idx;
+ }
+
+ // Main chunk
+ n /= BITS_PER_LONG;
+ while (n >= 8) {
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ n -= 8;
+ }
+ while (n--) {
+ FB_WRITEL(FB_READL(dst) ^ val, dst);
+ dst++;
+ }
+ // Trailing bits
+ if (last) {
+ dat = FB_READL(dst);
+ FB_WRITEL(comp(dat ^ val, dat, first), dst);
+ }
}
+}
- n = n / bpl;
- if (n <= 0) {
- if (start_mask) {
- if (end_mask)
- end_mask &= start_mask;
- else
- end_mask = start_mask;
- start_mask = 0;
+ /*
+ * Unaligned generic pattern fill using 32/64-bit memory accesses
+ * The pattern must have been expanded to a full 32/64-bit value
+ * Left/right are the appropriate shifts to convert to the pattern to be
+ * used for the next 32/64-bit word
+ */
+
+void bitfill_rev(unsigned long *dst, int dst_idx, unsigned long pat, int left,
+ int right, u32 n)
+{
+ unsigned long first, last, dat;
+
+ if (!n)
+ return;
+
+ first = ~0UL >> dst_idx;
+ last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+ if (dst_idx+n <= BITS_PER_LONG) {
+ // Single word
+ if (last)
+ first &= last;
+ dat = FB_READL(dst);
+ FB_WRITEL(comp(dat ^ pat, dat, first), dst);
+ } else {
+ // Multiple destination words
+ // Leading bits
+ if (first) {
+ dat = FB_READL(dst);
+ FB_WRITEL(comp(dat ^ pat, dat, first), dst);
+ dst++;
+ pat = pat << left | pat >> right;
+ n -= BITS_PER_LONG-dst_idx;
+ }
+
+ // Main chunk
+ n /= BITS_PER_LONG;
+ while (n >= 4) {
+ FB_WRITEL(FB_READL(dst) ^ pat, dst);
+ dst++;
+ pat = pat << left | pat >> right;
+ FB_WRITEL(FB_READL(dst) ^ pat, dst);
+ dst++;
+ pat = pat << left | pat >> right;
+ FB_WRITEL(FB_READL(dst) ^ pat, dst);
+ dst++;
+ pat = pat << left | pat >> right;
+ FB_WRITEL(FB_READL(dst) ^ pat, dst);
+ dst++;
+ pat = pat << left | pat >> right;
+ n -= 4;
+ }
+ while (n--) {
+ FB_WRITEL(FB_READL(dst) ^ pat, dst);
+ dst++;
+ pat = pat << left | pat >> right;
+ }
+
+ // Trailing bits
+ if (last) {
+ dat = FB_READL(dst);
+ FB_WRITEL(comp(dat ^ pat, dat, first), dst);
}
- n = 0;
}
+}
- if ((BITS_PER_LONG % p->var.bits_per_pixel) == 0) {
+void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
+{
+ unsigned long height, fg;
+ unsigned long x2, y2, vxres, vyres;
+ unsigned long *dst;
+ int dst_idx, left;
+ u32 bpp = p->var.bits_per_pixel;
+
+ /* We want rotation but lack hardware to do it for us. */
+ if (!p->fbops->fb_rotate && p->var.rotate) {
+ }
+
+ vxres = p->var.xres_virtual;
+ vyres = p->var.yres_virtual;
+
+ if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)
+ return;
+
+ /* We could use hardware clipping but on many cards you get around
+ * hardware clipping by writing to framebuffer directly. */
+
+ x2 = rect->dx + rect->width;
+ y2 = rect->dy + rect->height;
+ x2 = x2 < vxres ? x2 : vxres;
+ y2 = y2 < vyres ? y2 : vyres;
+ rect->width = x2 - rect->dx;
+ height = y2 - rect->dy;
+
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+ fg = ((u32 *) (p->pseudo_palette))[rect->color];
+ else
+ fg = rect->color;
+
+ dst = (unsigned long *)((unsigned long)p->screen_base & ~(BYTES_PER_LONG-1));
+ dst_idx = ((unsigned long)p->screen_base & (BYTES_PER_LONG-1))*8;
+ dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
+ /* FIXME For now we support 1-32 bpp only */
+ left = BITS_PER_LONG % bpp;
+ if (!left) {
+ u32 pat = pixel_to_pat32(p, fg);
+ void (*fill_op32)(unsigned long *dst, int dst_idx, u32 pat, u32 n) = NULL;
+
switch (rect->rop) {
- case ROP_COPY:
- do {
- /* Word align to increases performace :-) */
- dst = (unsigned long *) (dst1 - start_index);
-
- if (start_mask) {
- FB_WRITE(FB_READ(dst) |
- start_mask, dst);
- dst++;
- }
-
- for (i = 0; i < n; i++) {
- FB_WRITE(fg, dst);
- dst++;
- }
-
- if (end_mask)
- FB_WRITE(FB_READ(dst) | end_mask,
- dst);
- dst1 += linesize;
- } while (--height);
- break;
case ROP_XOR:
- do {
- dst = (unsigned long *) (dst1 - start_index);
-
- if (start_mask) {
- FB_WRITE(FB_READ(dst) ^
- start_mask, dst);
- dst++;
- }
-
- for (i = 0; i < n; i++) {
- FB_WRITE(FB_READ(dst) ^ fg, dst);
- dst++;
- }
-
- if (end_mask) {
- FB_WRITE(FB_READ(dst) ^ end_mask,
- dst);
- }
- dst1 += linesize;
- } while (--height);
+ fill_op32 = bitfill32_rev;
break;
+ case ROP_COPY:
+ default:
+ fill_op32 = bitfill32;
+ break;
+ }
+ while (height--) {
+ dst += dst_idx >> SHIFT_PER_LONG;
+ dst_idx &= (BITS_PER_LONG-1);
+ fill_op32(dst, dst_idx, pat, rect->width*bpp);
+ dst_idx += p->fix.line_length*8;
}
} else {
- /* Odd modes like 24 or 80 bits per pixel */
- start_mask = fg >> (start_index * p->var.bits_per_pixel);
- end_mask = fg << (end_index * p->var.bits_per_pixel);
- /* start_mask =& PFILL24(x1,fg);
- end_mask_or = end_mask & PFILL24(x1+width-1,fg); */
-
- n = (rect->width - start_index - end_index) / ppw;
-
+ unsigned long pat = pixel_to_pat(p, fg, (left-dst_idx) % bpp);
+ int right = bpp-left;
+ int r;
+ void (*fill_op)(unsigned long *dst, int dst_idx, unsigned long pat,
+ int left, int right, u32 n) = NULL;
+
switch (rect->rop) {
- case ROP_COPY:
- do {
- dst = (unsigned long *) dst1;
- if (start_mask)
- *dst |= start_mask;
- if ((start_index + rect->width) > ppw)
- dst++;
-
- /* XXX: slow */
- for (i = 0; i < n; i++) {
- *dst++ = fg;
- }
- if (end_mask)
- *dst |= end_mask;
- dst1 += linesize;
- } while (--height);
- break;
case ROP_XOR:
- do {
- dst = (unsigned long *) dst1;
- if (start_mask)
- *dst ^= start_mask;
- if ((start_mask + rect->width) > ppw)
- dst++;
-
- for (i = 0; i < n; i++) {
- *dst++ ^= fg; /* PFILL24(fg,x1+i); */
- }
- if (end_mask)
- *dst ^= end_mask;
- dst1 += linesize;
- } while (--height);
+ fill_op = bitfill_rev;
+ break;
+ case ROP_COPY:
+ default:
+ fill_op = bitfill;
break;
}
+ while (height--) {
+ dst += dst_idx >> SHIFT_PER_LONG;
+ dst_idx &= (BITS_PER_LONG-1);
+ fill_op(dst, dst_idx, pat, left, right, rect->width*bpp);
+ r = (p->fix.line_length*8) % bpp;
+ pat = pat << (bpp-r) | pat >> r;
+ dst_idx += p->fix.line_length*8;
+ }
}
- return;
}
+
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
+
+EXPORT_SYMBOL(cfb_fillrect);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software accelerated fill rectangle");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index e3f138ad21b3..11a87a694a85 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -22,17 +22,24 @@
* FIXME
* The code for 24 bit is horrible. It copies byte by byte size instead of
* longs like the other sizes. Needs to be optimized.
+ *
+ * Tony:
+ * Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API. This speeds
+ * up the code significantly.
+ *
+ * Code for depths not multiples of BITS_PER_LONG is still kludgy, which is
+ * still processed a bit at a time.
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
+#include <linux/config.h>
+#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
-#include <video/fbcon.h>
-
#define DEBUG
#ifdef DEBUG
@@ -41,91 +48,308 @@
#define DPRINTK(fmt, args...)
#endif
+static u32 cfb_tab8[] = {
+#if defined(__BIG_ENDIAN)
+ 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+ 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+ 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+ 0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+ 0x00000000,0xff000000,0x00ff0000,0xffff0000,
+ 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+ 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+ 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static u32 cfb_tab16[] = {
+#if defined(__BIG_ENDIAN)
+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+ 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static u32 cfb_tab32[] = {
+ 0x00000000, 0xffffffff
+};
+
+#if BITS_PER_LONG == 32
+#define FB_WRITEL fb_writel
+#define FB_READL fb_readl
+#else
+#define FB_WRITEL fb_writeq
+#define FB_READL fb_readq
+#endif
+
+#if defined (__BIG_ENDIAN)
+#define LEFT_POS(bpp) (BITS_PER_LONG - bpp)
+#define NEXT_POS(pos, bpp) ((pos) -= (bpp))
+#define SHIFT_HIGH(val, bits) ((val) >> (bits))
+#define SHIFT_LOW(val, bits) ((val) << (bits))
+#else
+#define LEFT_POS(bpp) (0)
+#define NEXT_POS(pos, bpp) ((pos) += (bpp))
+#define SHIFT_HIGH(val, bits) ((val) << (bits))
+#define SHIFT_LOW(val, bits) ((val) >> (bits))
+#endif
+
+static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1,
+ unsigned long start_index, unsigned long pitch_index)
+{
+ /* Draw the penguin */
+ int i, n;
+ unsigned long bitmask = SHIFT_LOW(~0UL, BITS_PER_LONG - p->var.bits_per_pixel);
+ unsigned long *palette = (unsigned long *) p->pseudo_palette;
+ unsigned long *dst, *dst2, color = 0, val, shift;
+ unsigned long null_bits = BITS_PER_LONG - p->var.bits_per_pixel;
+ u8 *src = image->data;
+
+ dst2 = (unsigned long *) dst1;
+ for (i = image->height; i--; ) {
+ n = image->width;
+ dst = (unsigned long *) dst1;
+ shift = 0;
+ val = 0;
+
+ if (start_index) {
+ unsigned long start_mask = ~(SHIFT_HIGH(~0UL, start_index));
+
+ val = FB_READL(dst) & start_mask;
+ shift = start_index;
+ }
+ while (n--) {
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+ color = palette[*src] & bitmask;
+ else
+ color = *src & bitmask;
+ val |= SHIFT_HIGH(color, shift);
+ if (shift >= null_bits) {
+ FB_WRITEL(val, dst++);
+ if (shift == null_bits)
+ val = 0;
+ else
+ val = SHIFT_LOW(color, BITS_PER_LONG - shift);
+ }
+ shift += p->var.bits_per_pixel;
+ shift &= (BITS_PER_LONG - 1);
+ src++;
+ }
+ if (shift) {
+ unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
+
+ FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
+ }
+ dst1 += p->fix.line_length;
+ if (pitch_index) {
+ dst2 += p->fix.line_length;
+ dst1 = (char *) dst2;
+ (unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
+
+ start_index += pitch_index;
+ start_index &= BITS_PER_LONG - 1;
+ }
+ }
+}
+
+static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1,
+ unsigned long fgcolor, unsigned long bgcolor,
+ unsigned long start_index, unsigned long pitch_index)
+{
+ unsigned long i, j, l = 8;
+ unsigned long shift, color, bpp = p->var.bits_per_pixel;
+ unsigned long *dst, *dst2, val, pitch = p->fix.line_length;
+ unsigned long null_bits = BITS_PER_LONG - bpp;
+ u8 *src = image->data;
+
+ dst2 = (unsigned long *) dst1;
+
+ for (i = image->height; i--; ) {
+ shift = 0;
+ val = 0;
+ j = image->width;
+ dst = (unsigned long *) dst1;
+
+ /* write leading bits */
+ if (start_index) {
+ unsigned long start_mask = ~(SHIFT_HIGH(~0UL, start_index));
+
+ val = FB_READL(dst) & start_mask;
+ shift = start_index;
+ }
+ while (j--) {
+ l--;
+ if (*src & (1 << l))
+ color = fgcolor;
+ else
+ color = bgcolor;
+ val |= SHIFT_HIGH(color, shift);
+
+ /* Did the bitshift spill bits to the next long? */
+ if (shift >= null_bits) {
+ FB_WRITEL(val, dst++);
+ if (shift == null_bits)
+ val = 0;
+ else
+ val = SHIFT_LOW(color, BITS_PER_LONG - shift);
+ }
+ shift += bpp;
+ shift &= (BITS_PER_LONG - 1);
+ if (!l) { l = 8; src++; };
+ }
+ /* write trailing bits */
+ if (shift) {
+ unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
+
+ FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
+ }
+ dst1 += pitch;
+
+ if (pitch_index) {
+ dst2 += pitch;
+ dst1 = (char *) dst2;
+ (unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
+
+ start_index += pitch_index;
+ start_index &= BITS_PER_LONG - 1;
+ }
+
+ }
+}
+
+static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1,
+ unsigned long fgcolor, unsigned long bgcolor)
+{
+ int i, j, k, l = 8, n;
+ unsigned long bit_mask, end_mask, eorx;
+ unsigned long fgx = fgcolor, bgx = bgcolor, pad, bpp = p->var.bits_per_pixel;
+ unsigned long tmp = (1 << bpp) - 1;
+ unsigned long ppw = BITS_PER_LONG/bpp, ppos;
+ unsigned long *dst;
+ u32 *tab = NULL;
+ char *src = image->data;
+
+ switch (ppw) {
+ case 4:
+ tab = cfb_tab8;
+ break;
+ case 2:
+ tab = cfb_tab16;
+ break;
+ case 1:
+ tab = cfb_tab32;
+ break;
+ }
+
+ for (i = ppw-1; i--; ) {
+ fgx <<= bpp;
+ bgx <<= bpp;
+ fgx |= fgcolor;
+ bgx |= bgcolor;
+ }
+
+ n = ((image->width + 7) / 8);
+ pad = (n * 8) - image->width;
+ n = image->width % ppw;
+
+ bit_mask = (1 << ppw) - 1;
+ eorx = fgx ^ bgx;
+
+ k = image->width/ppw;
+
+ for (i = image->height; i--; ) {
+ dst = (unsigned long *) dst1;
+
+ for (j = k; j--; ) {
+ l -= ppw;
+ end_mask = tab[(*src >> l) & bit_mask];
+ FB_WRITEL((end_mask & eorx)^bgx, dst++);
+ if (!l) { l = 8; src++; }
+ }
+ if (n) {
+ end_mask = 0;
+ ppos = LEFT_POS(bpp);
+ for (j = n; j > 0; j--) {
+ l--;
+ if (*src & (1 << l))
+ end_mask |= tmp << ppos;
+ NEXT_POS(ppos, bpp);
+ if (!l) { l = 8; src++; }
+ }
+ FB_WRITEL((end_mask & eorx)^bgx, dst++);
+ }
+ l -= pad;
+ dst1 += p->fix.line_length;
+ }
+}
+
void cfb_imageblit(struct fb_info *p, struct fb_image *image)
{
- int pad, ppw;
- int x2, y2, n, i, j, k, l = 7;
- unsigned long tmp = ~0 << (BITS_PER_LONG - p->var.bits_per_pixel);
- unsigned long fgx, bgx, fgcolor, bgcolor, eorx;
- unsigned long end_mask;
- unsigned long *dst = NULL;
+ int x2, y2, vxres, vyres;
+ unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
+ unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
u8 *dst1;
- u8 *src;
+ vxres = p->var.xres_virtual;
+ vyres = p->var.yres_virtual;
/*
* We could use hardware clipping but on many cards you get around hardware
* clipping by writing to framebuffer directly like we are doing here.
*/
+ if (image->dx > vxres ||
+ image->dy > vyres)
+ return;
+
x2 = image->dx + image->width;
y2 = image->dy + image->height;
image->dx = image->dx > 0 ? image->dx : 0;
image->dy = image->dy > 0 ? image->dy : 0;
- x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
- y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
+ x2 = x2 < vxres ? x2 : vxres;
+ y2 = y2 < vyres ? y2 : vyres;
image->width = x2 - image->dx;
image->height = y2 - image->dy;
-
- dst1 = p->screen_base + image->dy * p->fix.line_length +
- ((image->dx * p->var.bits_per_pixel) >> 3);
-
- ppw = BITS_PER_LONG/p->var.bits_per_pixel;
- src = image->data;
+ bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
+ start_index = bitstart & (BITS_PER_LONG - 1);
+ pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
- if (image->depth == 1) {
+ bitstart /= 8;
+ bitstart &= ~(bpl - 1);
+ dst1 = p->screen_base + bitstart;
- if (p->fix.visual == FB_VISUAL_TRUECOLOR) {
- fgx = fgcolor = ((u32 *)(p->pseudo_palette))[image->fg_color];
- bgx = bgcolor = ((u32 *)(p->pseudo_palette))[image->bg_color];
+ if (image->depth == 1) {
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ fgcolor = ((u32 *)(p->pseudo_palette))[image->fg_color];
+ bgcolor = ((u32 *)(p->pseudo_palette))[image->bg_color];
} else {
- fgx = fgcolor = image->fg_color;
- bgx = bgcolor = image->bg_color;
+ fgcolor = image->fg_color;
+ bgcolor = image->bg_color;
}
-
- for (i = 0; i < ppw-1; i++) {
- fgx <<= p->var.bits_per_pixel;
- bgx <<= p->var.bits_per_pixel;
- fgx |= fgcolor;
- bgx |= bgcolor;
- }
- eorx = fgx ^ bgx;
- n = ((image->width + 7) >> 3);
- pad = (n << 3) - image->width;
- n = image->width % ppw;
-
- for (i = 0; i < image->height; i++) {
- dst = (unsigned long *) dst1;
- for (j = image->width/ppw; j > 0; j--) {
- end_mask = 0;
-
- for (k = ppw; k > 0; k--) {
- if (test_bit(l, (unsigned long *) src))
- end_mask |= (tmp >> (p->var.bits_per_pixel*(k-1)));
- l--;
- if (l < 0) { l = 7; src++; }
- }
- fb_writel((end_mask & eorx)^bgx, dst);
- dst++;
- }
-
- if (n) {
- end_mask = 0;
- for (j = n; j > 0; j--) {
- if (test_bit(l, (unsigned long *) src))
- end_mask |= (tmp >> (p->var.bits_per_pixel*(j-1)));
- l--;
- if (l < 0) { l = 7; src++; }
- }
- fb_writel((end_mask & eorx)^bgx, dst);
- dst++;
- }
- l -= pad;
- dst1 += p->fix.line_length;
- }
- } else {
- /* Draw the penguin */
- n = ((image->width * p->var.bits_per_pixel) >> 3);
- end_mask = 0;
+ if (BITS_PER_LONG % bpp == 0 && !start_index && !pitch_index &&
+ bpp >= 8 && bpp <= 32 && (image->width & 7) == 0)
+ fast_imageblit(image, p, dst1, fgcolor, bgcolor);
+ else
+ slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index);
}
+ else if (image->depth == bpp)
+ color_imageblit(image, p, dst1, start_index, pitch_index);
}
+
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
+
+EXPORT_SYMBOL(cfb_imageblit);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software accelerated imaging drawing");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 4ad4e2e30ae5..ee43294488f1 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -562,7 +562,7 @@ static void __init init_chips(struct fb_info_chips *p)
}
printk("fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
- GET_FB_IDX(p->info.node), p->fix.smem_len / 1024);
+ minor(p->info.node), p->fix.smem_len / 1024);
chips_hw_init(p);
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index 14a67d332255..e54209c0728b 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -27,8 +27,6 @@
#include <linux/proc_fs.h>
#include <linux/delay.h>
-#include <video/fbcon.h>
-
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/uaccess.h>
@@ -216,14 +214,12 @@ static struct fb_ops clps7111fb_ops = {
.owner = THIS_MODULE,
.fb_check_var = clps7111fb_check_var,
.fb_set_par = clps7111fb_set_par,
- .fb_set_var = gen_set_var,
- .fb_set_cmap = gen_set_cmap,
- .fb_get_cmap = gen_get_cmap,
.fb_setcolreg = clps7111fb_setcolreg,
.fb_blank = clps7111fb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
static int
@@ -368,20 +364,15 @@ int __init clps711xfb_init(void)
{
int err = -ENOMEM;
- cfb = kmalloc(sizeof(*cfb) + sizeof(struct display), GFP_KERNEL);
+ cfb = kmalloc(sizeof(*cfb), GFP_KERNEL);
if (!cfb)
goto out;
- memset(cfb, 0, sizeof(*cfb) + sizeof(struct display));
+ memset(cfb, 0, sizeof(*cfb));
strcpy(cfb->fix.id, "clps711x");
- cfb->currcon = -1;
cfb->fbops = &clps7111fb_ops;
- cfb->changevar = NULL;
- cfb->switch_con = gen_switch;
- cfb->updatevar = gen_update_var;
cfb->flags = FBINFO_FLAG_DEFAULT;
- cfb->disp = (struct display *)(cfb + 1);
clps711x_guess_lcd_params(cfb);
@@ -422,7 +413,6 @@ int __init clps711xfb_init(void)
clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
}
- gen_set_var(&cfb->var, -1, cfb);
err = register_framebuffer(cfb);
out: return err;
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
new file mode 100644
index 000000000000..bf88c5c88d8d
--- /dev/null
+++ b/drivers/video/console/Kconfig
@@ -0,0 +1,221 @@
+#
+# Video configuration
+#
+
+menu "Console display driver support"
+
+config VGA_CONSOLE
+ bool "VGA text console"
+ depends on !ARCH_ACORN && !ARCH_EBSA110 || !4xx && !8xx
+ help
+ Saying Y here will allow you to use Linux in text mode through a
+ display that complies with the generic VGA standard. Virtually
+ everyone wants that.
+
+ The program SVGATextMode can be used to utilize SVGA video cards to
+ their full potential in text mode. Download it from
+ <ftp://ibiblio.org/pub/Linux/utils/console/>.
+
+ Say Y.
+
+# if [ "$CONFIG_PCI" = "y" -a "$CONFIG_VGA_CONSOLE" = "y" ]; then
+# bool ' Allow VGA on any bus?' CONFIG_VGA_HOSE
+# if [ "$CONFIG_VGA_HOSE" = "y" ]; then
+# define_bool CONFIG_DUMMY_CONSOLE y
+# fi
+# fi
+
+config VIDEO_SELECT
+ bool "Video mode selection support"
+ depends on (X86 || X86_64) && VGA_CONSOLE
+ ---help---
+ This enables support for text mode selection on kernel startup. If
+ you want to take advantage of some high-resolution text mode your
+ card's BIOS offers, but the traditional Linux utilities like
+ SVGATextMode don't, you can say Y here and set the mode using the
+ "vga=" option from your boot loader (lilo or loadlin) or set
+ "vga=ask" which brings up a video mode menu on kernel startup. (Try
+ "man bootparam" or see the documentation of your boot loader about
+ how to pass options to the kernel.)
+
+ Read the file <file:Documentation/svga.txt> for more information
+ about the Video mode selection support. If unsure, say N.
+
+config MDA_CONSOLE
+ tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
+ ---help---
+ Say Y here if you have an old MDA or monochrome Hercules graphics
+ adapter in your system acting as a second head ( = video card). You
+ will then be able to use two monitors with your Linux system. Do not
+ say Y here if your MDA card is the primary card in your system; the
+ normal VGA driver will handle it.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want).
+ The module will be called mdacon.o. If you want to compile it as
+ a module, say M here and read <file:Documentation/modules.txt>.
+
+ If unsure, say N.
+
+config SGI_NEWPORT_CONSOLE
+ tristate "SGI Newport Console support"
+ depends on SGI_IP22
+ help
+ Say Y here if you want the console on the Newport aka XL graphics
+ card of your Indy. Most people say Y here.
+
+# bool 'IODC console' CONFIG_IODC_CONSOLE
+config STI_CONSOLE
+ bool "STI console"
+ depends on PARISC
+ help
+ The STI console is the builtin display/keyboard on HP-PARISC
+ machines. Say Y here to build support for it into your kernel.
+ The alternative is to use your primary serial port as a console.
+
+config PROM_CONSOLE
+ bool "PROM console"
+ depends on SPARC32 || SPARC64
+ help
+ Say Y to build a console driver for Sun machines that uses the
+ terminal emulation built into their console PROMS.
+
+config DUMMY_CONSOLE
+ bool
+ depends on !PROM_CONSOLE=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y || !IODC_CONSOLE && GSC_PS2
+ default y
+
+config FRAMEBUFFER_CONSOLE
+ tristate "Framebuffer Console support"
+ depends on FB
+
+config PCI_CONSOLE
+ bool
+ depends on FRAMEBUFFER_CONSOLE
+ default y
+
+config FBCON_ADVANCED
+ bool "Advanced low level driver options"
+ depends on FRAMEBUFFER_CONSOLE
+ ---help---
+ The frame buffer console uses character drawing routines that are
+ tailored to the specific organization of pixels in the memory of
+ your graphics hardware. These are called the low level frame buffer
+ console drivers. Note that they are used for text console output
+ only; they are NOT needed for graphical applications.
+
+ If you say N here, the needed low level drivers are automatically
+ enabled, depending on what frame buffer devices you selected above.
+ This is recommended for most users.
+
+ If you say Y here, you have more fine-grained control over which low
+ level drivers are enabled. You can e.g. leave out low level drivers
+ for color depths you do not intend to use for text consoles.
+
+ Low level frame buffer console drivers can be modules ( = code which
+ can be inserted and removed from the running kernel whenever you
+ want). The modules will be called fbcon-*.o. If you want to compile
+ (some of) them as modules, read <file:Documentation/modules.txt>.
+
+ If unsure, say N.
+
+# Guess what we need
+config FBCON_STI
+ tristate
+ depends on !FBCON_ADVANCED && FRAMEBUFFER_CONSOLE && FB_STI
+ default y
+
+config FONTWIDTH8_ONLY
+ bool "Support only 8 pixels wide fonts"
+ depends on FRAMEBUFFER_CONSOLE
+ help
+ Answer Y here will make the kernel provide only the 8x8 fonts (these
+ are the less readable).
+
+ If unsure, say N.
+
+config FONT_SUN8x16
+ bool "Sparc console 8x16 font"
+ depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+ help
+ This is the high resolution console font for Sun machines. Say Y.
+
+config FONT_SUN12x22
+ bool "Sparc console 12x22 font (not supported by all drivers)"
+ depends on FRAMEBUFFER_CONSOLE && !FONTWIDTH8_ONLY && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+ help
+ This is the high resolution console font for Sun machines with very
+ big letters (like the letters used in the SPARC PROM). If the
+ standard font is unreadable for you, say Y, otherwise say N.
+
+config FONTS
+ bool "Select other fonts" if SPARC32 || SPARC64
+ depends on FRAMEBUFFER_CONSOLE
+ help
+ Say Y here if you would like to use fonts other than the default
+ your frame buffer console usually use.
+
+ Note that the answer to this question won't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about foreign fonts.
+
+ If unsure, say N (the default choices are safe).
+
+config FONTS
+ prompt "Select compiled-in fonts"
+ depends on FRAMEBUFFER_CONSOLE && !SPARC32 && !SPARC64
+
+config FONT_8x8
+ bool "VGA 8x8 font" if FONTS
+ depends on FRAMEBUFFER_CONSOLE
+ default y if !SPARC32 && !SPARC64 && !FONTS
+ help
+ This is the "high resolution" font for the VGA frame buffer (the one
+ provided by the text console 80x50 (and higher) modes).
+
+ Note that this is a poor quality font. The VGA 8x16 font is quite a
+ lot more readable.
+
+ Given the resolution provided by the frame buffer device, answer N
+ here is safe.
+
+config FONT_8x16
+ bool "VGA 8x16 font" if FONTS
+ depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y
+ default y if !SPARC32 && !SPARC64 && !FONTS
+ help
+ This is the "high resolution" font for the VGA frame buffer (the one
+ provided by the VGA text console 80x25 mode.
+
+ If unsure, say Y.
+
+config FONT_6x11
+ bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
+ depends on FRAMEBUFFER_CONSOLE && !FONTWIDTH8_ONLY
+ default y if !SPARC32 && !SPARC64 && !FONTS && MAC
+ help
+ Small console font with Macintosh-style high-half glyphs. Some Mac
+ framebuffer drivers don't support this one at all.
+
+config FONT_PEARL_8x8
+ bool "Pearl (old m68k) console 8x8 font" if FONTS
+ depends on FRAMEBUFFER_CONSOLE
+ default y if !SPARC32 && !SPARC64 && !FONTS && AMIGA
+ help
+ Small console font with PC-style control-character and high-half
+ glyphs.
+
+config FONT_ACORN_8x8
+ bool "Acorn console 8x8 font" if FONTS
+ depends on FRAMEBUFFER_CONSOLE
+ default y if !SPARC32 && !SPARC64 && !FONTS && ARM && ARCH_ACORN
+ help
+ Small console font with PC-style control characters and high-half
+ glyphs.
+
+config FONT_MINI_4x6
+ bool "Mini 4x6 font"
+ depends on !SPARC32 && !SPARC64 && FONTS
+
+endmenu
+
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
new file mode 100644
index 000000000000..0e5097734e76
--- /dev/null
+++ b/drivers/video/console/Makefile
@@ -0,0 +1,61 @@
+# Makefile for the Linux graphics to console drivers.
+# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
+# Rewritten to use lists instead of if-statements.
+
+# All of the (potential) objects that export symbols.
+# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
+
+export-objs := fbcon.o fonts.o
+
+# Font handling
+font-objs := fonts.o
+
+ifeq ($(CONFIG_FONT_SUN8x16),y)
+ font-objs += font_sun8x16.o
+endif
+ifeq ($(CONFIG_FONT_SUN12x22),y)
+ font-objs += font_sun12x22.o
+endif
+ifeq ($(CONFIG_FONT_8x8),y)
+ font-objs += font_8x8.o
+endif
+ifeq ($(CONFIG_FONT_8x16),y)
+ font-objs += font_8x16.o
+endif
+ifeq ($(CONFIG_FONT_6x11),y)
+ font-objs += font_6x11.o
+endif
+ifeq ($(CONFIG_FONT_PEARL_8x8),y)
+ font-objs += font_pearl_8x8.o
+endif
+ifeq ($(CONFIG_FONT_ACORN_8x8),y)
+ font-objs += font_acorn_8x8.o
+endif
+ifeq ($(CONFIG_FONT_MINI_4x6),y)
+ font-objs += font_mini_4x6.o
+endif
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o
+obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o
+obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
+obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o
+obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
+obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
+obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o font.o
+
+# Generic Low Level Drivers
+
+obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
+
+# Files generated that shall be removed upon make clean
+clean-files := promcon_tbl.c
+
+include $(TOPDIR)/Rules.make
+
+$(obj)/promcon_tbl.c: $(src)/prom.uni
+ $(objtree)/scripts/conmakehash $< | \
+ sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
+ -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+
diff --git a/drivers/video/dummycon.c b/drivers/video/console/dummycon.c
index 82686f4b2633..ba38857c8e3e 100644
--- a/drivers/video/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -9,7 +9,6 @@
#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>
@@ -33,14 +32,14 @@ static const char *dummycon_startup(void)
return "dummy device";
}
-static void dummycon_init(struct vc_data *conp, int init)
+static void dummycon_init(struct vc_data *vc, int init)
{
- conp->vc_can_do_color = 1;
+ vc->vc_can_do_color = 1;
if (init) {
- conp->vc_cols = DUMMY_COLUMNS;
- conp->vc_rows = DUMMY_ROWS;
+ vc->vc_cols = DUMMY_COLUMNS;
+ vc->vc_rows = DUMMY_ROWS;
} else
- vc_resize_con(DUMMY_ROWS, DUMMY_COLUMNS, conp->vc_num);
+ vc_resize(vc->vc_num, DUMMY_COLUMNS, DUMMY_ROWS);
}
static int dummycon_dummy(void)
diff --git a/drivers/video/fbcon-sti.c b/drivers/video/console/fbcon-sti.c
index ef6b9a49d119..35015f8c5592 100644
--- a/drivers/video/fbcon-sti.c
+++ b/drivers/video/console/fbcon-sti.c
@@ -17,42 +17,18 @@
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/delay.h>
+#include <asm/gsc.h> /* for gsc_read/write */
#include <asm/types.h>
#include <video/fbcon.h>
#include <video/fbcon-mfb.h>
-#include "sti.h"
-
-/* Translate an address as it would be found in a 2048x2048x1 bit frame
- * buffer into a logical address Artist actually expects. Addresses fed
- * into Artist look like this:
- * fixed Y X
- * FFFF FFFF LLLL LLLL LLLC CCCC CCCC CC00
- *
- * our "RAM" addresses look like this:
- *
- * FFFF FFFF 0000 0LLL LLLL LLLL CCCC CCCC [CCC]
- *
- * */
+#include "../sticore.h"
static inline u32
ram2log(void * addr)
{
- u32 a = (unsigned long) addr;
- u32 r;
-
-#if 0
- r = a & 0xff000000; /* fixed part */
- r += ((a & 0x000000ff) << 5);
- r += ((a & 0x00ffff00) << 3);
-#else
- r = a & 0xff000000; /* fixed part */
- r += ((a & 0x000000ff) << 5);
- r += ((a & 0x0007ff00) << 5);
-#endif
-
- return r;
+ return (unsigned long) addr;
}
/* All those functions need better names. */
@@ -74,30 +50,6 @@ memcpy_fromhp_tohp(void *dest, void *src, int count)
}
}
-static void
-memcpy_tohp(void *dest, void *src, int count)
-{
- unsigned long d = (unsigned long) dest;
- u32 *s = (u32 *)src;
-
- count += 3;
- count &= ~3; /* XXX */
-
- d = ram2log(dest);
-
- while(count) {
- count--;
- gsc_writel(*s++, d);
- d += 32*4;
- }
-}
-
-static void
-memcopy_fromhp(void *dest, void *src, int count)
-{
- /* FIXME */
- printk("uhm ...\n");
-}
static void
memset_tohp(void *dest, u32 word, int count)
@@ -139,10 +91,11 @@ writeb_hp(u8 b, void *dst)
static void
fbcon_sti_setup(struct display *p)
{
- if (p->line_length)
- p->next_line = p->line_length;
- else
+ /* in kernel 2.5 the value of sadly line_length disapeared */
+ if (p->var.xres_virtual /*line_length*/)
p->next_line = p->var.xres_virtual>>3;
+ else
+ p->next_line = 2048; /* default STI value */
p->next_plane = 0;
}
@@ -152,7 +105,7 @@ fbcon_sti_bmove(struct display *p, int sy, int sx,
int height, int width)
{
#if 0 /* Unfortunately, still broken */
- sti_bmove(&default_sti /* FIXME */, sy, sx, dy, dx, height, width);
+ sti_bmove(default_sti /* FIXME */, sy, sx, dy, dx, height, width);
#else
u8 *src, *dest;
u_int rows;
@@ -285,7 +238,6 @@ static void fbcon_sti_revc(struct display *p,
u8 *dest, d;
u_int rows;
-
dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
for (rows = fontheight(p); rows--; dest += p->next_line) {
d = readb_hp(dest);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
new file mode 100644
index 000000000000..c00f5d395afb
--- /dev/null
+++ b/drivers/video/console/fbcon.c
@@ -0,0 +1,2843 @@
+/*
+ * linux/drivers/video/fbcon.c -- Low level frame buffer based console driver
+ *
+ * Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * This file is based on the original Amiga console driver (amicon.c):
+ *
+ * Copyright (C) 1993 Hamish Macdonald
+ * Greg Harp
+ * Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
+ *
+ * with work by William Rucklidge (wjr@cs.cornell.edu)
+ * Geert Uytterhoeven
+ * Jes Sorensen (jds@kom.auc.dk)
+ * Martin Apel
+ *
+ * and on the original Atari console driver (atacon.c):
+ *
+ * Copyright (C) 1993 Bjoern Brauel
+ * Roman Hodek
+ *
+ * with work by Guenther Kelleter
+ * 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
+ * and software scrollback added by
+ * Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ * Random hacking by Martin Mares <mj@ucw.cz>
+ *
+ * 2001 - Documented with DocBook
+ * - Brad Douglas <brad@neruo.com>
+ *
+ * The low level operations for the various display memory organizations are
+ * now in separate source files.
+ *
+ * Currently the following organizations are supported:
+ *
+ * o afb Amiga bitplanes
+ * o cfb{2,4,8,16,24,32} Packed pixels
+ * 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)
+ *
+ *
+ * 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.
+ */
+
+#undef FBCONDEBUG
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/delay.h> /* MSch: for IRQ probe */
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/slab.h>
+#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>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#ifdef CONFIG_AMIGA
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+#include <asm/atariints.h>
+#endif
+#ifdef CONFIG_MAC
+#include <asm/macints.h>
+#endif
+#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"
+#include "font.h"
+
+#ifdef FBCONDEBUG
+# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+# define DPRINTK(fmt, args...)
+#endif
+
+#define LOGO_H 80
+#define LOGO_W 80
+#define LOGO_LINE (LOGO_W/8)
+
+struct display fb_display[MAX_NR_CONSOLES];
+char con2fb_map[MAX_NR_CONSOLES];
+static int logo_lines;
+static int logo_shown = -1;
+/* Software scrollback */
+int fbcon_softback_size = 32768;
+static unsigned long softback_buf, softback_curr;
+static unsigned long softback_in;
+static unsigned long softback_top, softback_end;
+static int softback_lines;
+/* console mappings */
+static int first_fb_vc;
+static int last_fb_vc = MAX_NR_CONSOLES - 1;
+static int fbcon_is_default = 1;
+
+#define REFCOUNT(fd) (((int *)(fd))[-1])
+#define FNTSIZE(fd) (((int *)(fd))[-2])
+#define FNTCHARCNT(fd) (((int *)(fd))[-3])
+#define FNTSUM(fd) (((int *)(fd))[-4])
+#define FONT_EXTRA_WORDS 4
+
+#define CM_SOFTBACK (8)
+
+#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
+
+static void fbcon_free_font(struct display *);
+static int fbcon_set_origin(struct vc_data *);
+static int cursor_drawn;
+
+#define CURSOR_DRAW_DELAY (1)
+
+/* # VBL ints between cursor state changes */
+#define ARM_CURSOR_BLINK_RATE (10)
+#define AMIGA_CURSOR_BLINK_RATE (20)
+#define ATARI_CURSOR_BLINK_RATE (42)
+#define MAC_CURSOR_BLINK_RATE (32)
+#define DEFAULT_CURSOR_BLINK_RATE (20)
+
+static int vbl_cursor_cnt;
+static int cursor_on;
+static int cursor_blink_rate;
+
+static inline void cursor_undrawn(void)
+{
+ vbl_cursor_cnt = 0;
+ cursor_drawn = 0;
+}
+
+#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
+
+/*
+ * Interface used by the world
+ */
+
+static const char *fbcon_startup(void);
+static void fbcon_init(struct vc_data *vc, int init);
+static void fbcon_deinit(struct vc_data *vc);
+static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+ int width);
+static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos);
+static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+ int count, int ypos, int xpos);
+static void fbcon_cursor(struct vc_data *vc, int mode);
+static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ int count);
+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
+ int height, int width);
+static int fbcon_switch(struct vc_data *vc);
+static int fbcon_blank(struct vc_data *vc, int blank);
+static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op);
+static int fbcon_set_palette(struct vc_data *vc, unsigned char *table);
+static int fbcon_scrolldelta(struct vc_data *vc, int lines);
+
+
+/*
+ * Internal routines
+ */
+
+static int fbcon_changevar(int con);
+static void fbcon_set_display(int con, int init, int logo);
+static __inline__ int real_y(struct display *p, int ypos);
+static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
+static __inline__ void updatescrollmode(struct display *p, struct vc_data *vc);
+static __inline__ void ywrap_up(struct display *p, struct vc_data *vc,
+ int count);
+static __inline__ void ywrap_down(struct display *p, struct vc_data *vc,
+ int count);
+static __inline__ void ypan_up(struct display *p, struct vc_data *vc,
+ int count);
+static __inline__ void ypan_down(struct display *p, struct vc_data *vc,
+ int count);
+static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy,
+ int dx, int height, int width, u_int y_break);
+
+static int fbcon_show_logo(void);
+
+#ifdef CONFIG_MAC
+/*
+ * On the Macintoy, there may or may not be a working VBL int. We need to probe
+ */
+static int vbl_detected;
+
+static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
+{
+ vbl_detected++;
+}
+#endif
+
+static void cursor_timer_handler(unsigned long dev_addr);
+
+static struct timer_list cursor_timer =
+ TIMER_INITIALIZER(cursor_timer_handler, 0, 0);
+
+static void cursor_timer_handler(unsigned long dev_addr)
+{
+ fbcon_vbl_handler(0, NULL, NULL);
+ cursor_timer.expires = jiffies + HZ / 50;
+ add_timer(&cursor_timer);
+}
+
+int __init fb_console_setup(char *this_opt)
+{
+ int unit, i, j;
+ char *options;
+
+ if (!this_opt || !*this_opt)
+ return 0;
+
+ while ((options = strsep(&this_opt, ",")) != NULL) {
+ if (!strncmp(options, "font:", 5)) {
+ for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
+ strcpy(fb_display[unit].fontname,
+ options + 5);
+ }
+
+ if (!strncmp(options, "scrollback:", 11)) {
+ options += 11;
+ if (*options) {
+ fbcon_softback_size = simple_strtoul(options, &options, 0);
+ if (*options == 'k' || *options == 'K') {
+ fbcon_softback_size *= 1024;
+ options++;
+ }
+ if (*options != ',')
+ return 0;
+ options++;
+ } else
+ return 0;
+ }
+
+ if (!strncmp(options, "map:", 4)) {
+ options += 4;
+ if (*options)
+ for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) {
+ if (!options[j])
+ j = 0;
+ con2fb_map[i] = (options[j++]-'0') % FB_MAX;
+ }
+ return 0;
+ }
+
+ if (!strncmp(options, "vc:", 3)) {
+ options += 3;
+ if (*options)
+ first_fb_vc = simple_strtoul(options, &options, 10) - 1;
+ if (first_fb_vc < 0)
+ first_fb_vc = 0;
+ if (*options++ == '-')
+ last_fb_vc = simple_strtoul(options, &options, 10) - 1;
+ fbcon_is_default = 0;
+ }
+ }
+ return 0;
+}
+
+__setup("fbcon=", fb_console_setup);
+
+void gen_set_disp(int con, struct fb_info *info)
+{
+ struct display *display = fb_display + con;
+
+ display->can_soft_blank = info->fbops->fb_blank ? 1 : 0;
+ display->scrollmode = SCROLL_YNOMOVE;
+ fbcon_changevar(con);
+ return;
+}
+
+/**
+ * set_con2fb_map - map console to frame buffer device
+ * @unit: virtual console number to map
+ * @newidx: frame buffer index to map virtual console to
+ *
+ * Maps a virtual console @unit to a frame buffer device
+ * @newidx.
+ *
+ */
+
+void set_con2fb_map(int unit, int newidx)
+{
+ int oldidx = con2fb_map[unit];
+ struct fb_info *oldfb, *newfb;
+ struct vc_data *vc;
+ char *fontdata;
+ int userfont;
+
+ if (newidx != con2fb_map[unit]) {
+ oldfb = registered_fb[oldidx];
+ newfb = registered_fb[newidx];
+ if (!try_module_get(newfb->fbops->owner))
+ return;
+ if (newfb->fbops->fb_open
+ && newfb->fbops->fb_open(newfb, 0)) {
+ module_put(newfb->fbops->owner);
+ return;
+ }
+ if (oldfb->fbops->fb_release)
+ oldfb->fbops->fb_release(oldfb, 0);
+ module_put(oldfb->fbops->owner);
+ vc = fb_display[unit].conp;
+ fontdata = fb_display[unit].fontdata;
+ userfont = fb_display[unit].userfont;
+ con2fb_map[unit] = newidx;
+
+ fb_display[unit].conp = vc;
+ fb_display[unit].fontdata = fontdata;
+ fb_display[unit].userfont = userfont;
+ fb_display[unit].fb_info = newfb;
+ gen_set_disp(unit, newfb);
+ /* tell console var has changed */
+ fbcon_changevar(unit);
+ }
+}
+
+/*
+ * Accelerated handlers.
+ */
+void accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
+ int height, int width)
+{
+ struct fb_info *info = p->fb_info;
+ struct vc_data *vc = p->conp;
+ struct fb_copyarea area;
+
+ area.sx = sx * vc->vc_font.width;
+ area.sy = sy * vc->vc_font.height;
+ area.dx = dx * vc->vc_font.width;
+ area.dy = dy * vc->vc_font.height;
+ area.height = height * vc->vc_font.height;
+ area.width = width * vc->vc_font.height;
+
+ info->fbops->fb_copyarea(info, &area);
+}
+
+void accel_clear(struct vc_data *vc, struct display *p, int sy,
+ int sx, int height, int width)
+{
+ struct fb_info *info = p->fb_info;
+ struct fb_fillrect region;
+
+ region.color = attr_bgcol_ec(p, vc);
+ region.dx = sx * vc->vc_font.width;
+ region.dy = sy * vc->vc_font.height;
+ region.width = width * vc->vc_font.width;
+ region.height = height * vc->vc_font.height;
+ region.rop = ROP_COPY;
+
+ info->fbops->fb_fillrect(info, &region);
+}
+
+void accel_putcs(struct vc_data *vc, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
+{
+ struct fb_info *info = p->fb_info;
+ unsigned short charmask = p->charmask;
+ unsigned int width = ((vc->vc_font.width + 7)/8);
+ unsigned int cellsize = vc->vc_font.height * width;
+ struct fb_image image;
+ u16 c = scr_readw(s);
+ static u8 pixmap[8192];
+
+ image.fg_color = attr_fgcol(p, c);
+ image.bg_color = attr_bgcol(p, c);
+ image.dx = xx * vc->vc_font.width;
+ image.dy = yy * vc->vc_font.height;
+ image.height = vc->vc_font.height;
+ image.depth = 1;
+
+/* pixmap = kmalloc((info->var.bits_per_pixel + 7) >> 3 *
+ vc->vc_font.height, GFP_KERNEL);
+*/
+
+ if (!(vc->vc_font.width & 7) && pixmap != NULL) {
+ unsigned int pitch = width * count, i, j;
+ char *src, *dst, *dst0;
+
+ dst0 = pixmap;
+ image.width = vc->vc_font.width * count;
+ image.data = pixmap;
+ while (count--) {
+ src = p->fontdata + (scr_readw(s++) & charmask) * cellsize;
+ dst = dst0;
+ for (i = image.height; i--; ) {
+ for (j = 0; j < width; j++)
+ dst[j] = *src++;
+ dst += pitch;
+ }
+ dst0 += width;
+ }
+ info->fbops->fb_imageblit(info, &image);
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+ } else {
+ image.width = vc->vc_font.width;
+ while (count--) {
+ image.data = p->fontdata +
+ (scr_readw(s++) & charmask) * vc->vc_font.height * width;
+ info->fbops->fb_imageblit(info, &image);
+ image.dx += vc->vc_font.width;
+ }
+ }
+ /*
+ if (pixmap);
+ kfree(pixmap);
+ */
+}
+
+void accel_clear_margins(struct vc_data *vc, struct display *p,
+ int bottom_only)
+{
+ struct fb_info *info = p->fb_info;
+ unsigned int cw = vc->vc_font.width;
+ unsigned int ch = vc->vc_font.height;
+ unsigned int rw = info->var.xres % cw;
+ unsigned int bh = info->var.yres % ch;
+ unsigned int rs = info->var.xres - rw;
+ unsigned int bs = info->var.yres - bh;
+ struct fb_fillrect region;
+
+ region.color = attr_bgcol_ec(p, vc);
+ region.rop = ROP_COPY;
+
+ if (rw & !bottom_only) {
+ region.dx = info->var.xoffset + rs;
+ region.dy = 0;
+ region.width = rw;
+ region.height = info->var.yres_virtual;
+ info->fbops->fb_fillrect(info, &region);
+ }
+
+ if (bh) {
+ region.dx = info->var.xoffset;
+ region.dy = info->var.yoffset + bs;
+ region.width = rs;
+ region.height = bh;
+ info->fbops->fb_fillrect(info, &region);
+ }
+}
+
+void accel_cursor(struct display *p, int flags, int xx, int yy)
+{
+ static char mask[64], image[64], *dest;
+ struct vc_data *vc = p->conp;
+ static int fgcolor, bgcolor, shape, width, height;
+ struct fb_info *info = p->fb_info;
+ struct fb_cursor cursor;
+ char *font;
+ int c;
+
+ cursor.set = FB_CUR_SETPOS;
+
+ if (width != vc->vc_font.width || height != vc->vc_font.height) {
+ width = vc->vc_font.width;
+ height = vc->vc_font.height;
+ cursor.set |= FB_CUR_SETSIZE;
+ }
+
+ if ((vc->vc_cursor_type & 0x0f) != shape) {
+ shape = vc->vc_cursor_type & 0x0f;
+ cursor.set |= FB_CUR_SETSHAPE;
+ }
+
+ c = scr_readw((u16 *) vc->vc_pos);
+
+ if (fgcolor != (int) attr_fgcol(p, c) ||
+ bgcolor != (int) attr_bgcol(p, c)) {
+ fgcolor = (int) attr_fgcol(p, c);
+ bgcolor = (int) attr_bgcol(p, c);
+ cursor.set |= FB_CUR_SETCMAP;
+ }
+ c &= p->charmask;
+ font = p->fontdata + (c * ((width + 7) / 8) * height);
+ if (font != dest) {
+ dest = font;
+ cursor.set |= FB_CUR_SETDEST;
+ }
+
+ if (flags & FB_CUR_SETCUR)
+ cursor.enable = 1;
+ else
+ cursor.enable = 0;
+
+ if (cursor.set & FB_CUR_SETSIZE) {
+ memset(image, 0xff, 64);
+ cursor.set |= FB_CUR_SETSHAPE;
+ }
+
+ if (cursor.set & FB_CUR_SETSHAPE) {
+ int w, cur_height, size, i = 0;
+
+ w = (width + 7) / 8;
+
+ switch (shape) {
+ case CUR_NONE:
+ cur_height = 0;
+ break;
+ case CUR_UNDERLINE:
+ cur_height = (height < 10) ? 1 : 2;
+ break;
+ case CUR_LOWER_THIRD:
+ cur_height = height/3;
+ break;
+ case CUR_LOWER_HALF:
+ cur_height = height/2;
+ break;
+ case CUR_TWO_THIRDS:
+ cur_height = (height * 2)/3;
+ break;
+ case CUR_BLOCK:
+ default:
+ cur_height = height;
+ break;
+ }
+
+ size = (height - cur_height) * w;
+ while (size--)
+ mask[i++] = 0;
+ size = cur_height * w;
+ while (size--)
+ mask[i++] = 0xff;
+ }
+
+ cursor.image.width = width;
+ cursor.image.height = height;
+ cursor.image.dx = xx * width;
+ cursor.image.dy = yy * height;
+ cursor.image.depth = 1;
+ cursor.image.data = image;
+ cursor.image.bg_color = bgcolor;
+ cursor.image.fg_color = fgcolor;
+ cursor.mask = mask;
+ cursor.dest = dest;
+ cursor.rop = ROP_XOR;
+
+ if (info->fbops->fb_cursor)
+ info->fbops->fb_cursor(info, &cursor);
+}
+
+/*
+ * Low Level Operations
+ */
+/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */
+
+static const char *fbcon_startup(void)
+{
+ const char *display_desc = "frame buffer device";
+ struct font_desc *font = NULL;
+ struct module *owner;
+ struct fb_info *info;
+ struct vc_data *vc;
+ static int done = 0;
+ int irqres = 1;
+
+ /*
+ * 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;
+
+ info = registered_fb[num_registered_fb-1];
+ if (!info) return NULL;
+ info->currcon = -1;
+
+ owner = info->fbops->owner;
+ if (!try_module_get(owner))
+ return NULL;
+ if (info->fbops->fb_open && info->fbops->fb_open(info, 0))
+ module_put(owner);
+
+ if (info->fix.type != FB_TYPE_TEXT) {
+ if (fbcon_softback_size) {
+ if (!softback_buf) {
+ softback_buf =
+ (unsigned long)
+ kmalloc(fbcon_softback_size,
+ GFP_KERNEL);
+ if (!softback_buf) {
+ fbcon_softback_size = 0;
+ softback_top = 0;
+ }
+ }
+ } else {
+ if (softback_buf) {
+ kfree((void *) softback_buf);
+ softback_buf = 0;
+ softback_top = 0;
+ }
+ }
+ if (softback_buf)
+ softback_in = softback_top = softback_curr =
+ softback_buf;
+ softback_lines = 0;
+ }
+
+ font = get_default_font(info->var.xres, info->var.yres);
+
+ vc = (struct vc_data *) kmalloc(sizeof(struct vc_data), GFP_ATOMIC);
+
+ /* Setup default font */
+ vc->vc_font.data = font->data;
+ vc->vc_font.width = font->width;
+ vc->vc_font.height = font->height;
+ vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
+
+ vc->vc_cols = info->var.xres/vc->vc_font.width;
+ vc->vc_rows = info->var.yres/vc->vc_font.height;
+
+ /* We trust the mode the driver supplies. */
+ if (info->fbops->fb_set_par)
+ info->fbops->fb_set_par(info);
+
+ DPRINTK("mode: %s\n", info->fix.id);
+ DPRINTK("visual: %d\n", info->fix.visual);
+ DPRINTK("res: %dx%d-%d\n", info->var.xres,
+ info->var.yres,
+ info->var.bits_per_pixel);
+
+ info->display_fg = vc;
+
+#ifdef CONFIG_AMIGA
+ if (MACH_IS_AMIGA) {
+ cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
+ irqres = request_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0,
+ "console/cursor", fbcon_vbl_handler);
+ }
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+ if (MACH_IS_ATARI) {
+ cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
+ irqres =
+ request_irq(IRQ_AUTO_4, fbcon_vbl_handler,
+ IRQ_TYPE_PRIO, "console/cursor",
+ fbcon_vbl_handler);
+ }
+#endif /* CONFIG_ATARI */
+
+#ifdef CONFIG_MAC
+ /*
+ * On a Macintoy, the VBL interrupt may or may not be active.
+ * As interrupt based cursor is more reliable and race free, we
+ * probe for VBL interrupts.
+ */
+ if (MACH_IS_MAC) {
+ int ct = 0;
+ /*
+ * Probe for VBL: set temp. handler ...
+ */
+ irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_detect, 0,
+ "console/cursor", fbcon_vbl_detect);
+ vbl_detected = 0;
+
+ /*
+ * ... and spin for 20 ms ...
+ */
+ while (!vbl_detected && ++ct < 1000)
+ udelay(20);
+
+ if (ct == 1000)
+ printk
+ ("fbcon_startup: No VBL detected, using timer based cursor.\n");
+
+ free_irq(IRQ_MAC_VBL, fbcon_vbl_detect);
+
+ if (vbl_detected) {
+ /*
+ * interrupt based cursor ok
+ */
+ cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
+ irqres =
+ request_irq(IRQ_MAC_VBL, fbcon_vbl_handler, 0,
+ "console/cursor",
+ fbcon_vbl_handler);
+ } else {
+ /*
+ * VBL not detected: fall through, use timer based cursor
+ */
+ irqres = 1;
+ }
+ }
+#endif /* CONFIG_MAC */
+
+#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
+ cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
+ 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;
+ add_timer(&cursor_timer);
+ }
+ return display_desc;
+}
+
+static void fbcon_init(struct vc_data *vc, int init)
+{
+ int unit = vc->vc_num;
+ struct fb_info *info;
+
+ /* on which frame buffer will we open this console? */
+ info = registered_fb[(int) con2fb_map[unit]];
+
+ gen_set_disp(unit, info);
+ fb_display[unit].conp = vc;
+ fb_display[unit].fb_info = info;
+
+ fbcon_set_display(unit, init, !init);
+}
+
+
+static void fbcon_deinit(struct vc_data *vc)
+{
+ int unit = vc->vc_num;
+ struct display *p = &fb_display[unit];
+
+ fbcon_free_font(p);
+ p->conp = 0;
+}
+
+#define fontwidthvalid(p,w) ((p)->fontwidthmask & FONTWIDTH(w))
+
+static int fbcon_changevar(int con)
+{
+ if (fb_display[con].conp) {
+ struct display *p = &fb_display[con];
+ struct fb_info *info = p->fb_info;
+ struct vc_data *vc = p->conp;
+ int nr_rows, nr_cols;
+ int old_rows, old_cols;
+ unsigned short *save = NULL, *q;
+ int i, charcnt = 256;
+ struct font_desc *font;
+
+ info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ if (i != con && fb_display[i].fb_info == info &&
+ fb_display[i].conp && fb_display[i].fontdata)
+ break;
+
+ fbcon_free_font(p);
+ if (i < MAX_NR_CONSOLES) {
+ struct display *q = &fb_display[i];
+ struct vc_data *tmp = vc_cons[i].d;
+
+ if (fontwidthvalid(p, vc->vc_font.width)) {
+ /* If we are not the first console on this
+ fb, copy the font from that console */
+ tmp->vc_font.width = vc->vc_font.width;
+ tmp->vc_font.height = vc->vc_font.height;
+ p->fontdata = q->fontdata;
+ p->userfont = q->userfont;
+ if (p->userfont) {
+ REFCOUNT(p->fontdata)++;
+ charcnt = FNTCHARCNT(p->fontdata);
+ }
+ con_copy_unimap(con, i);
+ }
+ }
+
+ if (!p->fontdata) {
+ if (!p->fontname[0] || !(font = find_font(p->fontname)))
+ font = get_default_font(info->var.xres,
+ info->var.yres);
+ vc->vc_font.width = font->width;
+ vc->vc_font.height = font->height;
+ p->fontdata = font->data;
+ }
+
+#ifdef FONTWIDTH8_ONLY
+ if (!fontwidthvalid(p, vc->vc_font.width)) {
+ /* ++Geert: changed from panic() to `correct and continue' */
+ printk(KERN_ERR
+ "fbcon_set_display: No support for fontwidth %d\n",
+ vc->vc_font.width);
+ }
+#endif
+ updatescrollmode(p, vc);
+
+ old_cols = vc->vc_cols;
+ old_rows = vc->vc_rows;
+
+ nr_cols = info->var.xres / vc->vc_font.width;
+ nr_rows = info->var.yres / vc->vc_font.height;
+
+ /*
+ * ++guenther: console.c:vc_allocate() relies on initializing
+ * vc_{cols,rows}, but we must not set those if we are only
+ * resizing the console.
+ */
+ p->vrows = info->var.yres_virtual / vc->vc_font.height;
+ if ((info->var.yres % vc->vc_font.height) &&
+ (info->var.yres_virtual % vc->vc_font.height <
+ info->var.yres % vc->vc_font.height))
+ p->vrows--;
+ vc->vc_can_do_color = info->var.bits_per_pixel != 1;
+ vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+ if (charcnt == 256) {
+ vc->vc_hi_font_mask = 0;
+ p->fgshift = 8;
+ p->bgshift = 12;
+ p->charmask = 0xff;
+ } else {
+ vc->vc_hi_font_mask = 0x100;
+ if (vc->vc_can_do_color)
+ vc->vc_complement_mask <<= 1;
+ p->fgshift = 9;
+ p->bgshift = 13;
+ p->charmask = 0x1ff;
+ }
+
+ if (vc->vc_cols != nr_cols || vc->vc_rows != nr_rows)
+ vc_resize(con, nr_cols, nr_rows);
+ else if (CON_IS_VISIBLE(vc) &&
+ vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
+ accel_clear_margins(vc, p, 0);
+ update_screen(con);
+ }
+ if (save) {
+ q = (unsigned short *) (vc->vc_origin +
+ vc->vc_size_row *
+ old_rows);
+ scr_memcpyw(q, save, logo_lines * nr_cols * 2);
+ vc->vc_y += logo_lines;
+ vc->vc_pos += logo_lines * vc->vc_size_row;
+ kfree(save);
+ }
+
+ if (con == fg_console && softback_buf) {
+ int l = fbcon_softback_size / vc->vc_size_row;
+ if (l > 5)
+ softback_end = softback_buf + l * vc->vc_size_row;
+ else {
+ /* Smaller scrollback makes no sense, and 0 would screw
+ the operation totally */
+ softback_top = 0;
+ }
+ }
+ }
+ return 0;
+}
+
+static __inline__ void updatescrollmode(struct display *p, struct vc_data *vc)
+{
+ struct fb_info *info = p->fb_info;
+
+ int m;
+ if (p->scrollmode & __SCROLL_YFIXED)
+ return;
+ if (divides(info->fix.ywrapstep, vc->vc_font.height) &&
+ divides(vc->vc_font.height, info->var.yres_virtual))
+ m = __SCROLL_YWRAP;
+ else if (divides(info->fix.ypanstep, vc->vc_font.height) &&
+ info->var.yres_virtual >= info->var.yres + vc->vc_font.height)
+ m = __SCROLL_YPAN;
+ else if (p->scrollmode & __SCROLL_YNOMOVE)
+ m = __SCROLL_YREDRAW;
+ else
+ m = __SCROLL_YMOVE;
+ p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;
+}
+
+static void fbcon_set_display(int con, int init, int logo)
+{
+ struct display *p = &fb_display[con];
+ struct fb_info *info = p->fb_info;
+ struct vc_data *vc = p->conp;
+ int nr_rows, nr_cols;
+ int old_rows, old_cols;
+ unsigned short *save = NULL, *r, *q;
+ int i, charcnt = 256;
+ struct font_desc *font;
+
+ if (con != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
+ info->fix.type == FB_TYPE_TEXT)
+ logo = 0;
+
+ info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ if (i != con && fb_display[i].fb_info == info &&
+ fb_display[i].conp && fb_display[i].fontdata)
+ break;
+
+ fbcon_free_font(p);
+ if (i < MAX_NR_CONSOLES) {
+ struct display *q = &fb_display[i];
+ struct vc_data *tmp = vc_cons[i].d;
+
+ if (fontwidthvalid(p, vc->vc_font.width)) {
+ /* If we are not the first console on this
+ fb, copy the font from that console */
+ tmp->vc_font.width = vc->vc_font.width;
+ tmp->vc_font.height = vc->vc_font.height;
+ p->fontdata = q->fontdata;
+ p->userfont = q->userfont;
+ if (p->userfont) {
+ REFCOUNT(p->fontdata)++;
+ charcnt = FNTCHARCNT(p->fontdata);
+ }
+ con_copy_unimap(con, i);
+ }
+ }
+
+ if (!p->fontdata) {
+ if (!p->fontname[0] || !(font = find_font(p->fontname)))
+ font = get_default_font(info->var.xres,
+ info->var.yres);
+ vc->vc_font.width = font->width;
+ vc->vc_font.height = font->height;
+ p->fontdata = font->data;
+ }
+
+#ifdef FONTWIDTH8_ONLY
+ if (!fontwidthvalid(p, vc->vc_font.width)) {
+ /* ++Geert: changed from panic() to `correct and continue' */
+ printk(KERN_ERR
+ "fbcon_set_display: No support for fontwidth %d\n",
+ vc->vc_font.width);
+ }
+#endif
+ updatescrollmode(p, vc);
+
+ old_cols = vc->vc_cols;
+ old_rows = vc->vc_rows;
+
+ nr_cols = info->var.xres / vc->vc_font.width;
+ nr_rows = info->var.yres / vc->vc_font.height;
+
+ if (logo) {
+ /* Need to make room for the logo */
+ int cnt;
+ int step;
+
+ logo_lines = (LOGO_H + vc->vc_font.height - 1) / vc->vc_font.height;
+ q = (unsigned short *) (vc->vc_origin +
+ vc->vc_size_row * old_rows);
+ step = logo_lines * old_cols;
+ for (r = q - logo_lines * old_cols; r < q; r++)
+ if (scr_readw(r) != vc->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, vc->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, vc->vc_size_row);
+ r -= old_cols;
+ }
+ if (!save) {
+ vc->vc_y += logo_lines;
+ vc->vc_pos += logo_lines * vc->vc_size_row;
+ }
+ }
+ scr_memsetw((unsigned short *) vc->vc_origin,
+ vc->vc_video_erase_char,
+ vc->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
+ * resizing the console.
+ */
+ if (init) {
+ vc->vc_cols = nr_cols;
+ vc->vc_rows = nr_rows;
+ }
+ p->vrows = info->var.yres_virtual / vc->vc_font.height;
+ if ((info->var.yres % vc->vc_font.height) &&
+ (info->var.yres_virtual % vc->vc_font.height <
+ info->var.yres % vc->vc_font.height))
+ p->vrows--;
+ vc->vc_can_do_color = info->var.bits_per_pixel != 1;
+ vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+ if (charcnt == 256) {
+ vc->vc_hi_font_mask = 0;
+ p->fgshift = 8;
+ p->bgshift = 12;
+ p->charmask = 0xff;
+ } else {
+ vc->vc_hi_font_mask = 0x100;
+ if (vc->vc_can_do_color)
+ vc->vc_complement_mask <<= 1;
+ p->fgshift = 9;
+ p->bgshift = 13;
+ p->charmask = 0x1ff;
+ }
+
+ if (!init) {
+ if (vc->vc_cols != nr_cols || vc->vc_rows != nr_rows)
+ vc_resize(con, nr_cols, nr_rows);
+ else if (CON_IS_VISIBLE(vc) &&
+ vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
+ accel_clear_margins(vc, p, 0);
+ update_screen(con);
+ }
+ if (save) {
+ q = (unsigned short *) (vc->vc_origin +
+ vc->vc_size_row *
+ old_rows);
+ scr_memcpyw(q, save, logo_lines * nr_cols * 2);
+ vc->vc_y += logo_lines;
+ vc->vc_pos += logo_lines * vc->vc_size_row;
+ kfree(save);
+ }
+ }
+
+ if (logo) {
+ if (logo_lines > vc->vc_bottom) {
+ logo_shown = -1;
+ printk(KERN_INFO
+ "fbcon_startup: disable boot-logo (boot-logo bigger than screen).\n");
+ } else {
+ logo_shown = -2;
+ vc->vc_top = logo_lines;
+ }
+ }
+
+ if (con == fg_console && softback_buf) {
+ int l = fbcon_softback_size / vc->vc_size_row;
+ if (l > 5)
+ softback_end = softback_buf + l * vc->vc_size_row;
+ else {
+ /* Smaller scrollback makes no sense, and 0 would screw
+ the operation totally */
+ softback_top = 0;
+ }
+ }
+}
+
+
+/* ====================================================================== */
+
+/* fbcon_XXX routines - interface used by the world
+ *
+ * This system is now divided into two levels because of complications
+ * caused by hardware scrolling. Top level functions:
+ *
+ * fbcon_bmove(), fbcon_clear(), fbcon_putc()
+ *
+ * handles y values in range [0, scr_height-1] that correspond to real
+ * screen positions. y_wrap shift means that first line of bitmap may be
+ * anywhere on this display. These functions convert lineoffsets to
+ * bitmap offsets and deal with the wrap-around case by splitting blits.
+ *
+ * fbcon_bmove_physical_8() -- These functions fast implementations
+ * fbcon_clear_physical_8() -- of original fbcon_XXX fns.
+ * fbcon_putc_physical_8() -- (fontwidth != 8) may be added later
+ *
+ * WARNING:
+ *
+ * At the moment fbcon_putc() cannot blit across vertical wrap boundary
+ * Implies should only really hardware scroll in rows. Only reason for
+ * restriction is simplicity & efficiency at the moment.
+ */
+
+static __inline__ int real_y(struct display *p, int ypos)
+{
+ int rows = p->vrows;
+
+ ypos += p->yscroll;
+ return ypos < rows ? ypos : ypos - rows;
+}
+
+
+static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+ int width)
+{
+ int unit = vc->vc_num;
+ struct display *p = &fb_display[unit];
+ u_int y_break;
+ int redraw_cursor = 0;
+
+ if (!p->can_soft_blank && console_blanked)
+ return;
+
+ if (!height || !width)
+ return;
+
+ if ((sy <= p->cursor_y) && (p->cursor_y < sy + height) &&
+ (sx <= p->cursor_x) && (p->cursor_x < sx + width)) {
+ cursor_undrawn();
+ redraw_cursor = 1;
+ }
+
+ /* Split blits that cross physical y_wrap boundary */
+
+ y_break = p->vrows - p->yscroll;
+ if (sy < y_break && sy + height - 1 >= y_break) {
+ u_int b = y_break - sy;
+ accel_clear(vc, p, real_y(p, sy), sx, b, width);
+ accel_clear(vc, p, real_y(p, sy + b), sx, height - b,
+ width);
+ } else
+ accel_clear(vc, p, real_y(p, sy), sx, height, width);
+
+ if (redraw_cursor)
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+}
+
+
+static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_info *info = p->fb_info;
+ unsigned short charmask = p->charmask;
+ unsigned int width = ((vc->vc_font.width + 7) >> 3);
+ struct fb_image image;
+ int redraw_cursor = 0;
+
+ if (!p->can_soft_blank && console_blanked)
+ return;
+
+ if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
+ return;
+
+ if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
+ cursor_undrawn();
+ redraw_cursor = 1;
+ }
+
+ image.fg_color = attr_fgcol(p, c);
+ image.bg_color = attr_bgcol(p, c);
+ image.dx = xpos * vc->vc_font.width;
+ image.dy = real_y(p, ypos) * vc->vc_font.height;
+ image.width = vc->vc_font.width;
+ image.height = vc->vc_font.height;
+ image.depth = 1;
+ image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
+
+ info->fbops->fb_imageblit(info, &image);
+
+ if (redraw_cursor)
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+}
+
+
+static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+ int count, int ypos, int xpos)
+{
+ int unit = vc->vc_num;
+ struct display *p = &fb_display[unit];
+ int redraw_cursor = 0;
+
+ if (!p->can_soft_blank && console_blanked)
+ return;
+
+ if (vt_cons[unit]->vc_mode != KD_TEXT)
+ return;
+
+ if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
+ (p->cursor_x < (xpos + count))) {
+ cursor_undrawn();
+ redraw_cursor = 1;
+ }
+ accel_putcs(vc, p, s, count, real_y(p, ypos), xpos);
+ if (redraw_cursor)
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+}
+
+static void fbcon_cursor(struct vc_data *vc, int mode)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ int y = vc->vc_y;
+
+ if (mode & CM_SOFTBACK) {
+ mode &= ~CM_SOFTBACK;
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows)
+ mode = CM_ERASE;
+ else
+ y += softback_lines;
+ }
+ } else if (softback_lines)
+ fbcon_set_origin(vc);
+
+ /* Avoid flickering if there's no real change. */
+ if (p->cursor_x == vc->vc_x && p->cursor_y == y &&
+ (mode == CM_ERASE) == !cursor_on)
+ return;
+
+ cursor_on = 0;
+ if (cursor_drawn)
+ accel_cursor(p, 0, p->cursor_x,
+ real_y(p, p->cursor_y));
+
+ p->cursor_x = vc->vc_x;
+ p->cursor_y = y;
+ p->cursor_pos = vc->vc_pos;
+
+ switch (mode) {
+ case CM_ERASE:
+ cursor_drawn = 0;
+ break;
+ case CM_MOVE:
+ case CM_DRAW:
+ if (cursor_drawn)
+ accel_cursor(p, FB_CUR_SETCUR, p->cursor_x,
+ real_y(p, p->cursor_y));
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+ cursor_on = 1;
+ break;
+ }
+
+}
+
+static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
+{
+ struct display *p;
+
+ if (!cursor_on)
+ return;
+
+ if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
+ int flag;
+
+ p = &fb_display[fg_console];
+ flag = 0;
+ if (!cursor_drawn)
+ flag = FB_CUR_SETCUR;
+ accel_cursor(p, flag, p->cursor_x,
+ real_y(p, p->cursor_y));
+ cursor_drawn ^= 1;
+ vbl_cursor_cnt = cursor_blink_rate;
+ }
+}
+
+static int scrollback_phys_max = 0;
+static int scrollback_max = 0;
+static int scrollback_current = 0;
+
+int update_var(int con, struct fb_info *info)
+{
+ int err;
+
+ if (con == info->currcon) {
+ if (info->fbops->fb_pan_display) {
+ if ((err =
+ info->fbops->fb_pan_display(&info->var,
+ info)))
+ return err;
+ }
+ }
+ return 0;
+}
+
+static __inline__ void ywrap_up(struct display *p, struct vc_data *vc,
+ int count)
+{
+ struct fb_info *info = p->fb_info;
+
+ p->yscroll += count;
+ if (p->yscroll >= p->vrows) /* Deal with wrap */
+ p->yscroll -= p->vrows;
+ info->var.xoffset = 0;
+ info->var.yoffset = p->yscroll * vc->vc_font.height;
+ info->var.vmode |= FB_VMODE_YWRAP;
+ update_var(vc->vc_num, info);
+ scrollback_max += count;
+ if (scrollback_max > scrollback_phys_max)
+ scrollback_max = scrollback_phys_max;
+ scrollback_current = 0;
+}
+
+static __inline__ void ywrap_down(struct display *p, struct vc_data *vc,
+ int count)
+{
+ struct fb_info *info = p->fb_info;
+
+ p->yscroll -= count;
+ if (p->yscroll < 0) /* Deal with wrap */
+ p->yscroll += p->vrows;
+ info->var.xoffset = 0;
+ info->var.yoffset = p->yscroll * vc->vc_font.height;
+ info->var.vmode |= FB_VMODE_YWRAP;
+ update_var(vc->vc_num, info);
+ scrollback_max -= count;
+ if (scrollback_max < 0)
+ scrollback_max = 0;
+ scrollback_current = 0;
+}
+
+static __inline__ void ypan_up(struct display *p, struct vc_data *vc,
+ int count)
+{
+ struct fb_info *info = p->fb_info;
+
+ p->yscroll += count;
+ if (p->yscroll > p->vrows - vc->vc_rows) {
+ accel_bmove(p, p->vrows - vc->vc_rows, 0, 0, 0,
+ vc->vc_rows, vc->vc_cols);
+ p->yscroll -= p->vrows - vc->vc_rows;
+ }
+ info->var.xoffset = 0;
+ info->var.yoffset = p->yscroll * vc->vc_font.height;
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+ update_var(vc->vc_num, info);
+ accel_clear_margins(vc, p, 1);
+ scrollback_max += count;
+ if (scrollback_max > scrollback_phys_max)
+ scrollback_max = scrollback_phys_max;
+ scrollback_current = 0;
+}
+
+
+static __inline__ void ypan_down(struct display *p, struct vc_data *vc,
+ int count)
+{
+ struct fb_info *info = p->fb_info;
+
+ p->yscroll -= count;
+ if (p->yscroll < 0) {
+ accel_bmove(p, 0, 0, p->vrows - vc->vc_rows, 0,
+ vc->vc_rows, vc->vc_cols);
+ p->yscroll += p->vrows - vc->vc_rows;
+ }
+ info->var.xoffset = 0;
+ info->var.yoffset = p->yscroll * vc->vc_font.height;
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+ update_var(vc->vc_num, info);
+ accel_clear_margins(vc, p, 1);
+ scrollback_max -= count;
+ if (scrollback_max < 0)
+ scrollback_max = 0;
+ scrollback_current = 0;
+}
+
+static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,
+ long delta)
+{
+ unsigned short *d, *s;
+ unsigned long n;
+ int line = 0;
+ int count = vc->vc_rows;
+
+ d = (u16 *) softback_curr;
+ if (d == (u16 *) softback_in)
+ d = (u16 *) vc->vc_origin;
+ n = softback_curr + delta * vc->vc_size_row;
+ softback_lines -= delta;
+ if (delta < 0) {
+ if (softback_curr < softback_top && n < softback_buf) {
+ n += softback_end - softback_buf;
+ if (n < softback_top) {
+ softback_lines -=
+ (softback_top - n) / vc->vc_size_row;
+ n = softback_top;
+ }
+ } else if (softback_curr >= softback_top
+ && n < softback_top) {
+ softback_lines -=
+ (softback_top - n) / vc->vc_size_row;
+ n = softback_top;
+ }
+ } else {
+ if (softback_curr > softback_in && n >= softback_end) {
+ n += softback_buf - softback_end;
+ if (n > softback_in) {
+ n = softback_in;
+ softback_lines = 0;
+ }
+ } else if (softback_curr <= softback_in && n > softback_in) {
+ n = softback_in;
+ softback_lines = 0;
+ }
+ }
+ if (n == softback_curr)
+ return;
+ softback_curr = n;
+ s = (u16 *) softback_curr;
+ if (s == (u16 *) softback_in)
+ s = (u16 *) vc->vc_origin;
+ while (count--) {
+ unsigned short *start;
+ unsigned short *le;
+ unsigned short c;
+ int x = 0;
+ unsigned short attr = 1;
+
+ start = s;
+ le = advance_row(s, 1);
+ do {
+ c = scr_readw(s);
+ if (attr != (c & 0xff00)) {
+ attr = c & 0xff00;
+ if (s > start) {
+ accel_putcs(vc, p, start,
+ s - start,
+ real_y(p, line),
+ x);
+ x += s - start;
+ start = s;
+ }
+ }
+ if (c == scr_readw(d)) {
+ if (s > start) {
+ accel_putcs(vc, p, start,
+ s - start,
+ real_y(p, line),
+ x);
+ x += s - start + 1;
+ start = s + 1;
+ } else {
+ x++;
+ start++;
+ }
+ }
+ s++;
+ d++;
+ } while (s < le);
+ if (s > start)
+ accel_putcs(vc, p, start, s - start,
+ real_y(p, line), x);
+ line++;
+ if (d == (u16 *) softback_end)
+ d = (u16 *) softback_buf;
+ if (d == (u16 *) softback_in)
+ d = (u16 *) vc->vc_origin;
+ if (s == (u16 *) softback_end)
+ s = (u16 *) softback_buf;
+ if (s == (u16 *) softback_in)
+ s = (u16 *) vc->vc_origin;
+ }
+}
+
+static void fbcon_redraw(struct vc_data *vc, struct display *p,
+ int line, int count, int offset)
+{
+ unsigned short *d = (unsigned short *)
+ (vc->vc_origin + vc->vc_size_row * line);
+ unsigned short *s = d + offset;
+
+ while (count--) {
+ unsigned short *start = s;
+ unsigned short *le = advance_row(s, 1);
+ 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) {
+ accel_putcs(vc, p, start,
+ s - start,
+ real_y(p, line),
+ x);
+ x += s - start;
+ start = s;
+ }
+ }
+ if (c == scr_readw(d)) {
+ if (s > start) {
+ accel_putcs(vc, p, start,
+ s - start,
+ real_y(p, line),
+ x);
+ x += s - start + 1;
+ start = s + 1;
+ } else {
+ x++;
+ start++;
+ }
+ }
+ scr_writew(c, d);
+ console_conditional_schedule();
+ s++;
+ d++;
+ } while (s < le);
+ if (s > start)
+ accel_putcs(vc, p, start, s - start,
+ real_y(p, line), x);
+ console_conditional_schedule();
+ if (offset > 0)
+ line++;
+ else {
+ line--;
+ /* NOTE: We subtract two lines from these pointers */
+ s -= vc->vc_size_row;
+ d -= vc->vc_size_row;
+ }
+ }
+}
+
+/**
+ * fbcon_redraw_clear - clear area of the screen
+ * @vc: stucture pointing to current active virtual console
+ * @p: display structure
+ * @sy: starting Y coordinate
+ * @sx: starting X coordinate
+ * @height: height of area to clear
+ * @width: width of area to clear
+ *
+ * Clears a specified area of the screen. All dimensions are in
+ * pixels.
+ *
+ */
+
+void fbcon_redraw_clear(struct vc_data *vc, struct display *p, int sy,
+ int sx, int height, int width)
+{
+ int x, y;
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ fbcon_putc(vc, ' ', sy + y, sx + x);
+}
+
+
+/**
+ * fbcon_redraw_bmove - copy area of screen to another area
+ * @p: display structure
+ * @sy: origin Y coordinate
+ * @sx: origin X coordinate
+ * @dy: destination Y coordinate
+ * @dx: destination X coordinate
+ * @h: height of area to copy
+ * @w: width of area to copy
+ *
+ * Copies an area of the screen to another area of the same screen.
+ * All dimensions are in pixels.
+ *
+ * Note that this function cannot be used together with ypan or
+ * ywrap.
+ *
+ */
+
+void fbcon_redraw_bmove(struct vc_data *vc, 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) {
+ unsigned short *d = (unsigned short *)
+ (vc->vc_origin + vc->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) {
+ accel_putcs(vc, p, start,
+ d - start, dy, x);
+ x += d - start;
+ start = d;
+ }
+ }
+ if (s >= ls && s < le && c == scr_readw(s)) {
+ if (d > start) {
+ accel_putcs(vc, p, start,
+ d - start, dy, x);
+ x += d - start + 1;
+ start = d + 1;
+ } else {
+ x++;
+ start++;
+ }
+ }
+ s++;
+ d++;
+ } while (d < le);
+ if (d > start)
+ accel_putcs(vc, p, start, d - start, dy, x);
+ sy++;
+ dy++;
+ }
+}
+
+static inline void fbcon_softback_note(struct vc_data *vc, int t,
+ int count)
+{
+ unsigned short *p;
+
+ if (vc->vc_num != fg_console)
+ return;
+ p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);
+
+ while (count) {
+ scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
+ count--;
+ p = advance_row(p, 1);
+ softback_in += vc->vc_size_row;
+ if (softback_in == softback_end)
+ softback_in = softback_buf;
+ if (softback_in == softback_top) {
+ softback_top += vc->vc_size_row;
+ if (softback_top == softback_end)
+ softback_top = softback_buf;
+ }
+ }
+ softback_curr = softback_in;
+}
+
+static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ int count)
+{
+ int unit = vc->vc_num;
+ struct display *p = &fb_display[unit];
+ int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
+
+ if (!p->can_soft_blank && console_blanked)
+ return 0;
+
+ if (!count || vt_cons[unit]->vc_mode != KD_TEXT)
+ return 0;
+
+ fbcon_cursor(vc, 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) {
+ case SM_UP:
+ if (count > vc->vc_rows) /* Maximum realistic size */
+ count = vc->vc_rows;
+ if (softback_top)
+ fbcon_softback_note(vc, t, count);
+ if (logo_shown >= 0)
+ goto redraw_up;
+ switch (p->scrollmode & __SCROLL_YMASK) {
+ case __SCROLL_YMOVE:
+ accel_bmove(p, t + count, 0, t, 0,
+ b - t - count, vc->vc_cols);
+ accel_clear(vc, p, b - count, 0, count,
+ vc->vc_cols);
+ break;
+
+ case __SCROLL_YWRAP:
+ if (b - t - count > 3 * vc->vc_rows >> 2) {
+ if (t > 0)
+ fbcon_bmove(vc, 0, 0, count, 0, t,
+ vc->vc_cols);
+ ywrap_up(p, vc, count);
+ if (vc->vc_rows - b > 0)
+ fbcon_bmove(vc, b - count, 0, b, 0,
+ vc->vc_rows - b,
+ vc->vc_cols);
+ } else if (p->scrollmode & __SCROLL_YPANREDRAW)
+ goto redraw_up;
+ else
+ fbcon_bmove(vc, t + count, 0, t, 0,
+ b - t - count, vc->vc_cols);
+ fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+ break;
+
+ case __SCROLL_YPAN:
+ if ((p->yscroll + count <=
+ 2 * (p->vrows - vc->vc_rows))
+ && ((!scroll_partial && (b - t == vc->vc_rows))
+ || (scroll_partial
+ && (b - t - count >
+ 3 * vc->vc_rows >> 2)))) {
+ if (t > 0)
+ fbcon_bmove(vc, 0, 0, count, 0, t,
+ vc->vc_cols);
+ ypan_up(p, vc, count);
+ if (vc->vc_rows - b > 0)
+ fbcon_bmove(vc, b - count, 0, b, 0,
+ vc->vc_rows - b,
+ vc->vc_cols);
+ } else if (p->scrollmode & __SCROLL_YPANREDRAW)
+ goto redraw_up;
+ else
+ fbcon_bmove(vc, t + count, 0, t, 0,
+ b - t - count, vc->vc_cols);
+ fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+ break;
+
+ case __SCROLL_YREDRAW:
+ redraw_up:
+ fbcon_redraw(vc, p, t, b - t - count,
+ count * vc->vc_cols);
+ accel_clear(vc, p, real_y(p, b - count), 0,
+ count, vc->vc_cols);
+ scr_memsetw((unsigned short *) (vc->vc_origin +
+ vc->vc_size_row *
+ (b - count)),
+ vc->vc_video_erase_char,
+ vc->vc_size_row * count);
+ return 1;
+ }
+ break;
+
+ case SM_DOWN:
+ if (count > vc->vc_rows) /* Maximum realistic size */
+ count = vc->vc_rows;
+ switch (p->scrollmode & __SCROLL_YMASK) {
+ case __SCROLL_YMOVE:
+ accel_bmove(p, t, 0, t + count, 0,
+ b - t - count, vc->vc_cols);
+ accel_clear(vc, p, t, 0, count, vc->vc_cols);
+ break;
+
+ case __SCROLL_YWRAP:
+ if (b - t - count > 3 * vc->vc_rows >> 2) {
+ if (vc->vc_rows - b > 0)
+ fbcon_bmove(vc, b, 0, b - count, 0,
+ vc->vc_rows - b,
+ vc->vc_cols);
+ ywrap_down(p, vc, count);
+ if (t > 0)
+ fbcon_bmove(vc, count, 0, 0, 0, t,
+ vc->vc_cols);
+ } else if (p->scrollmode & __SCROLL_YPANREDRAW)
+ goto redraw_down;
+ else
+ fbcon_bmove(vc, t, 0, t + count, 0,
+ b - t - count, vc->vc_cols);
+ fbcon_clear(vc, t, 0, count, vc->vc_cols);
+ break;
+
+ case __SCROLL_YPAN:
+ if ((count - p->yscroll <= p->vrows - vc->vc_rows)
+ && ((!scroll_partial && (b - t == vc->vc_rows))
+ || (scroll_partial
+ && (b - t - count >
+ 3 * vc->vc_rows >> 2)))) {
+ if (vc->vc_rows - b > 0)
+ fbcon_bmove(vc, b, 0, b - count, 0,
+ vc->vc_rows - b,
+ vc->vc_cols);
+ ypan_down(p, vc, count);
+ if (t > 0)
+ fbcon_bmove(vc, count, 0, 0, 0, t,
+ vc->vc_cols);
+ } else if (p->scrollmode & __SCROLL_YPANREDRAW)
+ goto redraw_down;
+ else
+ fbcon_bmove(vc, t, 0, t + count, 0,
+ b - t - count, vc->vc_cols);
+ fbcon_clear(vc, t, 0, count, vc->vc_cols);
+ break;
+
+ case __SCROLL_YREDRAW:
+ redraw_down:
+ fbcon_redraw(vc, p, b - 1, b - t - count,
+ -count * vc->vc_cols);
+ accel_clear(vc, p, real_y(p, t), 0, count,
+ vc->vc_cols);
+ scr_memsetw((unsigned short *) (vc->vc_origin +
+ vc->vc_size_row *
+ t),
+ vc->vc_video_erase_char,
+ vc->vc_size_row * count);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
+ int height, int width)
+{
+ int unit = vc->vc_num;
+ struct display *p = &fb_display[unit];
+
+ if (!p->can_soft_blank && console_blanked)
+ return;
+
+ if (!width || !height)
+ 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)))
+ fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
+
+ /* Split blits that cross physical y_wrap case.
+ * Pathological case involves 4 blits, better to use recursive
+ * code rather than unrolled case
+ *
+ * Recursive invocations don't need to erase the cursor over and
+ * over again, so we use fbcon_bmove_rec()
+ */
+ 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)
+{
+ u_int b;
+
+ if (sy < y_break && sy + height > y_break) {
+ b = y_break - sy;
+ if (dy < sy) { /* Avoid trashing self */
+ fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+ y_break);
+ fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+ height - b, width, y_break);
+ } else {
+ fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+ height - b, width, y_break);
+ fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+ y_break);
+ }
+ return;
+ }
+
+ if (dy < y_break && dy + height > y_break) {
+ b = y_break - dy;
+ if (dy < sy) { /* Avoid trashing self */
+ fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+ y_break);
+ fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+ height - b, width, y_break);
+ } else {
+ fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+ height - b, width, y_break);
+ fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+ y_break);
+ }
+ return;
+ }
+ accel_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height,
+ width);
+}
+
+
+static int fbcon_switch(struct vc_data *vc)
+{
+ int unit = vc->vc_num;
+ struct display *p = &fb_display[unit];
+ struct fb_info *info = p->fb_info;
+
+ if (softback_top) {
+ int l = fbcon_softback_size / vc->vc_size_row;
+ if (softback_lines)
+ fbcon_set_origin(vc);
+ softback_top = softback_curr = softback_in = softback_buf;
+ softback_lines = 0;
+
+ if (l > 5)
+ softback_end = softback_buf + l * vc->vc_size_row;
+ else {
+ /* Smaller scrollback makes no sense, and 0 would screw
+ the operation totally */
+ softback_top = 0;
+ }
+ }
+ 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;
+ }
+ if (info)
+ info->var.yoffset = p->yscroll = 0;
+ switch (p->scrollmode & __SCROLL_YMASK) {
+ case __SCROLL_YWRAP:
+ scrollback_phys_max = p->vrows - vc->vc_rows;
+ break;
+ case __SCROLL_YPAN:
+ scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
+ if (scrollback_phys_max < 0)
+ scrollback_phys_max = 0;
+ break;
+ default:
+ scrollback_phys_max = 0;
+ break;
+ }
+ scrollback_max = 0;
+ scrollback_current = 0;
+
+ info->currcon = unit;
+
+ update_var(unit, info);
+
+ if (vt_cons[unit]->vc_mode == KD_TEXT)
+ accel_clear_margins(vc, p, 0);
+ if (logo_shown == -2) {
+ logo_shown = fg_console;
+ fbcon_show_logo(); /* This is protected above by initmem_freed */
+ update_region(fg_console,
+ vc->vc_origin + vc->vc_size_row * vc->vc_top,
+ vc->vc_size_row * (vc->vc_bottom -
+ vc->vc_top) / 2);
+ return 0;
+ }
+ return 1;
+}
+
+static int fbcon_blank(struct vc_data *vc, int blank)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_info *info = p->fb_info;
+
+ if (blank < 0) /* Entering graphics mode */
+ return 0;
+
+ fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
+
+ if (!p->can_soft_blank) {
+ if (blank) {
+ unsigned short oldc;
+ u_int height;
+ u_int y_break;
+
+ oldc = vc->vc_video_erase_char;
+ vc->vc_video_erase_char &= p->charmask;
+ height = vc->vc_rows;
+ y_break = p->vrows - p->yscroll;
+ if (height > y_break) {
+ accel_clear(vc, p,
+ real_y(p, 0), 0,
+ y_break,
+ vc->vc_cols);
+ accel_clear(vc, p,
+ real_y(p,
+ y_break),
+ 0,
+ height - y_break,
+ vc->vc_cols);
+ } else
+ accel_clear(vc, p,
+ real_y(p, 0), 0,
+ height,
+ vc->vc_cols);
+ vc->vc_video_erase_char = oldc;
+ }
+ return 0;
+ } else {
+ /* Tell console.c that it has to restore the screen itself */
+ return 1;
+ }
+ fb_blank(blank, info);
+ return 0;
+}
+
+static void fbcon_free_font(struct display *p)
+{
+ if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
+ kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
+ p->fontdata = NULL;
+ p->userfont = 0;
+}
+
+static inline int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ u8 *data = op->data;
+ u8 *fontdata = p->fontdata;
+ int i, j;
+
+#ifdef CONFIG_FONTWIDTH8_ONLY
+ if (fontwidth(p) != 8)
+ return -EINVAL;
+#endif
+ op->width = vc->vc_font.width;
+ op->height = vc->vc_font.height;
+ op->charcount = (p->charmask == 0x1ff) ? 512 : 256;
+ if (!op->data)
+ return 0;
+
+ if (op->width <= 8) {
+ j = vc->vc_font.height;
+ for (i = 0; i < op->charcount; i++) {
+ memcpy(data, fontdata, j);
+ memset(data + j, 0, 32 - j);
+ data += 32;
+ fontdata += j;
+ }
+ }
+#ifndef CONFIG_FONTWIDTH8_ONLY
+ else if (op->width <= 16) {
+ j = vc->vc_font.height * 2;
+ for (i = 0; i < op->charcount; i++) {
+ memcpy(data, fontdata, j);
+ memset(data + j, 0, 64 - j);
+ data += 64;
+ fontdata += j;
+ }
+ } else if (op->width <= 24) {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < vc->vc_font.height; j++) {
+ *data++ = fontdata[0];
+ *data++ = fontdata[1];
+ *data++ = fontdata[2];
+ fontdata += sizeof(u32);
+ }
+ memset(data, 0, 3 * (32 - j));
+ data += 3 * (32 - j);
+ }
+ } else {
+ j = vc->vc_font.height * 4;
+ for (i = 0; i < op->charcount; i++) {
+ memcpy(data, fontdata, j);
+ memset(data + j, 0, 128 - j);
+ data += 128;
+ fontdata += j;
+ }
+ }
+#endif
+ return 0;
+}
+
+static int fbcon_do_set_font(struct vc_data *vc, struct console_font_op *op,
+ u8 * data, int userfont)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_info *info = p->fb_info;
+ int resize;
+ int w = op->width;
+ int h = op->height;
+ int cnt;
+ char *old_data = NULL;
+
+ if (!fontwidthvalid(p, w)) {
+ if (userfont && op->op != KD_FONT_OP_COPY)
+ kfree(data - FONT_EXTRA_WORDS * sizeof(int));
+ return -ENXIO;
+ }
+
+ if (CON_IS_VISIBLE(vc) && softback_lines)
+ fbcon_set_origin(vc);
+
+ resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
+ if (p->userfont)
+ old_data = p->fontdata;
+ if (userfont)
+ cnt = FNTCHARCNT(data);
+ else
+ cnt = 256;
+ p->fontdata = data;
+ if ((p->userfont = userfont))
+ REFCOUNT(data)++;
+ vc->vc_font.width = w;
+ vc->vc_font.height = h;
+ if (vc->vc_hi_font_mask && cnt == 256) {
+ vc->vc_hi_font_mask = 0;
+ if (vc->vc_can_do_color)
+ vc->vc_complement_mask >>= 1;
+ p->fgshift--;
+ p->bgshift--;
+ p->charmask = 0xff;
+
+ /* ++Edmund: reorder the attribute bits */
+ if (vc->vc_can_do_color) {
+ unsigned short *cp =
+ (unsigned short *) vc->vc_origin;
+ int count = vc->vc_screenbuf_size / 2;
+ unsigned short c;
+ for (; count > 0; count--, cp++) {
+ c = scr_readw(cp);
+ scr_writew(((c & 0xfe00) >> 1) |
+ (c & 0xff), cp);
+ }
+ c = vc->vc_video_erase_char;
+ vc->vc_video_erase_char =
+ ((c & 0xfe00) >> 1) | (c & 0xff);
+ vc->vc_attr >>= 1;
+ }
+
+ } else if (!vc->vc_hi_font_mask && cnt == 512) {
+ vc->vc_hi_font_mask = 0x100;
+ if (vc->vc_can_do_color)
+ vc->vc_complement_mask <<= 1;
+ p->fgshift++;
+ p->bgshift++;
+ p->charmask = 0x1ff;
+
+ /* ++Edmund: reorder the attribute bits */
+ {
+ unsigned short *cp =
+ (unsigned short *) vc->vc_origin;
+ int count = vc->vc_screenbuf_size / 2;
+ unsigned short c;
+ for (; count > 0; count--, cp++) {
+ unsigned short newc;
+ c = scr_readw(cp);
+ if (vc->vc_can_do_color)
+ newc =
+ ((c & 0xff00) << 1) | (c &
+ 0xff);
+ else
+ newc = c & ~0x100;
+ scr_writew(newc, cp);
+ }
+ c = vc->vc_video_erase_char;
+ if (vc->vc_can_do_color) {
+ vc->vc_video_erase_char =
+ ((c & 0xff00) << 1) | (c & 0xff);
+ vc->vc_attr <<= 1;
+ } else
+ vc->vc_video_erase_char = c & ~0x100;
+ }
+
+ }
+
+ if (resize) {
+ /* reset wrap/pan */
+ info->var.xoffset = info->var.yoffset = p->yscroll = 0;
+ p->vrows = info->var.yres_virtual / h;
+ if ((info->var.yres % h)
+ && (info->var.yres_virtual % h < info->var.yres % h))
+ p->vrows--;
+ updatescrollmode(p, vc);
+ vc_resize(vc->vc_num, info->var.xres / w, info->var.yres / h);
+ if (CON_IS_VISIBLE(vc) && softback_buf) {
+ int l = fbcon_softback_size / vc->vc_size_row;
+ if (l > 5)
+ softback_end =
+ softback_buf + l * vc->vc_size_row;
+ else {
+ /* Smaller scrollback makes no sense, and 0 would screw
+ the operation totally */
+ softback_top = 0;
+ }
+ }
+ } else if (CON_IS_VISIBLE(vc)
+ && vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
+ accel_clear_margins(vc, p, 0);
+ update_screen(vc->vc_num);
+ }
+
+ if (old_data && (--REFCOUNT(old_data) == 0))
+ kfree(old_data - FONT_EXTRA_WORDS * sizeof(int));
+ return 0;
+}
+
+static inline int fbcon_copy_font(struct vc_data *vc, struct console_font_op *op)
+{
+ struct display *od, *p = &fb_display[vc->vc_num];
+ int h = op->height;
+
+ if (h < 0 || !vc_cons_allocated(h))
+ return -ENOTTY;
+ if (h == vc->vc_num)
+ return 0; /* nothing to do */
+ od = &fb_display[h];
+ if (od->fontdata == p->fontdata)
+ return 0; /* already the same font... */
+ op->width = vc->vc_font.width;
+ op->height = vc->vc_font.height;
+ return fbcon_do_set_font(vc, op, od->fontdata, od->userfont);
+}
+
+static inline int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
+{
+ int w = op->width;
+ int h = op->height;
+ int size = h;
+ int i, k;
+ u8 *new_data, *data = op->data, *p;
+
+#ifdef CONFIG_FONTWIDTH8_ONLY
+ if (w != 8)
+ return -EINVAL;
+#endif
+ if ((w <= 0) || (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(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER)))
+ return -ENOMEM;
+ new_data += FONT_EXTRA_WORDS * sizeof(int);
+ FNTSIZE(new_data) = size;
+ FNTCHARCNT(new_data) = op->charcount;
+ REFCOUNT(new_data) = 0; /* usage counter */
+ p = new_data;
+ if (w <= 8) {
+ for (i = 0; i < op->charcount; i++) {
+ memcpy(p, data, h);
+ data += 32;
+ p += h;
+ }
+ }
+#ifndef CONFIG_FONTWIDTH8_ONLY
+ else if (w <= 16) {
+ h *= 2;
+ for (i = 0; i < op->charcount; i++) {
+ memcpy(p, data, h);
+ data += 64;
+ p += h;
+ }
+ } else if (w <= 24) {
+ for (i = 0; i < op->charcount; i++) {
+ int j;
+ for (j = 0; j < h; j++) {
+ memcpy(p, data, 3);
+ p[3] = 0;
+ data += 3;
+ p += sizeof(u32);
+ }
+ data += 3 * (32 - h);
+ }
+ } else {
+ h *= 4;
+ for (i = 0; i < op->charcount; i++) {
+ memcpy(p, data, h);
+ data += 128;
+ p += h;
+ }
+ }
+#endif
+ /* we can do it in u32 chunks because of charcount is 256 or 512, so
+ font length must be multiple of 256, at least. And 256 is multiple
+ of 4 */
+ k = 0;
+ while (p > new_data)
+ k += *--(u32 *) p;
+ FNTSUM(new_data) = k;
+ /* Check if the same font is on some other console already */
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ struct vc_data *tmp = vc_cons[i].d;
+
+ if (fb_display[i].userfont &&
+ fb_display[i].fontdata &&
+ FNTSUM(fb_display[i].fontdata) == k &&
+ FNTSIZE(fb_display[i].fontdata) == size &&
+ tmp->vc_font.width == w &&
+ !memcmp(fb_display[i].fontdata, new_data, size)) {
+ kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
+ new_data = fb_display[i].fontdata;
+ break;
+ }
+ }
+ return fbcon_do_set_font(vc, op, new_data, 1);
+}
+
+static inline int fbcon_set_def_font(struct vc_data *vc, struct console_font_op *op)
+{
+ char name[MAX_FONT_NAME];
+ struct font_desc *f;
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_info *info = p->fb_info;
+
+ if (!op->data)
+ f = get_default_font(info->var.xres, info->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 = find_font(name)))
+ return -ENOENT;
+ }
+ op->width = f->width;
+ op->height = f->height;
+ return fbcon_do_set_font(vc, op, f->data, 0);
+}
+
+static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op)
+{
+ switch (op->op) {
+ case KD_FONT_OP_SET:
+ return fbcon_set_font(vc, op);
+ case KD_FONT_OP_GET:
+ return fbcon_get_font(vc, op);
+ case KD_FONT_OP_SET_DEFAULT:
+ return fbcon_set_def_font(vc, op);
+ case KD_FONT_OP_COPY:
+ return fbcon_copy_font(vc, op);
+ default:
+ return -ENOSYS;
+ }
+}
+
+static u16 palette_red[16];
+static u16 palette_green[16];
+static u16 palette_blue[16];
+
+static struct fb_cmap palette_cmap = {
+ 0, 16, palette_red, palette_green, palette_blue, NULL
+};
+
+static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
+{
+ int unit = vc->vc_num;
+ struct display *p = &fb_display[unit];
+ struct fb_info *info = p->fb_info;
+ int i, j, k;
+ u8 val;
+
+ if (!vc->vc_can_do_color
+ || (!p->can_soft_blank && console_blanked))
+ return -EINVAL;
+ for (i = j = 0; i < 16; i++) {
+ k = table[i];
+ val = vc->vc_palette[j++];
+ palette_red[k] = (val << 8) | val;
+ val = vc->vc_palette[j++];
+ palette_green[k] = (val << 8) | val;
+ val = vc->vc_palette[j++];
+ palette_blue[k] = (val << 8) | val;
+ }
+ if (info->var.bits_per_pixel <= 4)
+ palette_cmap.len = 1 << info->var.bits_per_pixel;
+ else
+ palette_cmap.len = 16;
+ palette_cmap.start = 0;
+ return fb_set_cmap(&palette_cmap, 1, info);
+}
+
+static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
+{
+ int line;
+ unsigned long p;
+
+ if (vc->vc_num != fg_console || !softback_lines)
+ return (u16 *) (vc->vc_origin + offset);
+ line = offset / vc->vc_size_row;
+ if (line >= softback_lines)
+ return (u16 *) (vc->vc_origin + offset -
+ softback_lines * vc->vc_size_row);
+ p = softback_curr + offset;
+ if (p >= softback_end)
+ p += softback_buf - softback_end;
+ return (u16 *) p;
+}
+
+static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
+ int *px, int *py)
+{
+ int x, y;
+ unsigned long ret;
+ if (pos >= vc->vc_origin && pos < vc->vc_scr_end) {
+ unsigned long offset = (pos - vc->vc_origin) / 2;
+
+ x = offset % vc->vc_cols;
+ y = offset / vc->vc_cols;
+ if (vc->vc_num == fg_console)
+ y += softback_lines;
+ ret = pos + (vc->vc_cols - x) * 2;
+ } else if (vc->vc_num == fg_console && softback_lines) {
+ unsigned long offset = pos - softback_curr;
+
+ if (pos < softback_curr)
+ offset += softback_end - softback_buf;
+ offset /= 2;
+ x = offset % vc->vc_cols;
+ y = offset / vc->vc_cols;
+ ret = pos + (vc->vc_cols - x) * 2;
+ if (ret == softback_end)
+ ret = softback_buf;
+ if (ret == softback_in)
+ ret = vc->vc_origin;
+ } else {
+ /* Should not happen */
+ x = y = 0;
+ ret = vc->vc_origin;
+ }
+ if (px)
+ *px = x;
+ if (py)
+ *py = y;
+ return ret;
+}
+
+/* As we might be inside of softback, we may work with non-contiguous buffer,
+ that's why we have to use a separate routine. */
+static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
+{
+ while (cnt--) {
+ u16 a = scr_readw(p);
+ if (!vc->vc_can_do_color)
+ a ^= 0x0800;
+ else if (vc->vc_hi_font_mask == 0x100)
+ a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) |
+ (((a) & 0x0e00) << 4);
+ else
+ a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
+ (((a) & 0x0700) << 4);
+ scr_writew(a, p++);
+ if (p == (u16 *) softback_end)
+ p = (u16 *) softback_buf;
+ if (p == (u16 *) softback_in)
+ p = (u16 *) vc->vc_origin;
+ }
+}
+
+static int fbcon_scrolldelta(struct vc_data *vc, int lines)
+{
+ int unit, offset, limit, scrollback_old;
+ struct fb_info *info;
+ struct display *p;
+
+ unit = fg_console;
+ p = &fb_display[unit];
+ info = p->fb_info;
+
+ if (softback_top) {
+ if (vc->vc_num != unit)
+ return 0;
+ if (vt_cons[unit]->vc_mode != KD_TEXT || !lines)
+ return 0;
+ 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;
+ if (logo_shown == unit) {
+ unsigned long p, q;
+ int i;
+
+ p = softback_in;
+ q = vc->vc_origin +
+ logo_lines * vc->vc_size_row;
+ for (i = 0; i < logo_lines; i++) {
+ if (p == softback_top)
+ break;
+ if (p == softback_buf)
+ p = softback_end;
+ p -= vc->vc_size_row;
+ q -= vc->vc_size_row;
+ scr_memcpyw((u16 *) q, (u16 *) p,
+ vc->vc_size_row);
+ }
+ softback_in = p;
+ update_region(unit, vc->vc_origin,
+ logo_lines * vc->vc_cols);
+ }
+ logo_shown = -1;
+ }
+ fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
+ fbcon_redraw_softback(vc, p, lines);
+ fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
+ return 0;
+ }
+
+ 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;
+
+ if (!p->can_soft_blank &&
+ (console_blanked || vt_cons[unit]->vc_mode != KD_TEXT
+ || !lines))
+ return 0;
+ fbcon_cursor(vc, CM_ERASE);
+
+ offset = p->yscroll - scrollback_current;
+ limit = p->vrows;
+ switch (p->scrollmode && __SCROLL_YMASK) {
+ case __SCROLL_YWRAP:
+ info->var.vmode |= FB_VMODE_YWRAP;
+ break;
+ case __SCROLL_YPAN:
+ limit -= vc->vc_rows;
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+ break;
+ }
+ if (offset < 0)
+ offset += limit;
+ else if (offset >= limit)
+ offset -= limit;
+ info->var.xoffset = 0;
+ info->var.yoffset = offset * vc->vc_font.height;
+ update_var(unit, info);
+ if (!scrollback_current)
+ fbcon_cursor(vc, CM_DRAW);
+ return 0;
+}
+
+static int fbcon_set_origin(struct vc_data *vc)
+{
+ if (softback_lines && !console_blanked)
+ fbcon_scrolldelta(vc, softback_lines);
+ return 0;
+}
+
+static inline unsigned safe_shift(unsigned d, int n)
+{
+ return n < 0 ? d >> -n : d << n;
+}
+
+static void __init fbcon_set_logocmap(struct fb_info *info)
+{
+ int i, j, n;
+
+ for (i = 0; i < LINUX_LOGO_COLORS; i += n) {
+ n = LINUX_LOGO_COLORS - i;
+ if (n > 16)
+ /* palette_cmap provides space for only 16 colors at once */
+ n = 16;
+ palette_cmap.start = 32 + i;
+ palette_cmap.len = n;
+ for (j = 0; j < n; ++j) {
+ palette_cmap.red[j] =
+ (linux_logo_red[i + j] << 8) |
+ linux_logo_red[i + j];
+ palette_cmap.green[j] =
+ (linux_logo_green[i + j] << 8) |
+ linux_logo_green[i + j];
+ palette_cmap.blue[j] =
+ (linux_logo_blue[i + j] << 8) |
+ linux_logo_blue[i + j];
+ }
+ fb_set_cmap(&palette_cmap, 1, info);
+ }
+}
+
+static void __init fbcon_set_logo_truepalette(struct fb_info *info, u32 *palette)
+{
+ unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
+ unsigned char redmask, greenmask, bluemask;
+ int redshift, greenshift, blueshift;
+ int i;
+
+ /*
+ * We have to create a temporary palette since console palette is only
+ * 16 colors long.
+ */
+ /* Bug: Doesn't obey msb_right ... (who needs that?) */
+ redmask = mask[info->var.red.length < 8 ? info->var.red.length : 8];
+ greenmask = mask[info->var.green.length < 8 ? info->var.green.length : 8];
+ bluemask = mask[info->var.blue.length < 8 ? info->var.blue.length : 8];
+ redshift = info->var.red.offset - (8 - info->var.red.length);
+ greenshift = info->var.green.offset - (8 - info->var.green.length);
+ blueshift = info->var.blue.offset - (8 - info->var.blue.length);
+
+
+ for ( i = 0; i < LINUX_LOGO_COLORS; i++) {
+ palette[i+32] = (safe_shift((linux_logo_red[i] & redmask), redshift) |
+ safe_shift((linux_logo_green[i] & greenmask), greenshift) |
+ safe_shift((linux_logo_blue[i] & bluemask), blueshift));
+ }
+}
+
+static void __init fbcon_set_logo_directpalette(struct fb_info *info, u32 *palette)
+{
+ int redshift, greenshift, blueshift;
+ int i;
+
+ redshift = info->var.red.offset;
+ greenshift = info->var.green.offset;
+ blueshift = info->var.blue.offset;
+
+ for (i = 32; i < LINUX_LOGO_COLORS; i++)
+ palette[i] = i << redshift | i << greenshift | i << blueshift;
+
+}
+
+static void __init fbcon_set_logo(struct fb_info *info, u8 *logo, int needs_logo)
+{
+ int i, j;
+
+ switch (needs_logo) {
+ case 4:
+ for (i = 0; i < (LOGO_W * LOGO_H)/2; i++) {
+ logo[i*2] = linux_logo16[i] >> 4;
+ logo[(i*2)+1] = linux_logo16[i] & 0xf;
+ }
+ break;
+ case 1:
+ case ~1:
+ default:
+ for (i = 0; i < (LOGO_W * LOGO_H)/8; i++)
+ for (j = 0; j < 8; j++)
+ logo[i*2] = (linux_logo_bw[i] & (7 - j)) ?
+ ((needs_logo == 1) ? 1 : 0) :
+ ((needs_logo == 1) ? 0 : 1);
+
+ break;
+ }
+}
+
+/*
+ * Three (3) kinds of logo maps exist. linux_logo (>16 colors), linux_logo_16
+ * (16 colors) and linux_logo_bw (2 colors). Depending on the visual format and
+ * color depth of the framebuffer, the DAC, the pseudo_palette, and the logo data
+ * will be adjusted accordingly.
+ *
+ * Case 1 - linux_logo:
+ * Color exceeds the number of console colors (16), thus we set the hardware DAC
+ * using fb_set_cmap() appropriately. The "needs_cmapreset" flag will be set.
+ *
+ * For visuals that require color info from the pseudo_palette, we also construct
+ * one for temporary use. The "needs_directpalette" or "needs_truepalette" flags
+ * will be set.
+ *
+ * Case 2 - linux_logo_16:
+ * The number of colors just matches the console colors, thus there is no need
+ * to set the DAC or the pseudo_palette. However, the bitmap is packed, ie,
+ * each byte contains color information for two pixels (upper and lower nibble).
+ * To be consistent with fb_imageblit() usage, we therefore separate the two
+ * nibbles into separate bytes. The "needs_logo" flag will be set to 4.
+ *
+ * Case 3 - linux_logo_bw:
+ * This is similar with Case 2. Each byte contains information for 8 pixels.
+ * We isolate each bit and expand each into a byte. The "needs_logo" flag will
+ * be set to 1.
+ */
+static int __init fbcon_show_logo(void)
+ {
+ struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
+ struct fb_info *info = p->fb_info;
+ struct vc_data *vc = info->display_fg;
+ struct fb_image image;
+ u32 *palette = NULL, *saved_palette = NULL;
+ unsigned char *fb = info->screen_base, *logo_new = NULL;
+ int done = 0, x;
+ int needs_cmapreset = 0;
+ int needs_truepalette = 0;
+ int needs_directpalette = 0;
+ int needs_logo = 0;
+
+ /* Return if the frame buffer is not mapped */
+ if (!fb || !info->fbops->fb_imageblit)
+ return 0;
+
+ image.depth = info->var.bits_per_pixel;
+
+ /* reasonable default */
+ if (image.depth >= 8)
+ image.data = linux_logo;
+ else if (image.depth >= 4)
+ image.data = linux_logo16;
+ else
+ image.data = linux_logo_bw;
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ needs_truepalette = 1;
+ if (image.depth >= 4 && image.depth <= 8)
+ needs_logo = 4;
+ else if (image.depth < 4)
+ needs_logo = 1;
+ break;
+ case FB_VISUAL_DIRECTCOLOR:
+ if (image.depth >= 24) {
+ needs_directpalette = 1;
+ needs_cmapreset = 1;
+ }
+ /* 16 colors */
+ else if (image.depth >= 16)
+ needs_logo = 4;
+ /* 2 colors */
+ else
+ needs_logo = 1;
+ break;
+ case FB_VISUAL_MONO01:
+ /* reversed 0 = fg, 1 = bg */
+ needs_logo = ~1;
+ break;
+ case FB_VISUAL_MONO10:
+ needs_logo = 1;
+ break;
+ case FB_VISUAL_PSEUDOCOLOR:
+ default:
+ if (image.depth >= 8)
+ needs_cmapreset = 1;
+ /* fall through */
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ /* 16 colors */
+ if (image.depth >= 4 && image.depth < 8)
+ needs_logo = 4;
+ /* 2 colors */
+ else if (image.depth < 4)
+ needs_logo = 1;
+ break;
+ }
+
+ if (needs_cmapreset)
+ fbcon_set_logocmap(info);
+
+ if (needs_truepalette || needs_directpalette) {
+ palette = kmalloc(256 * 4, GFP_KERNEL);
+ if (palette == NULL)
+ return 1;
+
+ if (needs_truepalette)
+ fbcon_set_logo_truepalette(info, palette);
+ else
+ fbcon_set_logo_directpalette(info, palette);
+
+ saved_palette = info->pseudo_palette;
+ info->pseudo_palette = palette;
+ }
+
+ if (needs_logo) {
+ logo_new = kmalloc(LOGO_W * LOGO_H, GFP_KERNEL);
+ if (logo_new == NULL) {
+ if (palette)
+ kfree(palette);
+ if (saved_palette)
+ info->pseudo_palette = saved_palette;
+ return 1;
+ }
+
+ image.data = logo_new;
+ fbcon_set_logo(info, logo_new, needs_logo);
+ }
+
+ image.width = LOGO_W;
+ image.height = LOGO_H;
+ image.dy = 0;
+
+ for (x = 0; x < num_online_cpus() * (LOGO_W + 8) &&
+ x < info->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
+ image.dx = x;
+ info->fbops->fb_imageblit(info, &image);
+ done = 1;
+ }
+
+ if (palette != NULL)
+ kfree(palette);
+ if (saved_palette != NULL)
+ info->pseudo_palette = saved_palette;
+ if (logo_new != NULL)
+ kfree(logo_new);
+ /*
+ * Modes not yet supported: packed pixels with depth != 8 (does such a
+ * thing exist in reality?)
+ */
+ return done ? (LOGO_H + vc->vc_font.height - 1) / vc->vc_font.height : 0;
+}
+
+/*
+ * The console `switch' structure for the frame buffer based console
+ */
+
+const struct consw fb_con = {
+ .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 = fbcon_set_origin,
+ .con_invert_region = fbcon_invert_region,
+ .con_screen_pos = fbcon_screen_pos,
+ .con_getxy = fbcon_getxy,
+};
+
+int __init fb_console_init(void)
+{
+ if (!num_registered_fb)
+ return -ENODEV;
+ take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
+ __unsafe(THIS_MODULE);
+ return 0;
+}
+
+void __exit fb_console_exit(void)
+{
+ give_up_console(&fb_con);
+}
+
+module_init(fb_console_init);
+module_exit(fb_console_exit);
+
+/*
+ * Visible symbols for modules
+ */
+
+EXPORT_SYMBOL(fb_display);
+EXPORT_SYMBOL(fbcon_redraw_bmove);
+EXPORT_SYMBOL(fbcon_redraw_clear);
+EXPORT_SYMBOL(fb_con);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
new file mode 100644
index 000000000000..b49beeccc17e
--- /dev/null
+++ b/drivers/video/console/fbcon.h
@@ -0,0 +1,142 @@
+/*
+ * linux/drivers/video/console/fbcon.h -- Low level frame buffer based console driver
+ *
+ * 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.
+ */
+
+#ifndef _VIDEO_FBCON_H
+#define _VIDEO_FBCON_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/vt_buffer.h>
+#include <linux/vt_kern.h>
+
+#include <asm/io.h>
+
+ /*
+ * This is the interface between the low-level console driver and the
+ * low-level frame buffer device
+ */
+
+struct display {
+ /* Filled in by the frame buffer device */
+ u_short can_soft_blank; /* zero if no hardware blanking */
+ u_short inverse; /* != 0 text black on white as default */
+ struct display_switch *dispsw; /* low level operations */
+
+ /* Filled in by the low-level console driver */
+ struct vc_data *conp; /* pointer to console data */
+ struct fb_info *fb_info; /* frame buffer for this console */
+ int vrows; /* number of virtual rows */
+ unsigned short cursor_x; /* current cursor position */
+ unsigned short cursor_y;
+ unsigned long cursor_pos;
+ char fontname[40]; /* Font associated to this display */
+ u_char *fontdata;
+ int userfont; /* != 0 if fontdata kmalloc()ed */
+ u_short scrollmode; /* Scroll Method */
+ short yscroll; /* Hardware scrolling */
+ unsigned char fgshift, bgshift;
+ unsigned short charmask; /* 0xff or 0x1ff */
+ unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */
+};
+
+/* drivers/video/console/fbcon.c */
+extern struct display fb_display[MAX_NR_CONSOLES];
+extern char con2fb_map[MAX_NR_CONSOLES];
+extern void set_con2fb_map(int unit, int newidx);
+
+#define fontheight(p) ((p)->_fontheight)
+
+#ifdef CONFIG_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)
+
+#define fontwidth(p) (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))
+
+#define fontwidth(p) ((p)->_fontwidth)
+
+#endif
+
+ /*
+ * Attribute Decoding
+ */
+
+/* Color */
+#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) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
+#define attr_fgcol_ec(p,vc) \
+ ((vc) ? (((vc)->vc_video_erase_char >> ((p)->fgshift)) & 0x0f) : 0)
+
+/* Monochrome */
+#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
+ */
+
+/* Internal flags */
+#define __SCROLL_YPAN 0x001
+#define __SCROLL_YWRAP 0x002
+#define __SCROLL_YMOVE 0x003
+#define __SCROLL_YREDRAW 0x004
+#define __SCROLL_YMASK 0x00f
+#define __SCROLL_YFIXED 0x010
+#define __SCROLL_YNOMOVE 0x020
+#define __SCROLL_YPANREDRAW 0x040
+#define __SCROLL_YNOPARTIAL 0x080
+
+/* Only these should be used by the drivers */
+/* Which one should you use? If you have a fast card and slow bus,
+ then probably just 0 to indicate fbcon should choose between
+ YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
+ and even better if your card can do fonting (1->8/32bit painting),
+ you should consider either SCROLL_YREDRAW (if your card is
+ able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
+ The best is to test it with some real life scrolling (usually, not
+ all lines on the screen are filled completely with non-space characters,
+ and REDRAW performs much better on such lines, so don't cat a file
+ with every line covering all screen columns, it would not be the right
+ benchmark).
+ */
+#define SCROLL_YREDRAW (__SCROLL_YFIXED|__SCROLL_YREDRAW)
+#define SCROLL_YNOMOVE (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
+
+/* SCROLL_YNOPARTIAL, used in combination with the above, is for video
+ cards which can not handle using panning to scroll a portion of the
+ screen without excessive flicker. Panning will only be used for
+ whole screens.
+ */
+/* Namespace consistency */
+#define SCROLL_YNOPARTIAL __SCROLL_YNOPARTIAL
+
+extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
+extern void fbcon_redraw_bmove(struct vc_data *, struct display *, int, int, int, int, int, int);
+
+#endif /* _VIDEO_FBCON_H */
diff --git a/include/video/font.h b/drivers/video/console/font.h
index 007d97f9b3ef..d612657374d0 100644
--- a/include/video/font.h
+++ b/drivers/video/console/font.h
@@ -13,7 +13,7 @@
#include <linux/types.h>
-struct fbcon_font_desc {
+struct font_desc {
int idx;
char *name;
int width, height;
@@ -30,22 +30,22 @@ struct fbcon_font_desc {
#define ACORN8x8_IDX 6
#define MINI4x6_IDX 7
-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,
- font_mini_4x6;
+extern struct font_desc font_vga_8x8,
+ font_vga_8x16,
+ font_pearl_8x8,
+ font_vga_6x11,
+ font_sun_8x16,
+ font_sun_12x22,
+ font_acorn_8x8,
+ font_mini_4x6;
/* Find a font with a specific name */
-extern struct fbcon_font_desc *fbcon_find_font(char *name);
+extern struct font_desc *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);
+extern struct font_desc *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/console/font_6x11.c
index aa95f8863830..062f68d25734 100644
--- a/drivers/video/font_6x11.c
+++ b/drivers/video/console/font_6x11.c
@@ -4,7 +4,7 @@
/* */
/**********************************************/
-#include <video/font.h>
+#include "font.h"
#define FONTDATAMAX (11*256)
@@ -3341,7 +3341,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
};
-struct fbcon_font_desc font_vga_6x11 = {
+struct font_desc font_vga_6x11 = {
VGA6x11_IDX,
"ProFont6x11",
6,
diff --git a/drivers/video/font_8x16.c b/drivers/video/console/font_8x16.c
index 786619712560..a24ea2b6da52 100644
--- a/drivers/video/font_8x16.c
+++ b/drivers/video/console/font_8x16.c
@@ -4,7 +4,7 @@
/* */
/**********************************************/
-#include <video/font.h>
+#include "font.h"
#define FONTDATAMAX 4096
@@ -4621,7 +4621,7 @@ static unsigned char fontdata_8x16[FONTDATAMAX] = {
};
-struct fbcon_font_desc font_vga_8x16 = {
+struct font_desc font_vga_8x16 = {
VGA8x16_IDX,
"VGA8x16",
8,
diff --git a/drivers/video/font_8x8.c b/drivers/video/console/font_8x8.c
index 6358e671f1ce..d7cfa088ef89 100644
--- a/drivers/video/font_8x8.c
+++ b/drivers/video/console/font_8x8.c
@@ -4,7 +4,7 @@
/* */
/**********************************************/
-#include <video/font.h>
+#include "font.h"
#define FONTDATAMAX 2048
@@ -2573,7 +2573,7 @@ static unsigned char fontdata_8x8[FONTDATAMAX] = {
};
-struct fbcon_font_desc font_vga_8x8 = {
+struct font_desc font_vga_8x8 = {
VGA8x8_IDX,
"VGA8x8",
8,
diff --git a/drivers/video/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index 154d0fb39da7..3536c7edce1f 100644
--- a/drivers/video/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
@@ -2,7 +2,7 @@
#include <linux/config.h>
-#include <video/font.h>
+#include "font.h"
static unsigned char acorndata_8x8[] = {
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
@@ -263,7 +263,7 @@ static unsigned char acorndata_8x8[] = {
/* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-struct fbcon_font_desc font_acorn_8x8 = {
+struct font_desc font_acorn_8x8 = {
ACORN8x8_IDX,
"Acorn8x8",
8,
diff --git a/drivers/video/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index 9fe2db2a6edc..8e4cb92c82b7 100644
--- a/drivers/video/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -39,7 +39,7 @@ __END__;
MSBit to LSBit = left to right.
*/
-#include <video/font.h>
+#include "font.h"
#define FONTDATAMAX 1536
@@ -2147,7 +2147,7 @@ static unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
/*}*/
};
-struct fbcon_font_desc font_mini_4x6 = {
+struct font_desc font_mini_4x6 = {
MINI4x6_IDX,
"MINI4x6",
4,
diff --git a/drivers/video/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
index c8d7da5714c5..c84048423cf8 100644
--- a/drivers/video/font_pearl_8x8.c
+++ b/drivers/video/console/font_pearl_8x8.c
@@ -9,7 +9,7 @@
/* */
/**********************************************/
-#include <video/font.h>
+#include "font.h"
#define FONTDATAMAX 2048
@@ -2577,7 +2577,7 @@ static unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
};
-struct fbcon_font_desc font_pearl_8x8 = {
+struct font_desc font_pearl_8x8 = {
PEARL8x8_IDX,
"PEARL8x8",
8,
diff --git a/drivers/video/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
index 803b35ea8d72..99f01c060fbb 100644
--- a/drivers/video/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
@@ -1,4 +1,4 @@
-#include <video/font.h>
+#include "font.h"
#define FONTDATAMAX 11264
@@ -6206,7 +6206,7 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = {
};
-struct fbcon_font_desc font_sun_12x22 = {
+struct font_desc font_sun_12x22 = {
SUN12x22_IDX,
"SUN12x22",
12,
diff --git a/drivers/video/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 9f5bc40b4762..a8f6d60e8c6e 100644
--- a/drivers/video/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -1,4 +1,4 @@
-#include <video/font.h>
+#include "font.h"
#define FONTDATAMAX 4096
@@ -261,7 +261,7 @@ static unsigned char fontdata_sun8x16[FONTDATAMAX] = {
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
-struct fbcon_font_desc font_sun_8x16 = {
+struct font_desc font_sun_8x16 = {
SUN8x16_IDX,
"SUN8x16",
8,
diff --git a/drivers/video/fonts.c b/drivers/video/console/fonts.c
index 436f3a5ec2fc..54eda88e89de 100644
--- a/drivers/video/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -12,18 +12,18 @@
* for more details.
*/
-
#include <linux/config.h>
+#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#if defined(__mc68000__) || defined(CONFIG_APUS)
#include <asm/setup.h>
#endif
-#include <video/font.h>
+#include "font.h"
#define NO_FONTS
-static struct fbcon_font_desc *fbcon_fonts[] = {
+static struct font_desc *fonts[] = {
#ifdef CONFIG_FONT_8x8
#undef NO_FONTS
&font_vga_8x8,
@@ -33,9 +33,7 @@ static struct fbcon_font_desc *fbcon_fonts[] = {
&font_vga_8x16,
#endif
#ifdef CONFIG_FONT_6x11
-#if defined(CONFIG_FBCON_ACCEL) || defined(CONFIG_FB_SBUS)
#undef NO_FONTS
-#endif
&font_vga_6x11,
#endif
#ifdef CONFIG_FONT_SUN8x16
@@ -43,9 +41,7 @@ static struct fbcon_font_desc *fbcon_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) || defined(CONFIG_FBCON_ACCEL)
#undef NO_FONTS
-#endif
&font_sun_12x22,
#endif
#ifdef CONFIG_FONT_ACORN_8x8
@@ -62,7 +58,7 @@ static struct fbcon_font_desc *fbcon_fonts[] = {
#endif
};
-#define num_fonts (sizeof(fbcon_fonts)/sizeof(*fbcon_fonts))
+#define num_fonts (sizeof(fonts)/sizeof(*fonts))
#ifdef NO_FONTS
#error No fonts configured.
@@ -70,7 +66,7 @@ static struct fbcon_font_desc *fbcon_fonts[] = {
/**
- * fbcon_find_font - find a font
+ * find_font - find a font
* @name: string name of a font
*
* Find a specified font with string name @name.
@@ -80,19 +76,19 @@ static struct fbcon_font_desc *fbcon_fonts[] = {
*
*/
-struct fbcon_font_desc *fbcon_find_font(char *name)
+struct font_desc *find_font(char *name)
{
unsigned int i;
for (i = 0; i < num_fonts; i++)
- if (!strcmp(fbcon_fonts[i]->name, name))
- return fbcon_fonts[i];
+ if (!strcmp(fonts[i]->name, name))
+ return fonts[i];
return NULL;
}
/**
- * fbcon_get_default_font - get default font
+ * get_default_font - get default font
* @xres: screen size of X
* @yres: screen size of Y
*
@@ -104,15 +100,15 @@ struct fbcon_font_desc *fbcon_find_font(char *name)
*
*/
-struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres)
+struct font_desc *get_default_font(int xres, int yres)
{
int i, c, cc;
- struct fbcon_font_desc *f, *g;
+ struct font_desc *f, *g;
g = NULL;
cc = -10000;
for(i=0; i<num_fonts; i++) {
- f = fbcon_fonts[i];
+ f = fonts[i];
c = f->pref;
#if defined(__mc68000__) || defined(CONFIG_APUS)
#ifdef CONFIG_FONT_PEARL_8x8
@@ -133,3 +129,14 @@ struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres)
}
return g;
}
+
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+
+EXPORT_SYMBOL(fonts);
+EXPORT_SYMBOL(find_font);
+EXPORT_SYMBOL(get_default_font);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Console Fonts");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mdacon.c b/drivers/video/console/mdacon.c
index f1c47bfaa270..9e88eeb9f479 100644
--- a/drivers/video/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -33,7 +33,6 @@
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
-#include <linux/console_struct.h>
#include <linux/string.h>
#include <linux/kd.h>
#include <linux/slab.h>
@@ -364,7 +363,7 @@ static void mdacon_init(struct vc_data *c, int init)
c->vc_cols = mda_num_columns;
c->vc_rows = mda_num_lines;
} else {
- vc_resize_con(mda_num_lines, mda_num_columns, c->vc_num);
+ vc_resize(c->vc_num, mda_num_columns, mda_num_lines);
}
/* make the first MDA console visible */
diff --git a/drivers/video/newport_con.c b/drivers/video/console/newport_con.c
index 364874dff50d..fae9b93070ba 100644
--- a/drivers/video/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -16,7 +16,6 @@
#include <linux/kd.h>
#include <linux/selection.h>
#include <linux/console.h>
-#include <linux/console_struct.h>
#include <linux/vt_kern.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -30,12 +29,12 @@
#define INCLUDE_LINUX_LOGO_DATA
#include <asm/linux_logo.h>
-#include <video/font.h>
+#include "font.h"
#define LOGO_W 80
#define LOGO_H 80
-extern struct fbcon_font_desc font_vga_8x16;
+extern struct font_desc font_vga_8x16;
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
diff --git a/drivers/video/prom.uni b/drivers/video/console/prom.uni
index 58f9c04ed9d3..58f9c04ed9d3 100644
--- a/drivers/video/prom.uni
+++ b/drivers/video/console/prom.uni
diff --git a/drivers/video/promcon.c b/drivers/video/console/promcon.c
index d72ce48cb3f1..c2a3deca898f 100644
--- a/drivers/video/promcon.c
+++ b/drivers/video/console/promcon.c
@@ -15,7 +15,6 @@
#include <linux/slab.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>
@@ -184,7 +183,7 @@ promcon_init(struct vc_data *conp, int init)
}
if (!init) {
if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
- vc_resize_con(ph + 1, pw + 1, conp->vc_num);
+ vc_resize(conp->unit, pw + 1, ph + 1);
}
}
diff --git a/drivers/video/sti.h b/drivers/video/console/sti.h
index feea4fb92fbb..feea4fb92fbb 100644
--- a/drivers/video/sti.h
+++ b/drivers/video/console/sti.h
diff --git a/drivers/video/sticon.c b/drivers/video/console/sticon.c
index 7dddbe42d40a..634b0289dea7 100644
--- a/drivers/video/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -49,7 +49,6 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/console.h>
-#include <linux/console_struct.h>
#include <linux/errno.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
@@ -137,7 +136,7 @@ static void sticon_init(struct vc_data *c, int init)
vc_cols = PTR_STI(sti->glob_cfg)->onscreen_x / sti_font_x(sti);
vc_rows = PTR_STI(sti->glob_cfg)->onscreen_y / sti_font_y(sti);
- vc_resize_con(vc_rows, vc_cols, c->vc_num);
+ vc_resize(c->vc_num, vc_cols, vc_rows);
}
static void sticon_deinit(struct vc_data *c)
diff --git a/drivers/video/sticore.c b/drivers/video/console/sticore.c
index 8437e1570ed3..8437e1570ed3 100644
--- a/drivers/video/sticore.c
+++ b/drivers/video/console/sticore.c
diff --git a/drivers/video/vgacon.c b/drivers/video/console/vgacon.c
index b65d47810913..4f7d0c731658 100644
--- a/drivers/video/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -41,7 +41,6 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/console.h>
-#include <linux/console_struct.h>
#include <linux/string.h>
#include <linux/kd.h>
#include <linux/slab.h>
@@ -180,6 +179,13 @@ static const char __init *vgacon_startup(void)
#endif
}
+ /* VGA16 modes are not handled by VGACON */
+ if ((ORIG_VIDEO_MODE == 0x0D) || /* 320x200/4 */
+ (ORIG_VIDEO_MODE == 0x0E) || /* 640x200/4 */
+ (ORIG_VIDEO_MODE == 0x10) || /* 640x350/4 */
+ (ORIG_VIDEO_MODE == 0x12) || /* 640x480/4 */
+ (ORIG_VIDEO_MODE == 0x6A)) /* 800x600/4, 0x6A is very common */
+ goto no_vga;
vga_video_num_lines = ORIG_VIDEO_LINES;
vga_video_num_columns = ORIG_VIDEO_COLS;
@@ -838,8 +844,8 @@ vgacon_do_font_op(char *arg, int set, int ch512)
static int
vgacon_adjust_height(unsigned fontheight)
{
- int rows, maxscan;
unsigned char ovr, vde, fsr;
+ int rows, maxscan, i;
if (fontheight == vga_video_font_height)
return 0;
@@ -881,7 +887,12 @@ vgacon_adjust_height(unsigned fontheight)
outb_p( vde, vga_video_port_val );
spin_unlock_irq(&vga_lock);
- vc_resize_all(rows, 0); /* Adjust console size */
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ struct vc_data *c = vc_cons[i].d;
+
+ if (c && c->vc_sw == &vga_con)
+ vc_resize(c->vc_num, 0, rows); /* Adjust console size */
+ }
return 0;
}
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 87b44e7865da..19031e2573f6 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -96,13 +96,11 @@ static inline int VAR_MATCH(struct fb_var_screeninfo *x, struct fb_var_screeninf
}
struct fb_info_control {
- struct fb_info info;
- struct display display;
- struct fb_par_control par;
- struct {
- __u8 red, green, blue;
- } palette[256];
-
+ struct fb_info info;
+ struct display display; /* Will disappear */
+ struct fb_par_control par;
+ u32 pseudo_palette[17];
+
struct cmap_regs *cmap_regs;
unsigned long cmap_regs_phys;
@@ -118,14 +116,6 @@ struct fb_info_control {
int control_use_bank2;
unsigned long total_vram;
unsigned char vram_attr;
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
-#endif
- } fbcon_cmap;
};
/* control register access macro */
@@ -136,33 +126,15 @@ struct fb_info_control {
/*
* struct fb_ops
*/
-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,
+static int controlfb_pan_display(struct fb_var_screeninfo *var, int con,
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 int controlfb_blank(int blank_mode, struct fb_info *info);
-static int control_mmap(struct fb_info *info, struct file *file,
+static int controlfb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma);
-
-/*
- * low level fbcon ops
- */
-static int controlfb_switch(int con, struct fb_info *info);
-static int controlfb_updatevar(int con, struct fb_info *info);
-
-/*
- * low level cmap set/get ops
- */
-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_set_par (struct fb_info *info);
+static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info);
/*
* inititialization
@@ -170,13 +142,6 @@ static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,
int control_init(void);
void control_setup(char *);
-/*
- * low level fbcon revc ops
- */
-static void control_cfb16_revc(struct display *p, int xx, int yy);
-static void control_cfb32_revc(struct display *p, int xx, int yy);
-
-
/******************** Prototypes for internal functions **********************/
static void set_control_clock(unsigned char *params);
@@ -184,10 +149,6 @@ static int init_control(struct fb_info_control *p);
static void control_set_hardware(struct fb_info_control *p,
struct fb_par_control *par);
static int control_of_init(struct device_node *dp);
-static void control_par_to_fix(struct fb_par_control *par,
- struct fb_fix_screeninfo *fix, struct fb_info_control *p);
-static void control_set_dispsw(struct display *disp, int cmode,
- struct fb_info_control *p);
static void find_vram_size(struct fb_info_control *p);
static int read_control_sense(struct fb_info_control *p);
static int calc_clock_params(unsigned long clk, unsigned char *param);
@@ -195,13 +156,6 @@ static int control_var_to_par(struct fb_var_screeninfo *var,
struct fb_par_control *par, const struct fb_info *fb_info);
static inline void control_par_to_var(struct fb_par_control *par,
struct fb_var_screeninfo *var);
-static void control_par_to_fix(struct fb_par_control *par,
- struct fb_fix_screeninfo *fix, 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_set_dispsw(struct display *disp, int cmode,
- struct fb_info_control *p);
static void control_init_info(struct fb_info *info, struct fb_info_control *p);
static void control_cleanup(void);
@@ -216,16 +170,19 @@ static int default_cmode __initdata = CMODE_NVRAM;
static struct fb_ops controlfb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = control_get_fix,
- .fb_get_var = control_get_var,
- .fb_set_var = control_set_var,
- .fb_get_cmap = control_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = controlfb_setcolreg,
- .fb_pan_display =control_pan_display,
- .fb_blank = controlfb_blank,
- .fb_mmap = control_mmap,
+ .owner = THIS_MODULE,
+ .fb_set_var = gen_set_var,
+ .fb_check_var = controlfb_check_var,
+ .fb_set_par = controlfb_set_par,
+ .fb_get_cmap = gen_get_cmap,
+ .fb_set_cmap = gen_set_cmap,
+ .fb_setcolreg = controlfb_setcolreg,
+ .fb_pan_display = controlfb_pan_display,
+ .fb_blank = controlfb_blank,
+ .fb_mmap = controlfb_mmap,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
};
@@ -251,87 +208,48 @@ void cleanup_module(void)
}
#endif
-/*********** Providing our information to the user ************/
-
-static int control_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
+/*
+ * Checks a var structure
+ */
+static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
{
- struct fb_info_control *p = (struct fb_info_control *) info;
-
- if(con == -1) {
- control_par_to_fix(&p->par, fix, p);
- } else {
- struct fb_par_control par;
-
- control_var_to_par(&fb_display[con].var, &par, info);
- control_par_to_fix(&par, fix, p);
- }
- return 0;
-}
+ struct fb_par_control par;
+ int err;
-static int control_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct fb_info_control *p = (struct fb_info_control *) info;
+ err = control_var_to_par(var, &par, info);
+ if (err)
+ return err;
+ control_par_to_var(&par, var);
- if(con == -1) {
- control_par_to_var(&p->par, var);
- } else {
- *var = fb_display[con].var;
- }
return 0;
}
-
/*
- * Sets everything according to var
+ * Applies current var to display
*/
-static int control_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+static int controlfb_set_par (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;
- int activate = var->activate;
+ int err;
- if((err = control_var_to_par(var, &par, info))) {
- if (con < 0)
- printk (KERN_ERR "control_set_var: error calling"
- " control_var_to_par: %d.\n", err);
+ if((err = control_var_to_par(&info->var, &par, info))) {
+ printk (KERN_ERR "controlfb_set_par: error calling"
+ " control_var_to_par: %d.\n", err);
return err;
}
- control_par_to_var(&par, var);
-
- if ((activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
- return 0;
-
- disp = (con >= 0) ? &fb_display[con] : info->disp;
+ control_set_hardware(p, &par);
- depthchange = (disp->var.bits_per_pixel != var->bits_per_pixel);
- if(!VAR_MATCH(&disp->var, var)) {
- struct fb_fix_screeninfo fix;
- control_par_to_fix(&par, &fix, p);
- control_par_to_display(&par, disp, &fix, p);
- if(info->changevar)
- (*info->changevar)(con);
- } else
- disp->var = *var;
-
- if (con == info->currcon) {
- control_set_hardware(p, &par);
- if(depthchange) {
- if((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
- return err;
- do_install_cmap(con, info);
- }
- }
+ info->fix.visual = (p->par.cmode == CMODE_8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+ info->fix.line_length = p->par.pitch;
+ info->fix.xpanstep = 32 >> p->par.cmode;
+ info->fix.ypanstep = 1;
return 0;
}
-
/*
* Set screen start address according to var offset values
*/
@@ -347,7 +265,7 @@ static inline void set_screen_start(int xoffset, int yoffset,
}
-static int control_pan_display(struct fb_var_screeninfo *var, int con,
+static int controlfb_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
unsigned int xoffset, hstep;
@@ -369,48 +287,30 @@ static int control_pan_display(struct fb_var_screeninfo *var, int con,
return 0;
}
-static int control_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- if (con == info->currcon) /* current console? */
- return fb_get_cmap(cmap, 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;
-}
/*
* Private mmap since we want to have a different caching on the framebuffer
* for controlfb.
* Note there's no locking in here; it's done in fb_mmap() in fbmem.c.
*/
-static int control_mmap(struct fb_info *info, struct file *file,
+static int controlfb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma)
{
- struct fb_ops *fb = info->fbops;
- struct fb_fix_screeninfo fix;
- struct fb_var_screeninfo var;
unsigned long off, start;
u32 len;
- fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
off = vma->vm_pgoff << PAGE_SHIFT;
/* frame buffer memory */
- start = fix.smem_start;
- len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len);
+ start = info->fix.smem_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.smem_len);
if (off >= len) {
/* memory mapped io */
off -= len;
- fb->fb_get_var(&var, PROC_CONSOLE(info), info);
- if (var.accel_flags)
+ if (info->var.accel_flags)
return -EINVAL;
- start = fix.mmio_start;
- len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len);
+ start = info->fix.mmio_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len);
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
} else {
/* framebuffer */
@@ -428,44 +328,6 @@ static int control_mmap(struct fb_info *info, struct file *file,
return 0;
}
-
-/******************** End of controlfb_ops implementation ******************/
-
-/*
- * low level fbcon ops
- */
-
-static int controlfb_switch(int con, struct fb_info *info)
-{
- struct fb_info_control *p = (struct fb_info_control *)info;
- struct fb_par_control par;
-
- if (info->currcon >= 0 && fb_display[info->currcon].cmap.len)
- fb_get_cmap(&fb_display[info->currcon].cmap, 1, controlfb_getcolreg,
- info);
- info->currcon = con;
-
- fb_display[con].var.activate = FB_ACTIVATE_NOW;
- control_var_to_par(&fb_display[con].var, &par, info);
- control_set_hardware(p, &par);
- control_set_dispsw(&fb_display[con], par.cmode, p);
- do_install_cmap(con, info);
-
- return 1;
-}
-
-
-static int controlfb_updatevar(int con, struct fb_info *info)
-{
- struct fb_var_screeninfo *var = &fb_display[con].var;
- struct fb_info_control *p = (struct fb_info_control *) info;
-
- set_screen_start(var->xoffset, var->yoffset, p);
-
- return 0;
-}
-
-
static int controlfb_blank(int blank_mode, struct fb_info *info)
{
struct fb_info_control *p = (struct fb_info_control *) info;
@@ -498,30 +360,10 @@ static int controlfb_blank(int blank_mode, struct fb_info *info)
return 0;
}
-
-/*
- * low level cmap set/get ops
- */
-
-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<<8) | p->palette[regno].red;
- *green = (p->palette[regno].green<<8) | p->palette[regno].green;
- *blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
- *transp = 0;
- 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;
- u_int i;
__u8 r, g, b;
if (regno > 255)
@@ -531,32 +373,34 @@ static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
g = green >> 8;
b = blue >> 8;
- p->palette[regno].red = r;
- p->palette[regno].green = g;
- p->palette[regno].blue = b;
-
out_8(&p->cmap_regs->addr, regno); /* tell clut what addr to fill */
out_8(&p->cmap_regs->lut, r); /* send one color channel at */
out_8(&p->cmap_regs->lut, g); /* a time... */
out_8(&p->cmap_regs->lut, b);
- if (regno < 16)
+ if (regno < 16) {
+ int i;
switch (p->par.cmode) {
-#ifdef FBCON_HAS_CFB16
- case CMODE_16:
- p->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case CMODE_32:
- i = (regno << 8) | regno;
- p->fbcon_cmap.cfb32[regno] = (i << 16) | i;
- break;
-#endif
+ case CMODE_16:
+ ((u16 *) (info->pseudo_palette))[regno] =
+ (regno << 10) | (regno << 5) | regno;
+ break;
+ case CMODE_32:
+ i = (regno << 8) | regno;
+ ((u32 *) (info->pseudo_palette))[regno] =
+ (i << 16) | i;
+ break;
}
+ }
+
return 0;
}
+
+/******************** End of controlfb_ops implementation ******************/
+
+
+
static void set_control_clock(unsigned char *params)
{
#ifdef CONFIG_ADB_CUDA
@@ -580,7 +424,8 @@ static int __init init_control(struct fb_info_control *p)
{
int full, sense, vmode, cmode, vyres;
struct fb_var_screeninfo var;
-
+ int rc;
+
printk(KERN_INFO "controlfb: ");
full = p->total_vram == 0x400000;
@@ -613,6 +458,10 @@ static int __init init_control(struct fb_info_control *p)
}
}
+ /* Initialize info structure */
+ control_init_info(&p->info, p);
+
+ /* Setup default var */
if (mac_vmode_to_var(vmode, cmode, &var) < 0) {
/* This shouldn't happen! */
printk("mac_vmode_to_var(%d, %d,) failed\n", vmode, cmode);
@@ -631,18 +480,14 @@ try_again:
if (vyres > var.yres)
var.yres_virtual = vyres;
- control_init_info(&p->info, p);
- p->info.currcon = -1;
+ /* Apply default var */
+ p->info.var = var;
var.activate = FB_ACTIVATE_NOW;
+ rc = gen_set_var(&var, -1, &p->info);
+ if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8))
+ goto try_again;
- if (control_set_var(&var, -1, &p->info) < 0) {
- if (vmode != VMODE_640_480_60 || cmode != CMODE_8)
- goto try_again;
- printk(KERN_ERR "controlfb: initilization failed\n");
- return -ENXIO;
- }
-
- p->info.flags = FBINFO_FLAG_DEFAULT;
+ /* Register with fbdev layer */
if (register_framebuffer(&p->info) < 0)
return -ENXIO;
@@ -820,7 +665,7 @@ static int __init control_of_init(struct device_node *dp)
printk(KERN_ERR "expecting 2 address for control (got %d)", dp->n_addrs);
return -ENXIO;
}
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
if (p == 0)
return -ENXIO;
control_fb = p; /* save it for cleanups */
@@ -1164,171 +1009,41 @@ static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeni
var->pixclock >>= par->regvals.clock_params[2];
}
-
-/*
- * init fix according to given par
- */
-static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeninfo *fix,
- struct fb_info_control *p)
-{
- memset(fix, 0, sizeof(*fix));
- strcpy(fix->id, "control");
- fix->mmio_start = p->control_regs_phys;
- fix->mmio_len = sizeof(struct control_regs);
- fix->type = FB_TYPE_PACKED_PIXELS;
-
- fix->xpanstep = 32 >> par->cmode;
- fix->ypanstep = 1;
-
- fix->smem_start = p->frame_buffer_phys + CTRLFB_OFF;
- fix->smem_len = p->total_vram - CTRLFB_OFF;
- fix->visual = (par->cmode == CMODE_8) ?
- FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
- fix->line_length = par->pitch;
-}
-
-/*
- * initialize a portion of struct display which low level driver is responsible
- * for.
- */
-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->type = fix->type;
- disp->can_soft_blank = 1;
- disp->scrollmode = SCROLL_YNOMOVE | SCROLL_YNOPARTIAL;
- disp->ypanstep = fix->ypanstep;
- disp->ywrapstep = fix->ywrapstep;
-
- control_par_to_var(par, &disp->var);
- p->info.screen_base = (char *) p->frame_buffer + CTRLFB_OFF;
- disp->visual = fix->visual;
- disp->line_length = fix->line_length;
- control_set_dispsw(disp, par->cmode, p);
-}
-
-
-/*
- * our own _revc() routines since generic routines don't work for DIRECT Color
- * devices like control
- */
-static void control_cfb16_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes = p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
- for (rows = fontheight(p); rows--; dest += bytes) {
- switch (fontwidth(p)) {
- case 16:
- ((u32 *)dest)[6] ^= 0x3def3def; ((u32 *)dest)[7] ^= 0x3def3def;
- /* FALL THROUGH */
- case 12:
- ((u32 *)dest)[4] ^= 0x3def3def; ((u32 *)dest)[5] ^= 0x3def3def;
- /* FALL THROUGH */
- case 8:
- ((u32 *)dest)[2] ^= 0x3def3def; ((u32 *)dest)[3] ^= 0x3def3def;
- /* FALL THROUGH */
- case 4:
- ((u32 *)dest)[0] ^= 0x3def3def; ((u32 *)dest)[1] ^= 0x3def3def;
- }
- }
-}
-
-static void control_cfb32_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes = p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
- for (rows = fontheight(p); rows--; dest += bytes) {
- switch (fontwidth(p)) {
- case 16:
- ((u32 *)dest)[12] ^= 0x0f0f0f0f; ((u32 *)dest)[13] ^= 0x0f0f0f0f;
- ((u32 *)dest)[14] ^= 0x0f0f0f0f; ((u32 *)dest)[15] ^= 0x0f0f0f0f;
- /* FALL THROUGH */
- case 12:
- ((u32 *)dest)[8] ^= 0x0f0f0f0f; ((u32 *)dest)[9] ^= 0x0f0f0f0f;
- ((u32 *)dest)[10] ^= 0x0f0f0f0f; ((u32 *)dest)[11] ^= 0x0f0f0f0f;
- /* FALL THROUGH */
- case 8:
- ((u32 *)dest)[4] ^= 0x0f0f0f0f; ((u32 *)dest)[5] ^= 0x0f0f0f0f;
- ((u32 *)dest)[6] ^= 0x0f0f0f0f; ((u32 *)dest)[7] ^= 0x0f0f0f0f;
- /* FALL THROUGH */
- case 4:
- ((u32 *)dest)[0] ^= 0x0f0f0f0f; ((u32 *)dest)[1] ^= 0x0f0f0f0f;
- ((u32 *)dest)[2] ^= 0x0f0f0f0f; ((u32 *)dest)[3] ^= 0x0f0f0f0f;
- /* FALL THROUGH */
- }
- }
-}
-
-static struct display_switch control_cfb16 = {
- setup: fbcon_cfb16_setup,
- bmove: fbcon_cfb16_bmove,
- clear: fbcon_cfb16_clear,
- putc: fbcon_cfb16_putc,
- putcs: fbcon_cfb16_putcs,
- revc: control_cfb16_revc,
- clear_margins: fbcon_cfb16_clear_margins,
- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-static struct display_switch control_cfb32 = {
- setup: fbcon_cfb32_setup,
- bmove: fbcon_cfb32_bmove,
- clear: fbcon_cfb32_clear,
- putc: fbcon_cfb32_putc,
- putcs: fbcon_cfb32_putcs,
- revc: control_cfb32_revc,
- clear_margins: fbcon_cfb32_clear_margins,
- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-/*
- * Set struct dispsw according to given cmode
- */
-static void control_set_dispsw(struct display *disp, int cmode, struct fb_info_control *p)
-{
- switch (cmode) {
-#ifdef FBCON_HAS_CFB8
- case CMODE_8:
- disp->dispsw = &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case CMODE_16:
- disp->dispsw = &control_cfb16;
- disp->dispsw_data = p->fbcon_cmap.cfb16;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case CMODE_32:
- disp->dispsw = &control_cfb32;
- disp->dispsw_data = p->fbcon_cmap.cfb32;
- break;
-#endif
- default:
- disp->dispsw = &fbcon_dummy;
- break;
- }
-}
-
-
/*
* Set misc info vars for this driver
*/
static void __init control_init_info(struct fb_info *info, struct fb_info_control *p)
{
+ /* Fill fb_info */
strcpy(info->modename, "control");
+ info->currcon = -1;
+ info->par = &p->par;
info->node = NODEV;
info->fbops = &controlfb_ops;
info->disp = &p->display;
- strcpy(info->fontname, fontname);
+ info->pseudo_palette = p->pseudo_palette;
+ info->flags = FBINFO_FLAG_DEFAULT;
+ strncpy (info->fontname, fontname, sizeof (info->fontname));
+ info->fontname[sizeof (info->fontname) - 1] = 0;
info->changevar = NULL;
- info->switch_con = &controlfb_switch;
- info->updatevar = &controlfb_updatevar;
+ info->display_fg = NULL;
+ info->screen_base = (char *) p->frame_buffer + CTRLFB_OFF;
+ info->changevar = NULL;
+ info->switch_con = gen_switch;
+ info->updatevar = gen_update_var;
+
+ fb_alloc_cmap(&info->cmap, 256, 0);
+
+ /* Fill fix common fields */
+ strcpy(info->fix.id, "control");
+ info->fix.mmio_start = p->control_regs_phys;
+ info->fix.mmio_len = sizeof(struct control_regs);
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.smem_start = p->frame_buffer_phys + CTRLFB_OFF;
+ info->fix.smem_len = p->total_vram - CTRLFB_OFF;
+ info->fix.ywrapstep = 0;
+ info->fix.type_aux = 0;
+ info->fix.accel = FB_ACCEL_NONE;
}
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index 54c9214b9806..79c11de10abf 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -1063,7 +1063,7 @@ int __init cyberfb_init(void)
}
printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10);
+ minor(fb_info.node), fb_info.modename, CyberSize>>10);
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index bf299d99ea67..1809827e3af9 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -15,8 +15,6 @@
#include <linux/fb.h>
#include <linux/module.h>
-#include <video/fbcon.h>
-
/* apollo video HW definitions */
/*
@@ -111,7 +109,6 @@
#endif
static struct fb_info fb_info;
-static struct display disp;
/* frame buffer operations */
@@ -120,13 +117,11 @@ static void dnfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
static struct fb_ops dn_fb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_blank = dnfb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = dnfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
struct fb_var_screeninfo dnfb_var __initdata = {
@@ -239,22 +234,13 @@ unsigned long __init dnfb_init(unsigned long mem_start)
{
int err;
- strcpy(fb_info.modename, dnfb_fix.id);
- fb_info.changevar = NULL;
- fb_info.fontname[0] = 0;
- fb_info.disp = &disp;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_info.node = NODEV;
fb_info.fbops = &dn_fb_ops;
- fb_info.currcon = -1;
fb_info.fix = dnfb_fix;
fb_info.var = dnfb_var;
+ fb_info.screen_base = (u_char *) fb_info.fix.smem_start;
fb_alloc_cmap(&fb_info.cmap, 2, 0);
- gen_set_disp(-1, &fb_info);
-
- fb_info.screen_base = (u_char *) fb_info.fix.smem_start;
err = register_framebuffer(&fb_info);
if (err < 0)
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index d581cb7faf1b..8fa3c2b6e88d 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -517,7 +517,7 @@ int __init e1355fb_init(void)
do_install_cmap(0, &fb_info.gen);
if (register_framebuffer(&fb_info.gen.info) < 0)
return -EINVAL;
- printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", minor(fb_info.gen.info.node),
fb_info.gen.info.modename);
return 0;
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index e10d65f53d69..3b70c0585b48 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -94,16 +94,7 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
int size = len*sizeof(u16);
if (cmap->len != len) {
- if (cmap->red)
- kfree(cmap->red);
- if (cmap->green)
- kfree(cmap->green);
- if (cmap->blue)
- kfree(cmap->blue);
- if (cmap->transp)
- kfree(cmap->transp);
- cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
- cmap->len = 0;
+ fb_dealloc_cmap(cmap);
if (!len)
return 0;
if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
@@ -124,6 +115,29 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
return 0;
}
+/**
+ * fb_dealloc_cmap - deallocate a colormap
+ * @cmap: frame buffer colormap structure
+ *
+ * Deallocates a colormap that was previously allocated with
+ * fb_alloc_cmap().
+ *
+ */
+
+void fb_dealloc_cmap(struct fb_cmap *cmap)
+{
+ if (cmap->red)
+ kfree(cmap->red);
+ if (cmap->green)
+ kfree(cmap->green);
+ if (cmap->blue)
+ kfree(cmap->blue);
+ if (cmap->transp)
+ kfree(cmap->transp);
+
+ cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+ cmap->len = 0;
+}
/**
* fb_copy_cmap - copy a colormap
@@ -181,62 +195,6 @@ void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
}
}
-
-/**
- * fb_get_cmap - get a colormap
- * @cmap: frame buffer colormap
- * @kspc: boolean, 0 copy local, 1 put_user() function
- * @getcolreg: pointer to a function to get a color register
- * @info: frame buffer info structure
- *
- * Get a colormap @cmap for a screen of device @info.
- *
- * Returns negative errno on error, or zero on success.
- *
- */
-
-int fb_get_cmap(struct fb_cmap *cmap, int kspc,
- int (*getcolreg)(u_int, u_int *, u_int *, u_int *, u_int *,
- struct fb_info *),
- struct fb_info *info)
-{
- int i, start;
- u16 *red, *green, *blue, *transp;
- u_int hred, hgreen, hblue, htransp;
-
- red = cmap->red;
- green = cmap->green;
- blue = cmap->blue;
- transp = cmap->transp;
- start = cmap->start;
- if (start < 0)
- return -EINVAL;
- for (i = 0; i < cmap->len; i++) {
- if (getcolreg(start++, &hred, &hgreen, &hblue, &htransp, info))
- return 0;
- if (kspc) {
- *red = hred;
- *green = hgreen;
- *blue = hblue;
- if (transp)
- *transp = htransp;
- } else {
- put_user(hred, red);
- put_user(hgreen, green);
- put_user(hblue, blue);
- if (transp)
- put_user(htransp, transp);
- }
- red++;
- green++;
- blue++;
- if (transp)
- transp++;
- }
- return 0;
-}
-
-
/**
* fb_set_cmap - set the colormap
* @cmap: frame buffer colormap structure
@@ -352,8 +310,8 @@ void fb_invert_cmaps(void)
*/
EXPORT_SYMBOL(fb_alloc_cmap);
+EXPORT_SYMBOL(fb_dealloc_cmap);
EXPORT_SYMBOL(fb_copy_cmap);
-EXPORT_SYMBOL(fb_get_cmap);
EXPORT_SYMBOL(fb_set_cmap);
EXPORT_SYMBOL(fb_default_cmap);
EXPORT_SYMBOL(fb_invert_cmaps);
diff --git a/drivers/video/fbcon-accel.c b/drivers/video/fbcon-accel.c
deleted file mode 100644
index 27119e32c5dc..000000000000
--- a/drivers/video/fbcon-accel.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * linux/drivers/video/fbcon-accel.c -- Framebuffer accel console wrapper
- *
- * Created 20 Feb 2001 by James Simmons <jsimmons@users.sf.net>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include "fbcon-accel.h"
-
-void fbcon_accel_setup(struct display *p)
-{
- p->next_line = p->fb_info->fix.line_length;
- p->next_plane = 0;
-}
-
-void fbcon_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- struct fb_info *info = p->fb_info;
- struct fb_copyarea area;
-
- area.sx = sx * fontwidth(p);
- area.sy = sy * fontheight(p);
- area.dx = dx * fontwidth(p);
- area.dy = dy * fontheight(p);
- area.height = height * fontheight(p);
- area.width = width * fontwidth(p);
-
- info->fbops->fb_copyarea(info, &area);
-}
-
-void fbcon_accel_clear(struct vc_data *vc, struct display *p, int sy, int sx,
- int height, int width)
-{
- struct fb_info *info = p->fb_info;
- struct fb_fillrect region;
-
- region.color = attr_bgcol_ec(p,vc);
- region.dx = sx * fontwidth(p);
- region.dy = sy * fontheight(p);
- region.width = width * fontwidth(p);
- region.height = height * fontheight(p);
- region.rop = ROP_COPY;
-
- info->fbops->fb_fillrect(info, &region);
-}
-
-void fbcon_accel_putc(struct vc_data *vc, struct display *p, int c, int yy,
- int xx)
-{
- struct fb_info *info = p->fb_info;
- unsigned short charmask = p->charmask;
- unsigned int width = ((fontwidth(p)+7)>>3);
- struct fb_image image;
-
- image.fg_color = attr_fgcol(p, c);
- image.bg_color = attr_bgcol(p, c);
- image.dx = xx * fontwidth(p);
- image.dy = yy * fontheight(p);
- image.width = fontwidth(p);
- image.height = fontheight(p);
- image.depth = 1;
- image.data = p->fontdata + (c & charmask)*fontheight(p)*width;
-
- info->fbops->fb_imageblit(info, &image);
-}
-
-void fbcon_accel_putcs(struct vc_data *vc, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- struct fb_info *info = p->fb_info;
- unsigned short charmask = p->charmask;
- unsigned int width = ((fontwidth(p)+7)>>3);
- struct fb_image image;
-
- image.fg_color = attr_fgcol(p, *s);
- image.bg_color = attr_bgcol(p, *s);
- image.dx = xx * fontwidth(p);
- image.dy = yy * fontheight(p);
- image.width = fontwidth(p);
- image.height = fontheight(p);
- image.depth = 1;
-
- while (count--) {
- image.data = p->fontdata +
- (scr_readw(s++) & charmask) * fontheight(p) * width;
- info->fbops->fb_imageblit(info, &image);
- image.dx += fontwidth(p);
- }
-}
-
-void fbcon_accel_revc(struct display *p, int xx, int yy)
-{
- struct fb_info *info = p->fb_info;
- struct fb_fillrect region;
-
- region.color = attr_fgcol_ec(p, p->conp);
- region.dx = xx * fontwidth(p);
- region.dy = yy * fontheight(p);
- region.width = fontwidth(p);
- region.height = fontheight(p);
- region.rop = ROP_XOR;
-
- info->fbops->fb_fillrect(info, &region);
-}
-
-void fbcon_accel_clear_margins(struct vc_data *vc, struct display *p,
- int bottom_only)
-{
- struct fb_info *info = p->fb_info;
- unsigned int cw = fontwidth(p);
- unsigned int ch = fontheight(p);
- unsigned int rw = info->var.xres % cw;
- unsigned int bh = info->var.yres % ch;
- unsigned int rs = info->var.xres - rw;
- unsigned int bs = info->var.yres - bh;
- struct fb_fillrect region;
-
- region.color = attr_bgcol_ec(p,vc);
- region.rop = ROP_COPY;
-
- if (rw && !bottom_only) {
- region.dx = info->var.xoffset + rs;
- region.dy = 0;
- region.width = rw;
- region.height = info->var.yres_virtual;
- info->fbops->fb_fillrect(info, &region);
- }
-
- if (bh) {
- region.dx = info->var.xoffset;
- region.dy = info->var.yoffset + bs;
- region.width = rs;
- region.height = bh;
- info->fbops->fb_fillrect(info, &region);
- }
-}
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_accel = {
- .setup = fbcon_accel_setup,
- .bmove = fbcon_accel_bmove,
- .clear = fbcon_accel_clear,
- .putc = fbcon_accel_putc,
- .putcs = fbcon_accel_putcs,
- .revc = fbcon_accel_revc,
- .clear_margins =fbcon_accel_clear_margins,
- .fontwidthmask =FONTWIDTHRANGE(1, 16)
-};
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_accel);
-EXPORT_SYMBOL(fbcon_accel_setup);
-EXPORT_SYMBOL(fbcon_accel_bmove);
-EXPORT_SYMBOL(fbcon_accel_clear);
-EXPORT_SYMBOL(fbcon_accel_putc);
-EXPORT_SYMBOL(fbcon_accel_putcs);
-EXPORT_SYMBOL(fbcon_accel_revc);
-EXPORT_SYMBOL(fbcon_accel_clear_margins);
diff --git a/drivers/video/fbcon-accel.h b/drivers/video/fbcon-accel.h
deleted file mode 100644
index 80944b6e04c1..000000000000
--- a/drivers/video/fbcon-accel.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * FBcon low-level driver that is a wrapper for the accel engine.
- */
-
-#ifndef _VIDEO_FBCON_ACCEL_H
-#define _VIDEO_FBCON_ACCEL_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_ACCEL) || defined(CONFIG_FBCON_ACCEL_MODULE)
-#define FBCON_HAS_ACCEL
-#endif
-#else
-#if defined(CONFIG_FBCON_ACCEL)
-#define FBCON_HAS_ACCEL
-#endif
-#endif
-
-extern struct display_switch fbcon_accel;
-extern void fbcon_accel_setup(struct display *p);
-extern void fbcon_accel_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width);
-extern void fbcon_accel_clear(struct vc_data *vc, struct display *p, int sy,
- int sx, int height, int width);
-extern void fbcon_accel_putc(struct vc_data *vc, struct display *p, int c,
- int yy, int xx);
-extern void fbcon_accel_putcs(struct vc_data *vc, struct display *p,
- const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_accel_revc(struct display *p, int xx, int yy);
-extern void fbcon_accel_clear_margins(struct vc_data *vc, struct display *p,
- int bottom_only);
-
-#endif /* _VIDEO_FBCON_ACCEL_H */
diff --git a/drivers/video/fbcon-afb.c b/drivers/video/fbcon-afb.c
deleted file mode 100644
index 6afee164b609..000000000000
--- a/drivers/video/fbcon-afb.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * linux/drivers/video/afb.c -- Low level frame buffer operations for
- * bitplanes à la Amiga
- *
- * Created 5 Apr 1997 by 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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-afb.h>
-
-
- /*
- * Bitplanes à la Amiga
- */
-
-static u8 expand_table[1024] = {
- /* bg = fg = 0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* bg = 0, fg = 1 */
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
- /* bg = 1, fg = 0 */
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
- 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
- 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
- 0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
- 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
- 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
- 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
- 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
- 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
- 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
- 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
- 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
- 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
- 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
- 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
- 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
- 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
- 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
- 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
- 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
- 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
- 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
- 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
- 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
- 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
- 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
- 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
- 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
- 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
- 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
- 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
- /* bg = fg = 1 */
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-void fbcon_afb_setup(struct display *p)
-{
- if (p->fb_info->fix.line_length)
- p->next_line = p->fb_info->fix.line_length;
- else
- p->next_line = p->var.xres_virtual>>3;
- p->next_plane = p->var.yres_virtual*p->next_line;
-}
-
-void fbcon_afb_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- u8 *src, *dest, *src0, *dest0;
- u_short i, j;
-
- if (sx == 0 && dx == 0 && width == p->next_line) {
- src = p->fb_info->screen_base+sy*fontheight(p)*width;
- dest = p->fb_info->screen_base+dy*fontheight(p)*width;
- i = p->var.bits_per_pixel;
- do {
- fb_memmove(dest, src, height*fontheight(p)*width);
- src += p->next_plane;
- dest += p->next_plane;
- } while (--i);
- } else if (dy <= sy) {
- src0 = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
- dest0 = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
- i = p->var.bits_per_pixel;
- do {
- src = src0;
- dest = dest0;
- j = height*fontheight(p);
- do {
- fb_memmove(dest, src, width);
- src += p->next_line;
- dest += p->next_line;
- } while (--j);
- src0 += p->next_plane;
- dest0 += p->next_plane;
- } while (--i);
- } else {
- src0 = p->fb_info->screen_base+(sy+height)*fontheight(p)*p->next_line+sx;
- dest0 = p->fb_info->screen_base+(dy+height)*fontheight(p)*p->next_line+dx;
- i = p->var.bits_per_pixel;
- do {
- src = src0;
- dest = dest0;
- j = height*fontheight(p);
- do {
- src -= p->next_line;
- dest -= p->next_line;
- fb_memmove(dest, src, width);
- } while (--j);
- src0 += p->next_plane;
- dest0 += p->next_plane;
- } while (--i);
- }
-}
-
-void fbcon_afb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest, *dest0;
- u_short i, j;
- int bg;
-
- dest0 = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-
- bg = attr_bgcol_ec(p,conp);
- i = p->var.bits_per_pixel;
- do {
- dest = dest0;
- j = height*fontheight(p);
- do {
- if (bg & 1)
- fb_memset255(dest, width);
- else
- fb_memclear(dest, width);
- dest += p->next_line;
- } while (--j);
- bg >>= 1;
- dest0 += p->next_plane;
- } while (--i);
-}
-
-void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest, *dest0, *cdat, *cdat0, *expand;
- u_short i, j;
- int fg, bg;
-
- dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- cdat0 = p->fontdata+(c&p->charmask)*fontheight(p);
- fg = attr_fgcol(p,c);
- bg = attr_bgcol(p,c);
-
- i = p->var.bits_per_pixel;
- do {
- dest = dest0;
- cdat = cdat0;
- expand = expand_table;
- if (bg & 1)
- expand += 512;
- if (fg & 1)
- expand += 256;
- j = fontheight(p);
- do {
- *dest = expand[*cdat++];
- dest += p->next_line;
- } while (--j);
- bg >>= 1;
- fg >>= 1;
- dest0 += p->next_plane;
- } while (--i);
-}
-
- /*
- * I've split the console character loop in two parts
- * (cfr. fbcon_putcs_ilbm())
- */
-
-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;
- u16 c1, c2, c3, c4;
- int fg0, bg0, fg, bg;
-
- dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- c1 = scr_readw(s);
- fg0 = attr_fgcol(p, c1);
- bg0 = attr_bgcol(p, c1);
-
- while (count--)
- if (xx&3 || count < 3) { /* Slow version */
- c1 = scr_readw(s++) & p->charmask;
- dest1 = dest0++;
- xx++;
-
- cdat10 = p->fontdata+c1*fontheight(p);
- fg = fg0;
- bg = bg0;
-
- i = p->var.bits_per_pixel;
- do {
- dest = dest1;
- cdat1 = cdat10;
- expand = expand_table;
- if (bg & 1)
- expand += 512;
- if (fg & 1)
- expand += 256;
- j = fontheight(p);
- do {
- *dest = expand[*cdat1++];
- dest += p->next_line;
- } while (--j);
- bg >>= 1;
- fg >>= 1;
- dest1 += p->next_plane;
- } while (--i);
- } else { /* Fast version */
- c1 = scr_readw(&s[0]) & p->charmask;
- c2 = scr_readw(&s[1]) & p->charmask;
- c3 = scr_readw(&s[2]) & p->charmask;
- c4 = scr_readw(&s[3]) & p->charmask;
-
- dest1 = dest0;
- cdat10 = p->fontdata+c1*fontheight(p);
- cdat20 = p->fontdata+c2*fontheight(p);
- cdat30 = p->fontdata+c3*fontheight(p);
- cdat40 = p->fontdata+c4*fontheight(p);
- fg = fg0;
- bg = bg0;
-
- i = p->var.bits_per_pixel;
- do {
- dest = dest1;
- cdat1 = cdat10;
- cdat2 = cdat20;
- cdat3 = cdat30;
- cdat4 = cdat40;
- expand = expand_table;
- if (bg & 1)
- expand += 512;
- if (fg & 1)
- expand += 256;
- j = fontheight(p);
- do {
-#if defined(__BIG_ENDIAN)
- *(u32 *)dest = expand[*cdat1++]<<24 |
- expand[*cdat2++]<<16 |
- expand[*cdat3++]<<8 |
- expand[*cdat4++];
-#elif defined(__LITTLE_ENDIAN)
- *(u32 *)dest = expand[*cdat1++] |
- expand[*cdat2++]<<8 |
- expand[*cdat3++]<<16 |
- expand[*cdat4++]<<24;
-#else
-#error FIXME: No endianness??
-#endif
- dest += p->next_line;
- } while (--j);
- bg >>= 1;
- fg >>= 1;
- dest1 += p->next_plane;
- } while (--i);
- s += 4;
- dest0 += 4;
- xx += 4;
- count -= 3;
- }
-}
-
-void fbcon_afb_revc(struct display *p, int xx, int yy)
-{
- u8 *dest, *dest0;
- u_short i, j;
- int mask;
-
- dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- mask = p->fgcol ^ p->bgcol;
-
- /*
- * This should really obey the individual character's
- * background and foreground colors instead of simply
- * inverting.
- */
-
- i = p->var.bits_per_pixel;
- do {
- if (mask & 1) {
- dest = dest0;
- j = fontheight(p);
- do {
- *dest = ~*dest;
- dest += p->next_line;
- } while (--j);
- }
- mask >>= 1;
- dest0 += p->next_plane;
- } while (--i);
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_afb = {
- setup: fbcon_afb_setup,
- bmove: fbcon_afb_bmove,
- clear: fbcon_afb_clear,
- putc: fbcon_afb_putc,
- putcs: fbcon_afb_putcs,
- revc: fbcon_afb_revc,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_afb);
-EXPORT_SYMBOL(fbcon_afb_setup);
-EXPORT_SYMBOL(fbcon_afb_bmove);
-EXPORT_SYMBOL(fbcon_afb_clear);
-EXPORT_SYMBOL(fbcon_afb_putc);
-EXPORT_SYMBOL(fbcon_afb_putcs);
-EXPORT_SYMBOL(fbcon_afb_revc);
diff --git a/drivers/video/fbcon-cfb16.c b/drivers/video/fbcon-cfb16.c
deleted file mode 100644
index 254e559fb591..000000000000
--- a/drivers/video/fbcon-cfb16.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * linux/drivers/video/cfb16.c -- Low level frame buffer operations for 16 bpp
- * truecolor packed pixels
- *
- * Created 5 Apr 1997 by 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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-#include <asm/io.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb16.h>
-
-
- /*
- * 16 bpp packed pixels
- */
-
-static u32 tab_cfb16[] = {
-#if defined(__BIG_ENDIAN)
- 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
-#elif defined(__LITTLE_ENDIAN)
- 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
-#else
-#error FIXME: No endianness??
-#endif
-};
-
-void fbcon_cfb16_setup(struct display *p)
-{
- p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual<<1;
- p->next_plane = 0;
-}
-
-void fbcon_cfb16_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src, *dst;
-
- if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes) {
- fb_memmove(p->fb_info->screen_base + dy * linesize,
- p->fb_info->screen_base + sy * linesize,
- height * linesize);
- return;
- }
- if (fontwidthlog(p)) {
- sx <<= fontwidthlog(p)+1;
- dx <<= fontwidthlog(p)+1;
- width <<= fontwidthlog(p)+1;
- } else {
- sx *= fontwidth(p)*2;
- dx *= fontwidth(p)*2;
- width *= fontwidth(p)*2;
- }
- if (dy < sy || (dy == sy && dx < sx)) {
- src = p->fb_info->screen_base + sy * linesize + sx;
- dst = p->fb_info->screen_base + dy * linesize + dx;
- for (rows = height * fontheight(p); rows--;) {
- fb_memmove(dst, src, width);
- src += bytes;
- dst += bytes;
- }
- } else {
- src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
- dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
- for (rows = height * fontheight(p); rows--;) {
- fb_memmove(dst, src, width);
- src -= bytes;
- dst -= bytes;
- }
- }
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u32 data,
- int linesize)
-{
- int i;
-
- data |= data<<16;
-
- while (height-- > 0) {
- u32 *p = (u32 *)dest;
- for (i = 0; i < width/4; i++) {
- fb_writel(data, p++);
- fb_writel(data, p++);
- }
- if (width & 2)
- fb_writel(data, p++);
- if (width & 1)
- fb_writew(data, (u16*)p);
- dest += linesize;
- }
-}
-
-void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest;
- int bytes = p->next_line, lines = height * fontheight(p);
- u32 bgx;
-
- dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
-
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- width *= fontwidth(p)/4;
- if (width * 8 == bytes)
- rectfill(dest, lines * width * 4, 1, bgx, bytes);
- else
- rectfill(dest, width * 4, lines, bgx, bytes);
-}
-
-void fbcon_cfb16_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest, *cdat, bits;
- int bytes = p->next_line, rows;
- u32 eorx, fgx, bgx;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
-
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
- fgx |= (fgx << 16);
- bgx |= (bgx << 16);
- eorx = fgx ^ bgx;
-
- switch (fontwidth(p)) {
- case 4:
- case 8:
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- for (rows = fontheight(p); rows--; dest += bytes) {
- bits = *cdat++;
- fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
- fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
- if (fontwidth(p) == 8) {
- fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
- fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
- }
- }
- break;
- case 12:
- case 16:
- cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
- for (rows = fontheight(p); rows--; dest += bytes) {
- bits = *cdat++;
- fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
- fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
- fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
- fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
- bits = *cdat++;
- fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
- fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
- if (fontwidth(p) == 16) {
- fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
- fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
- }
- }
- break;
- }
-}
-
-void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *cdat, *dest, *dest0;
- u16 c;
- int rows, bytes = p->next_line;
- u32 eorx, fgx, bgx;
-
- dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
- c = scr_readw(s);
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
- fgx |= (fgx << 16);
- bgx |= (bgx << 16);
- eorx = fgx ^ bgx;
-
- switch (fontwidth(p)) {
- case 4:
- case 8:
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata + c * fontheight(p);
- for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
- u8 bits = *cdat++;
- fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
- fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
- if (fontwidth(p) == 8) {
- fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
- fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
- }
- }
- dest0 += fontwidth(p)*2;;
- }
- break;
- case 12:
- case 16:
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata + (c * fontheight(p) << 1);
- for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
- u8 bits = *cdat++;
- fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
- fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
- fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
- fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
- bits = *cdat++;
- fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
- fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
- if (fontwidth(p) == 16) {
- fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
- fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
- }
- }
- dest0 += fontwidth(p)*2;
- }
- break;
- }
-}
-
-void fbcon_cfb16_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes = p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
- for (rows = fontheight(p); rows--; dest += bytes) {
- switch (fontwidth(p)) {
- case 16:
- fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
- fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
- /* FALL THROUGH */
- case 12:
- fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
- fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
- /* FALL THROUGH */
- case 8:
- fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
- fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
- /* FALL THROUGH */
- case 4:
- fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
- fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
- }
- }
-}
-
-void fbcon_cfb16_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- int bytes = p->next_line;
- u32 bgx;
-
- unsigned int right_start = conp->vc_cols*fontwidth(p);
- unsigned int bottom_start = conp->vc_rows*fontheight(p);
- unsigned int right_width, bottom_width;
-
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- if (!bottom_only && (right_width = p->var.xres-right_start))
- rectfill(p->fb_info->screen_base+right_start*2, right_width,
- p->var.yres_virtual, bgx, bytes);
- if ((bottom_width = p->var.yres-bottom_start))
- rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
- right_start, bottom_width, bgx, bytes);
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_cfb16 = {
- setup: fbcon_cfb16_setup,
- bmove: fbcon_cfb16_bmove,
- clear: fbcon_cfb16_clear,
- putc: fbcon_cfb16_putc,
- putcs: fbcon_cfb16_putcs,
- revc: fbcon_cfb16_revc,
- clear_margins: fbcon_cfb16_clear_margins,
- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_cfb16);
-EXPORT_SYMBOL(fbcon_cfb16_setup);
-EXPORT_SYMBOL(fbcon_cfb16_bmove);
-EXPORT_SYMBOL(fbcon_cfb16_clear);
-EXPORT_SYMBOL(fbcon_cfb16_putc);
-EXPORT_SYMBOL(fbcon_cfb16_putcs);
-EXPORT_SYMBOL(fbcon_cfb16_revc);
-EXPORT_SYMBOL(fbcon_cfb16_clear_margins);
diff --git a/drivers/video/fbcon-cfb2.c b/drivers/video/fbcon-cfb2.c
deleted file mode 100644
index e4896a6ce9e3..000000000000
--- a/drivers/video/fbcon-cfb2.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * linux/drivers/video/cfb2.c -- Low level frame buffer operations for 2 bpp
- * packed pixels
- *
- * Created 26 Dec 1997 by Michael Schmitz
- * Based on cfb4.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb2.h>
-
-
- /*
- * 2 bpp packed pixels
- */
-
- /*
- * IFF the font is even pixel aligned (that is to say each
- * character start is a byte start in the pixel pairs). That
- * avoids us having to mask bytes and means we won't be here
- * all week. On a MacII that matters _lots_
- */
-
-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
-};
-
-
-void fbcon_cfb2_setup(struct display *p)
-{
- p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual>>2;
- p->next_plane = 0;
-}
-
-void fbcon_cfb2_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src,*dst;
-
- if (sx == 0 && dx == 0 && width * 2 == bytes) {
- fb_memmove(p->fb_info->screen_base + dy * linesize,
- p->fb_info->screen_base + sy * linesize,
- height * linesize);
- }
- else {
- if (dy < sy || (dy == sy && dx < sx)) {
- src = p->fb_info->screen_base + sy * linesize + sx * 2;
- dst = p->fb_info->screen_base + dy * linesize + dx * 2;
- for (rows = height * fontheight(p) ; rows-- ;) {
- fb_memmove(dst, src, width * 2);
- src += bytes;
- dst += bytes;
- }
- }
- else {
- src = p->fb_info->screen_base + (sy+height) * linesize + sx * 2 - bytes;
- dst = p->fb_info->screen_base + (dy+height) * linesize + dx * 2 - bytes;
- for (rows = height * fontheight(p) ; rows-- ;) {
- fb_memmove(dst, src, width * 2);
- src -= bytes;
- dst -= bytes;
- }
- }
- }
-}
-
-void fbcon_cfb2_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 * fontheight(p), rows, i;
- u32 bgx;
-
- dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * 2;
-
- bgx=attr_bgcol_ec(p,conp);
- bgx |= (bgx << 2); /* expand the colour to 16 bits */
- bgx |= (bgx << 4);
- bgx |= (bgx << 8);
-
- if (sx == 0 && width * 2 == bytes) {
- for (i = 0 ; i < lines * width ; i++) {
- fb_writew (bgx, dest);
- dest+=2;
- }
- } else {
- dest0=dest;
- for (rows = lines; rows-- ; dest0 += bytes) {
- dest=dest0;
- for (i = 0 ; i < width ; i++) {
- /* memset ?? */
- fb_writew (bgx, dest);
- dest+=2;
- }
- }
- }
-}
-
-void fbcon_cfb2_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest,*cdat;
- int bytes=p->next_line,rows;
- u32 eorx,fgx,bgx;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 2;
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-
- 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);
- bgx |= (bgx << 4);
- eorx = fgx ^ bgx;
-
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- fb_writeb((nibbletab_cfb2[*cdat >> 4] & eorx) ^ bgx, dest+0);
- fb_writeb((nibbletab_cfb2[*cdat++ & 0xf] & eorx) ^ bgx, dest+1);
- }
-}
-
-void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
- int count, int yy, int xx)
-{
- u8 *cdat, *dest, *dest0;
- u16 c;
- int rows,bytes=p->next_line;
- u32 eorx, fgx, bgx;
-
- dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 2;
- c = scr_readw(s);
- fgx = 3/*attr_fgcol(p, c)*/;
- bgx = attr_bgcol(p, c);
- fgx |= (fgx << 2);
- fgx |= (fgx << 4);
- bgx |= (bgx << 2);
- bgx |= (bgx << 4);
- eorx = fgx ^ bgx;
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata + c * fontheight(p);
-
- for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
- fb_writeb((nibbletab_cfb2[*cdat >> 4] & eorx) ^ bgx, dest+0);
- fb_writeb((nibbletab_cfb2[*cdat++ & 0xf] & eorx) ^ bgx, dest+1);
- }
- dest0+=2;
- }
-}
-
-void fbcon_cfb2_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes=p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 2;
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- fb_writew(fb_readw(dest) ^ 0xffff, dest);
- }
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_cfb2 = {
- setup: fbcon_cfb2_setup,
- bmove: fbcon_cfb2_bmove,
- clear: fbcon_cfb2_clear,
- putc: fbcon_cfb2_putc,
- putcs: fbcon_cfb2_putcs,
- revc: fbcon_cfb2_revc,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_cfb2);
-EXPORT_SYMBOL(fbcon_cfb2_setup);
-EXPORT_SYMBOL(fbcon_cfb2_bmove);
-EXPORT_SYMBOL(fbcon_cfb2_clear);
-EXPORT_SYMBOL(fbcon_cfb2_putc);
-EXPORT_SYMBOL(fbcon_cfb2_putcs);
-EXPORT_SYMBOL(fbcon_cfb2_revc);
diff --git a/drivers/video/fbcon-cfb24.c b/drivers/video/fbcon-cfb24.c
deleted file mode 100644
index 878bac753eb5..000000000000
--- a/drivers/video/fbcon-cfb24.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * linux/drivers/video/cfb24.c -- Low level frame buffer operations for 24 bpp
- * truecolor packed pixels
- *
- * Created 7 Mar 1998 by 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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb24.h>
-
-
- /*
- * 24 bpp packed pixels
- */
-
-void fbcon_cfb24_setup(struct display *p)
-{
- struct fb_info *info = p->fb_info;
-
- p->next_line = info->fix.line_length ? info->fix.line_length : p->var.xres_virtual*3;
- p->next_plane = 0;
-}
-
-void fbcon_cfb24_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src, *dst;
-
- if (sx == 0 && dx == 0 && width * fontwidth(p) * 3 == bytes) {
- fb_memmove(p->fb_info->screen_base + dy * linesize,
- p->fb_info->screen_base + sy * linesize,
- height * linesize);
- return;
- }
- if (fontwidthlog(p)) {
- sx <<= fontwidthlog(p);
- dx <<= fontwidthlog(p);
- width <<= fontwidthlog(p);
- } else {
- sx *= fontwidth(p);
- dx *= fontwidth(p);
- width *= fontwidth(p);
- }
- sx *= 3; dx *= 3; width *= 3;
- if (dy < sy || (dy == sy && dx < sx)) {
- src = p->fb_info->screen_base + sy * linesize + sx;
- dst = p->fb_info->screen_base + dy * linesize + dx;
- for (rows = height * fontheight(p); rows--;) {
- fb_memmove(dst, src, width);
- src += bytes;
- dst += bytes;
- }
- } else {
- src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
- dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
- for (rows = height * fontheight(p); rows--;) {
- fb_memmove(dst, src, width);
- src -= bytes;
- dst -= bytes;
- }
- }
-}
-
-#if defined(__BIG_ENDIAN)
-#define convert4to3(in1, in2, in3, in4, out1, out2, out3) \
- do { \
- out1 = (in1<<8) | (in2>>16); \
- out2 = (in2<<16) | (in3>>8); \
- out3 = (in3<<24) | in4; \
- } while (0);
-#elif defined(__LITTLE_ENDIAN)
-#define convert4to3(in1, in2, in3, in4, out1, out2, out3) \
- do { \
- out1 = in1 | (in2<<24); \
- out2 = (in2>> 8) | (in3<<16); \
- out3 = (in3>>16) | (in4<< 8); \
- } while (0);
-#else
-#error FIXME: No endianness??
-#endif
-
-static inline void store4pixels(u32 d1, u32 d2, u32 d3, u32 d4, u32 *dest)
-{
- u32 o1, o2, o3;
- convert4to3(d1, d2, d3, d4, o1, o2, o3);
- fb_writel (o1, dest++);
- fb_writel (o2, dest++);
- fb_writel (o3, dest);
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u32 data,
- int linesize)
-{
- u32 d1, d2, d3;
- int i;
-
- convert4to3(data, data, data, data, d1, d2, d3);
- while (height-- > 0) {
- u32 *p = (u32 *)dest;
- for (i = 0; i < width/4; i++) {
- fb_writel(d1, p++);
- fb_writel(d2, p++);
- fb_writel(d3, p++);
- }
- dest += linesize;
- }
-}
-
-void fbcon_cfb24_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest;
- int bytes = p->next_line, lines = height * fontheight(p);
- u32 bgx;
-
- dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 3;
-
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- width *= fontwidth(p)/4;
- if (width * 12 == bytes)
- rectfill(dest, lines * width * 4, 1, bgx, bytes);
- else
- rectfill(dest, width * 4, lines, bgx, bytes);
-}
-
-void fbcon_cfb24_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest, *cdat, bits;
- int bytes = p->next_line, rows;
- u32 eorx, fgx, bgx, d1, d2, d3, d4;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
- if (fontwidth(p) <= 8)
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- else
- cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
- eorx = fgx ^ bgx;
-
- for (rows = fontheight(p); 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);
- if (fontwidth(p) < 8)
- 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+12));
- if (fontwidth(p) < 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 (fontwidth(p) < 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+36));
- }
-}
-
-void fbcon_cfb24_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *cdat, *dest, *dest0, bits;
- u16 c;
- int rows, bytes = p->next_line;
- u32 eorx, fgx, bgx, d1, d2, d3, d4;
-
- dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
- c = scr_readw(s);
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
- eorx = fgx ^ bgx;
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- if (fontwidth(p) <= 8)
- cdat = p->fontdata + c * fontheight(p);
-
- else
- cdat = p->fontdata + (c * fontheight(p) << 1);
- for (rows = fontheight(p), 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);
- if (fontwidth(p) < 8)
- 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+12));
- if (fontwidth(p) < 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 (fontwidth(p) < 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+36));
- }
- dest0 += fontwidth(p)*3;
- }
-}
-
-void fbcon_cfb24_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes = p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
- for (rows = fontheight(p); rows--; dest += bytes) {
- switch (fontwidth(p)) {
- case 16:
- fb_writel(fb_readl(dest+36) ^ 0xffffffff, dest+36);
- fb_writel(fb_readl(dest+40) ^ 0xffffffff, dest+40);
- fb_writel(fb_readl(dest+44) ^ 0xffffffff, dest+44);
- /* FALL THROUGH */
- case 12:
- fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
- fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
- fb_writel(fb_readl(dest+32) ^ 0xffffffff, dest+32);
- /* FALL THROUGH */
- case 8:
- fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
- fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
- fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
- /* FALL THROUGH */
- case 4:
- fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
- fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
- fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
- }
- }
-}
-
-void fbcon_cfb24_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- int bytes = p->next_line;
- u32 bgx;
-
- unsigned int right_start = conp->vc_cols*fontwidth(p);
- unsigned int bottom_start = conp->vc_rows*fontheight(p);
- unsigned int right_width, bottom_width;
-
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- if (!bottom_only && (right_width = p->var.xres-right_start))
- rectfill(p->fb_info->screen_base+right_start*3, right_width,
- p->var.yres_virtual, bgx, bytes);
- if ((bottom_width = p->var.yres-bottom_start))
- rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
- right_start, bottom_width, bgx, bytes);
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_cfb24 = {
- setup: fbcon_cfb24_setup,
- bmove: fbcon_cfb24_bmove,
- clear: fbcon_cfb24_clear,
- putc: fbcon_cfb24_putc,
- putcs: fbcon_cfb24_putcs,
- revc: fbcon_cfb24_revc,
- clear_margins: fbcon_cfb24_clear_margins,
- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_cfb24);
-EXPORT_SYMBOL(fbcon_cfb24_setup);
-EXPORT_SYMBOL(fbcon_cfb24_bmove);
-EXPORT_SYMBOL(fbcon_cfb24_clear);
-EXPORT_SYMBOL(fbcon_cfb24_putc);
-EXPORT_SYMBOL(fbcon_cfb24_putcs);
-EXPORT_SYMBOL(fbcon_cfb24_revc);
-EXPORT_SYMBOL(fbcon_cfb24_clear_margins);
diff --git a/drivers/video/fbcon-cfb32.c b/drivers/video/fbcon-cfb32.c
deleted file mode 100644
index 76e703610960..000000000000
--- a/drivers/video/fbcon-cfb32.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * linux/drivers/video/cfb32.c -- Low level frame buffer operations for 32 bpp
- * truecolor packed pixels
- *
- * 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 COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb32.h>
-
-
- /*
- * 32 bpp packed pixels
- */
-
-void fbcon_cfb32_setup(struct display *p)
-{
- p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual<<2;
- p->next_plane = 0;
-}
-
-void fbcon_cfb32_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src, *dst;
-
- if (sx == 0 && dx == 0 && width * fontwidth(p) * 4 == bytes) {
- fb_memmove(p->fb_info->screen_base + dy * linesize,
- p->fb_info->screen_base + sy * linesize,
- height * linesize);
- return;
- }
- if (fontwidthlog(p)) {
- sx <<= fontwidthlog(p)+2;
- dx <<= fontwidthlog(p)+2;
- width <<= fontwidthlog(p)+2;
- } else {
- sx *= fontwidth(p)*4;
- dx *= fontwidth(p)*4;
- width *= fontwidth(p)*4;
- }
- if (dy < sy || (dy == sy && dx < sx)) {
- src = p->fb_info->screen_base + sy * linesize + sx;
- dst = p->fb_info->screen_base + dy * linesize + dx;
- for (rows = height * fontheight(p); rows--;) {
- fb_memmove(dst, src, width);
- src += bytes;
- dst += bytes;
- }
- } else {
- src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
- dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
- for (rows = height * fontheight(p); rows--;) {
- fb_memmove(dst, src, width);
- src -= bytes;
- dst -= bytes;
- }
- }
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u32 data,
- int linesize)
-{
- int i;
-
- while (height-- > 0) {
- u32 *p = (u32 *)dest;
- for (i = 0; i < width/4; i++) {
- fb_writel(data, p++);
- fb_writel(data, p++);
- fb_writel(data, p++);
- fb_writel(data, p++);
- }
- if (width & 2) {
- fb_writel(data, p++);
- fb_writel(data, p++);
- }
- if (width & 1)
- fb_writel(data, p++);
- dest += linesize;
- }
-}
-
-void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest;
- int bytes = p->next_line, lines = height * fontheight(p);
- u32 bgx;
-
- dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 4;
-
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- width *= fontwidth(p)/4;
- if (width * 16 == bytes)
- rectfill(dest, lines * width * 4, 1, bgx, bytes);
- else
- rectfill(dest, width * 4, lines, bgx, bytes);
-}
-
-void fbcon_cfb32_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest, *cdat, bits;
- int bytes = p->next_line, rows;
- u32 eorx, fgx, bgx, *pt;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
- if (fontwidth(p) <= 8)
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- else
- cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
- eorx = fgx ^ bgx;
-
- for (rows = fontheight(p); rows--; dest += bytes) {
- bits = *cdat++;
- pt = (u32 *) dest;
- fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
- if (fontwidth(p) < 8)
- continue;
- fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
- if (fontwidth(p) < 12)
- continue;
- bits = *cdat++;
- fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
- if (fontwidth(p) < 16)
- continue;
- fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
- }
-}
-
-void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *cdat, *dest, *dest0, bits;
- u16 c;
- int rows, bytes = p->next_line;
- u32 eorx, fgx, bgx, *pt;
-
- dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
- c = scr_readw(s);
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
- eorx = fgx ^ bgx;
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- if (fontwidth(p) <= 8)
- cdat = p->fontdata + c * fontheight(p);
- else
- cdat = p->fontdata + (c * fontheight(p) << 1);
- for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
- bits = *cdat++;
- pt = (u32 *) dest;
- fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
- if (fontwidth(p) < 8)
- continue;
- fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
- if (fontwidth(p) < 12)
- continue;
- bits = *cdat++;
- fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
- if (fontwidth(p) < 16)
- continue;
- fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
- fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
- }
- dest0 += fontwidth(p)*4;
- }
-}
-
-void fbcon_cfb32_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes = p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
- for (rows = fontheight(p); rows--; dest += bytes) {
- switch (fontwidth(p)) {
- case 16:
- fb_writel(fb_readl(dest+(4*12)) ^ 0xffffffff, dest+(4*12));
- fb_writel(fb_readl(dest+(4*13)) ^ 0xffffffff, dest+(4*13));
- fb_writel(fb_readl(dest+(4*14)) ^ 0xffffffff, dest+(4*14));
- fb_writel(fb_readl(dest+(4*15)) ^ 0xffffffff, dest+(4*15));
- /* FALL THROUGH */
- case 12:
- fb_writel(fb_readl(dest+(4*8)) ^ 0xffffffff, dest+(4*8));
- fb_writel(fb_readl(dest+(4*9)) ^ 0xffffffff, dest+(4*9));
- fb_writel(fb_readl(dest+(4*10)) ^ 0xffffffff, dest+(4*10));
- fb_writel(fb_readl(dest+(4*11)) ^ 0xffffffff, dest+(4*11));
- /* FALL THROUGH */
- case 8:
- fb_writel(fb_readl(dest+(4*4)) ^ 0xffffffff, dest+(4*4));
- fb_writel(fb_readl(dest+(4*5)) ^ 0xffffffff, dest+(4*5));
- fb_writel(fb_readl(dest+(4*6)) ^ 0xffffffff, dest+(4*6));
- fb_writel(fb_readl(dest+(4*7)) ^ 0xffffffff, dest+(4*7));
- /* FALL THROUGH */
- case 4:
- fb_writel(fb_readl(dest+(4*0)) ^ 0xffffffff, dest+(4*0));
- fb_writel(fb_readl(dest+(4*1)) ^ 0xffffffff, dest+(4*1));
- fb_writel(fb_readl(dest+(4*2)) ^ 0xffffffff, dest+(4*2));
- fb_writel(fb_readl(dest+(4*3)) ^ 0xffffffff, dest+(4*3));
- /* FALL THROUGH */
- }
- }
-}
-
-void fbcon_cfb32_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- int bytes = p->next_line;
- u32 bgx;
-
- unsigned int right_start = conp->vc_cols*fontwidth(p);
- unsigned int bottom_start = conp->vc_rows*fontheight(p);
- unsigned int right_width, bottom_width;
-
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- if (!bottom_only && (right_width = p->var.xres-right_start))
- rectfill(p->fb_info->screen_base+right_start*4, right_width,
- p->var.yres_virtual, bgx, bytes);
- if ((bottom_width = p->var.yres-bottom_start))
- rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
- right_start, bottom_width, bgx, bytes);
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_cfb32 = {
- setup: fbcon_cfb32_setup,
- bmove: fbcon_cfb32_bmove,
- clear: fbcon_cfb32_clear,
- putc: fbcon_cfb32_putc,
- putcs: fbcon_cfb32_putcs,
- revc: fbcon_cfb32_revc,
- clear_margins: fbcon_cfb32_clear_margins,
- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_cfb32);
-EXPORT_SYMBOL(fbcon_cfb32_setup);
-EXPORT_SYMBOL(fbcon_cfb32_bmove);
-EXPORT_SYMBOL(fbcon_cfb32_clear);
-EXPORT_SYMBOL(fbcon_cfb32_putc);
-EXPORT_SYMBOL(fbcon_cfb32_putcs);
-EXPORT_SYMBOL(fbcon_cfb32_revc);
-EXPORT_SYMBOL(fbcon_cfb32_clear_margins);
diff --git a/drivers/video/fbcon-cfb4.c b/drivers/video/fbcon-cfb4.c
deleted file mode 100644
index 5af563a65965..000000000000
--- a/drivers/video/fbcon-cfb4.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * linux/drivers/video/cfb4.c -- Low level frame buffer operations for 4 bpp
- * packed pixels
- *
- * Created 26 Dec 1997 by Michael Schmitz
- * Based on the old macfb.c 4bpp code by Alan Cox
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb4.h>
-
-
- /*
- * 4 bpp packed pixels
- */
-
- /*
- * IFF the font is even pixel aligned (that is to say each
- * character start is a byte start in the pixel pairs). That
- * avoids us having to mask bytes and means we won't be here
- * all week. On a MacII that matters _lots_
- */
-
-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)
-{
- p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual>>1;
- p->next_plane = 0;
-}
-
-void fbcon_cfb4_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src,*dst;
-
- if (sx == 0 && dx == 0 && width * 4 == bytes) {
- fb_memmove(p->fb_info->screen_base + dy * linesize,
- p->fb_info->screen_base + sy * linesize,
- height * linesize);
- }
- else {
- if (dy < sy || (dy == sy && dx < sx)) {
- src = p->fb_info->screen_base + sy * linesize + sx * 4;
- dst = p->fb_info->screen_base + dy * linesize + dx * 4;
- for (rows = height * fontheight(p) ; rows-- ;) {
- fb_memmove(dst, src, width * 4);
- src += bytes;
- dst += bytes;
- }
- }
- else {
- src = p->fb_info->screen_base + (sy+height) * linesize + sx * 4 - bytes;
- dst = p->fb_info->screen_base + (dy+height) * linesize + dx * 4 - bytes;
- for (rows = height * fontheight(p) ; rows-- ;) {
- fb_memmove(dst, src, width * 4);
- src -= bytes;
- dst -= bytes;
- }
- }
- }
-}
-
-void fbcon_cfb4_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 * fontheight(p), rows, i;
- u32 bgx;
-
-/* if(p->fb_info->screen_base!=0xFDD00020)
- mac_boom(1);*/
- dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * 4;
-
- bgx=attr_bgcol_ec(p,conp);
- bgx |= (bgx << 4); /* expand the colour to 32bits */
- bgx |= (bgx << 8);
- bgx |= (bgx << 16);
-
- if (sx == 0 && width * 4 == bytes) {
- for (i = 0 ; i < lines * width ; i++) {
- fb_writel (bgx, dest);
- dest+=4;
- }
- } else {
- dest0=dest;
- for (rows = lines; rows-- ; dest0 += bytes) {
- dest=dest0;
- for (i = 0 ; i < width ; i++) {
- /* memset ?? */
- fb_writel (bgx, dest);
- dest+=4;
- }
- }
- }
-}
-
-void fbcon_cfb4_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest,*cdat;
- int bytes=p->next_line,rows;
- u32 eorx,fgx,bgx;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 4;
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-
- fgx=attr_fgcol(p,c);
- bgx=attr_bgcol(p,c);
- fgx |= (fgx << 4);
- fgx |= (fgx << 8);
- bgx |= (bgx << 4);
- bgx |= (bgx << 8);
- eorx = fgx ^ bgx;
-
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- fb_writew((nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx, dest+0);
- fb_writew((nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx, dest+2);
- }
-}
-
-void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *cdat, *dest, *dest0;
- u16 c;
- int rows,bytes=p->next_line;
- u32 eorx, fgx, bgx;
-
- dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 4;
- c = scr_readw(s);
- fgx = attr_fgcol(p, c);
- bgx = attr_bgcol(p, c);
- fgx |= (fgx << 4);
- fgx |= (fgx << 8);
- fgx |= (fgx << 16);
- bgx |= (bgx << 4);
- bgx |= (bgx << 8);
- bgx |= (bgx << 16);
- eorx = fgx ^ bgx;
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata + c * fontheight(p);
-
- for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
- fb_writew((nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx, dest+0);
- fb_writew((nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx, dest+2);
- }
- dest0+=4;
- }
-}
-
-void fbcon_cfb4_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes=p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 4;
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
- }
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_cfb4 = {
- setup: fbcon_cfb4_setup,
- bmove: fbcon_cfb4_bmove,
- clear: fbcon_cfb4_clear,
- putc: fbcon_cfb4_putc,
- putcs: fbcon_cfb4_putcs,
- revc: fbcon_cfb4_revc,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_cfb4);
-EXPORT_SYMBOL(fbcon_cfb4_setup);
-EXPORT_SYMBOL(fbcon_cfb4_bmove);
-EXPORT_SYMBOL(fbcon_cfb4_clear);
-EXPORT_SYMBOL(fbcon_cfb4_putc);
-EXPORT_SYMBOL(fbcon_cfb4_putcs);
-EXPORT_SYMBOL(fbcon_cfb4_revc);
diff --git a/drivers/video/fbcon-cfb8.c b/drivers/video/fbcon-cfb8.c
deleted file mode 100644
index 1ac103832e2a..000000000000
--- a/drivers/video/fbcon-cfb8.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * linux/drivers/video/cfb8.c -- Low level frame buffer operations for 8 bpp
- * packed pixels
- *
- * Created 5 Apr 1997 by 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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-
-
- /*
- * 8 bpp packed pixels
- */
-
-static u32 nibbletab_cfb8[] = {
-#if defined(__BIG_ENDIAN)
- 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
- 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
- 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
- 0xffff0000,0xffff00ff,0xffffff00,0xffffffff
-#elif defined(__LITTLE_ENDIAN)
- 0x00000000,0xff000000,0x00ff0000,0xffff0000,
- 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
- 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
- 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
-#else
-#error FIXME: No endianness??
-#endif
-};
-
-void fbcon_cfb8_setup(struct display *p)
-{
- p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual;
- p->next_plane = 0;
-}
-
-void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src,*dst;
-
- if (sx == 0 && dx == 0 && width * fontwidth(p) == bytes) {
- fb_memmove(p->fb_info->screen_base + dy * linesize,
- p->fb_info->screen_base + sy * linesize,
- height * linesize);
- return;
- }
- if (fontwidthlog(p)) {
- sx <<= fontwidthlog(p); dx <<= fontwidthlog(p); width <<= fontwidthlog(p);
- } else {
- sx *= fontwidth(p); dx *= fontwidth(p); width *= fontwidth(p);
- }
- if (dy < sy || (dy == sy && dx < sx)) {
- src = p->fb_info->screen_base + sy * linesize + sx;
- dst = p->fb_info->screen_base + dy * linesize + dx;
- for (rows = height * fontheight(p) ; rows-- ;) {
- fb_memmove(dst, src, width);
- src += bytes;
- dst += bytes;
- }
- } else {
- src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
- dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
- for (rows = height * fontheight(p) ; rows-- ;) {
- fb_memmove(dst, src, width);
- src -= bytes;
- dst -= bytes;
- }
- }
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u8 data,
- int linesize)
-{
- while (height-- > 0) {
- fb_memset(dest, data, width);
- dest += linesize;
- }
-}
-
-void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest;
- int bytes=p->next_line,lines=height * fontheight(p);
- u8 bgx;
-
- dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p);
-
- bgx=attr_bgcol_ec(p,conp);
-
- width *= fontwidth(p);
- if (width == bytes)
- rectfill(dest, lines * width, 1, bgx, bytes);
- else
- rectfill(dest, width, lines, bgx, bytes);
-}
-
-void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest,*cdat;
- int bytes=p->next_line,rows;
- u32 eorx,fgx,bgx;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- if (fontwidth(p) <= 8)
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- else
- cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-
- 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;
-
- switch (fontwidth(p)) {
- case 4:
- for (rows = fontheight(p) ; rows-- ; dest += bytes)
- fb_writel((nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx, dest);
- break;
- case 8:
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
- fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
- }
- break;
- case 12:
- case 16:
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
- fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
- fb_writel((nibbletab_cfb8[(*cdat >> 4) & 0xf] & eorx) ^ bgx, dest+8);
- if (fontwidth(p) == 16)
- fb_writel((nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx, dest+12);
- cdat++;
- }
- break;
- }
-}
-
-void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *cdat, *dest, *dest0;
- u16 c;
- int rows,bytes=p->next_line;
- u32 eorx, fgx, bgx;
-
- dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- c = scr_readw(s);
- 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;
- switch (fontwidth(p)) {
- case 4:
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata + c * fontheight(p);
-
- for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes)
- fb_writel((nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx, dest);
- dest0+=4;
- }
- break;
- case 8:
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata + c * fontheight(p);
-
- for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
- fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
- fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
- }
- dest0+=8;
- }
- break;
- case 12:
- case 16:
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata + (c * fontheight(p) << 1);
-
- for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
- fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
- fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
- fb_writel((nibbletab_cfb8[(*cdat >> 4) & 0xf] & eorx) ^ bgx, dest+8);
- if (fontwidth(p) == 16)
- fb_writel((nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx, dest+12);
- cdat++;
- }
- dest0+=fontwidth(p);
- }
- break;
- }
-}
-
-void fbcon_cfb8_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int bytes=p->next_line, rows;
-
- dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- switch (fontwidth(p)) {
- case 16: fb_writel(fb_readl(dest+12) ^ 0x0f0f0f0f, dest+12); /* fall thru */
- case 12: fb_writel(fb_readl(dest+8) ^ 0x0f0f0f0f, dest+8); /* fall thru */
- case 8: fb_writel(fb_readl(dest+4) ^ 0x0f0f0f0f, dest+4); /* fall thru */
- case 4: fb_writel(fb_readl(dest) ^ 0x0f0f0f0f, dest); /* fall thru */
- default: break;
- }
- }
-}
-
-void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- int bytes=p->next_line;
- u8 bgx;
-
- unsigned int right_start = conp->vc_cols*fontwidth(p);
- unsigned int bottom_start = conp->vc_rows*fontheight(p);
- unsigned int right_width, bottom_width;
-
- bgx=attr_bgcol_ec(p,conp);
-
- if (!bottom_only && (right_width = p->var.xres-right_start))
- rectfill(p->fb_info->screen_base+right_start, right_width, p->var.yres_virtual, bgx, bytes);
- if ((bottom_width = p->var.yres-bottom_start))
- rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
- right_start, bottom_width, bgx, bytes);
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_cfb8 = {
- setup: fbcon_cfb8_setup,
- bmove: fbcon_cfb8_bmove,
- clear: fbcon_cfb8_clear,
- putc: fbcon_cfb8_putc,
- putcs: fbcon_cfb8_putcs,
- revc: fbcon_cfb8_revc,
- clear_margins: fbcon_cfb8_clear_margins,
- fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_cfb8);
-EXPORT_SYMBOL(fbcon_cfb8_setup);
-EXPORT_SYMBOL(fbcon_cfb8_bmove);
-EXPORT_SYMBOL(fbcon_cfb8_clear);
-EXPORT_SYMBOL(fbcon_cfb8_putc);
-EXPORT_SYMBOL(fbcon_cfb8_putcs);
-EXPORT_SYMBOL(fbcon_cfb8_revc);
-EXPORT_SYMBOL(fbcon_cfb8_clear_margins);
diff --git a/drivers/video/fbcon-hga.c b/drivers/video/fbcon-hga.c
deleted file mode 100644
index 4cb12c6e47f5..000000000000
--- a/drivers/video/fbcon-hga.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * linux/drivers/video/fbcon-hga.c -- Low level frame buffer operations for
- * the Hercules graphics adaptor
- *
- * Created 25 Nov 1999 by Ferenc Bakonyi (fero@drama.obuda.kando.hu)
- * Based on fbcon-mfb.c by Geert Uytterhoeven
- *
- * History:
- *
- * - Revision 0.1.0 (6 Dec 1999): comment changes
- * - First release (25 Nov 1999)
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-hga.h>
-
-#if 0
-#define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
-#else
-#define DPRINTK(args...)
-#endif
-
-#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
-
- /*
- * Hercules monochrome
- */
-
-static inline u8* rowaddr(struct display *p, u_int row)
-{
- return p->fb_info->screen_base + HGA_ROWADDR(row);
-}
-
-void fbcon_hga_setup(struct display *p)
-{
- DPRINTK("fbcon_hga_setup: ll:%d\n", (int)p->line_length);
-
- p->next_line = p->fb_info->fix.line_length;
- p->next_plane = 0;
-}
-
-void fbcon_hga_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- u8 *src, *dest;
- u_int rows, y1, y2;
-
-#if 0
- if (sx == 0 && dx == 0 && width == p->next_line) {
- src = p->fb_info->screen_base+sy*fontheight(p)*width;
- dest = p->fb_info->screen_base+dy*fontheight(p)*width;
- fb_memmove(dest, src, height*fontheight(p)*width);
- } else
-#endif
- if (dy <= sy) {
- y1 = sy*fontheight(p);
- y2 = dy*fontheight(p);
- for (rows = height*fontheight(p); rows--; ) {
- src = rowaddr(p, y1)+sx;
- dest = rowaddr(p, y2)+dx;
- fb_memmove(dest, src, width);
- y1++;
- y2++;
- }
- } else {
- y1 = (sy+height)*fontheight(p)-1;
- y2 = (dy+height)*fontheight(p)-1;
- for (rows = height*fontheight(p); rows--;) {
- src = rowaddr(p, y1)+sx;
- dest = rowaddr(p, y2)+dx;
- fb_memmove(dest, src, width);
- y1--;
- y2--;
- }
- }
-}
-
-void fbcon_hga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest;
- u_int rows, y;
- int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
- DPRINTK("fbcon_hga_clear: sx:%d, sy:%d, height:%d, width:%d\n", sx, sy, height, width);
-
- y = sy*fontheight(p);
-#if 0
- if (sx == 0 && width == p->next_line) {
- if (inverse) {
- fb_memset255(dest, height*fontheight(p)*width);
- } else {
- fb_memclear(dest, height*fontheight(p)*width);
- }
- } else
-#endif
- for (rows = height*fontheight(p); rows--; y++) {
- dest = rowaddr(p, y)+sx;
- if (inverse) {
- fb_memset255(dest, width);
- } else {
- fb_memclear(dest, width);
- }
- }
-}
-
-void fbcon_hga_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest, *cdat;
- u_int rows, y, bold, revs, underl;
- u8 d;
-
- cdat = p->fontdata+(c&p->charmask)*fontheight(p);
- bold = attr_bold(p, c);
- revs = attr_reverse(p, c);
- underl = attr_underline(p, c);
- y = yy*fontheight(p);
-
- for (rows = fontheight(p); rows--; y++) {
- d = *cdat++;
- if (underl && !rows)
- d = 0xff;
- else if (bold)
- d |= d>>1;
- if (revs)
- d = ~d;
- dest = rowaddr(p, y)+xx;
- *dest = d;
- }
-}
-
-void fbcon_hga_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *dest, *cdat;
- u_int rows, y, y0, bold, revs, underl;
- u8 d;
- u16 c;
-
- c = scr_readw(s);
- bold = attr_bold(p, c);
- revs = attr_reverse(p, c);
- underl = attr_underline(p, c);
- y0 = yy*fontheight(p);
-
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- cdat = p->fontdata+c*fontheight(p);
- y = y0;
- for (rows = fontheight(p); rows--; y++) {
- d = *cdat++;
- if (underl && !rows)
- d = 0xff;
- else if (bold)
- d |= d>>1;
- if (revs)
- d = ~d;
- dest = rowaddr(p, y)+xx;
- *dest = d;
- }
- xx++;
- }
-}
-
-void fbcon_hga_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- u_int rows, y;
-
- y = yy*fontheight(p);
- for (rows = fontheight(p); rows--; y++) {
- dest = rowaddr(p, y)+xx;
- *dest = ~*dest;
- }
-}
-
-void fbcon_hga_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- u8 *dest;
- u_int height, y;
- int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
- DPRINTK("fbcon_hga_clear_margins: enter\n");
-
- /* No need to handle right margin. */
-
- y = conp->vc_rows * fontheight(p);
- for (height = p->var.yres - y; height-- > 0; y++) {
- DPRINTK("fbcon_hga_clear_margins: y:%d, height:%d\n", y, height);
- dest = rowaddr(p, y);
- if (inverse) {
- fb_memset255(dest, p->next_line);
- } else {
- fb_memclear(dest, p->next_line);
- }
- }
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_hga = {
- .setup = fbcon_hga_setup,
- .bmove = fbcon_hga_bmove,
- .clear = fbcon_hga_clear,
- .putc = fbcon_hga_putc,
- .putcs = fbcon_hga_putcs,
- .revc = fbcon_hga_revc,
- .clear_margins =fbcon_hga_clear_margins,
- .fontwidthmask =FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{
-}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_hga);
-EXPORT_SYMBOL(fbcon_hga_setup);
-EXPORT_SYMBOL(fbcon_hga_bmove);
-EXPORT_SYMBOL(fbcon_hga_clear);
-EXPORT_SYMBOL(fbcon_hga_putc);
-EXPORT_SYMBOL(fbcon_hga_putcs);
-EXPORT_SYMBOL(fbcon_hga_revc);
-EXPORT_SYMBOL(fbcon_hga_clear_margins);
diff --git a/drivers/video/fbcon-ilbm.c b/drivers/video/fbcon-ilbm.c
deleted file mode 100644
index 157736e809a7..000000000000
--- a/drivers/video/fbcon-ilbm.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * linux/drivers/video/ilbm.c -- Low level frame buffer operations for
- * interleaved bitplanes à la Amiga
- *
- * Created 5 Apr 1997 by 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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-ilbm.h>
-
-
- /*
- * Interleaved bitplanes à la Amiga
- *
- * This code heavily relies on the fact that
- *
- * next_line == interleave == next_plane*bits_per_pixel
- *
- * But maybe it can be merged with the code for normal bitplanes without
- * much performance loss?
- */
-
-void fbcon_ilbm_setup(struct display *p)
-{
- if (p->fb_info->fix.line_length) {
- p->next_line = p->fb_info->fix.line_length*p->var.bits_per_pixel;
- p->next_plane = p->fb_info->fix.line_length;
- } else {
- p->next_line = p->fb_info->fix.type_aux;
- p->next_plane = p->fb_info->fix.type_aux/p->var.bits_per_pixel;
- }
-}
-
-void fbcon_ilbm_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- if (sx == 0 && dx == 0 && width == p->next_plane)
- fb_memmove(p->fb_info->screen_base+dy*fontheight(p)*p->next_line,
- p->fb_info->screen_base+sy*fontheight(p)*p->next_line,
- height*fontheight(p)*p->next_line);
- else {
- u8 *src, *dest;
- u_int i;
-
- if (dy <= sy) {
- src = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
- dest = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
- for (i = p->var.bits_per_pixel*height*fontheight(p); i--;) {
- fb_memmove(dest, src, width);
- src += p->next_plane;
- dest += p->next_plane;
- }
- } else {
- src = p->fb_info->screen_base+(sy+height)*fontheight(p)*p->next_line+sx;
- dest = p->fb_info->screen_base+(dy+height)*fontheight(p)*p->next_line+dx;
- for (i = p->var.bits_per_pixel*height*fontheight(p); i--;) {
- src -= p->next_plane;
- dest -= p->next_plane;
- fb_memmove(dest, src, width);
- }
- }
- }
-}
-
-void fbcon_ilbm_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest;
- u_int i, rows;
- int bg, bg0;
-
- dest = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-
- bg0 = attr_bgcol_ec(p,conp);
- for (rows = height*fontheight(p); rows--;) {
- bg = bg0;
- for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
- if (bg & 1)
- fb_memset255(dest, width);
- else
- fb_memclear(dest, width);
- bg >>= 1;
- }
- }
-}
-
-void fbcon_ilbm_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest, *cdat;
- u_int rows, i;
- u8 d;
- int fg0, bg0, fg, bg;
-
- dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- cdat = p->fontdata+(c&p->charmask)*fontheight(p);
- fg0 = attr_fgcol(p,c);
- bg0 = attr_bgcol(p,c);
-
- for (rows = fontheight(p); rows--;) {
- d = *cdat++;
- fg = fg0;
- bg = bg0;
- for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
- if (bg & 1){
- if (fg & 1)
- *dest = 0xff;
- else
- *dest = ~d;
- }else{
- if (fg & 1)
- *dest = d;
- else
- *dest = 0x00;
- }
- bg >>= 1;
- fg >>= 1;
- }
- }
-}
-
- /*
- * I've split the console character loop in two parts:
- *
- * - slow version: this blits one character at a time
- *
- * - fast version: this blits 4 characters at a time at a longword
- * aligned address, to reduce the number of expensive
- * Chip RAM accesses.
- *
- * Experiments on my A4000/040 revealed that this makes a console switch
- * on a 640x400 screen with 256 colors about 3 times faster.
- *
- * -- Geert
- */
-
-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;
- u16 c1, c2, c3, c4;
- u32 d;
- int fg0, bg0, fg, bg;
-
- dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- c1 = scr_readw(s);
- fg0 = attr_fgcol(p, c1);
- bg0 = attr_bgcol(p, c1);
-
- while (count--)
- if (xx&3 || count < 3) { /* Slow version */
- c1 = scr_readw(s++) & p->charmask;
- dest = dest0++;
- xx++;
-
- cdat1 = p->fontdata+c1*fontheight(p);
- for (rows = fontheight(p); rows--;) {
- d = *cdat1++;
- fg = fg0;
- bg = bg0;
- for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
- if (bg & 1){
- if (fg & 1)
- *dest = 0xff;
- else
- *dest = ~d;
- }else{
- if (fg & 1)
- *dest = d;
- else
- *dest = 0x00;
- }
- bg >>= 1;
- fg >>= 1;
- }
- }
- } else { /* Fast version */
- c1 = scr_readw(&s[0]) & p->charmask;
- c2 = scr_readw(&s[1]) & p->charmask;
- c3 = scr_readw(&s[2]) & p->charmask;
- c4 = scr_readw(&s[3]) & p->charmask;
-
- dest = dest0;
- cdat1 = p->fontdata+c1*fontheight(p);
- cdat2 = p->fontdata+c2*fontheight(p);
- cdat3 = p->fontdata+c3*fontheight(p);
- cdat4 = p->fontdata+c4*fontheight(p);
- for (rows = fontheight(p); rows--;) {
-#if defined(__BIG_ENDIAN)
- d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
-#elif defined(__LITTLE_ENDIAN)
- d = *cdat1++ | *cdat2++<<8 | *cdat3++<<16 | *cdat4++<<24;
-#else
-#error FIXME: No endianness??
-#endif
- fg = fg0;
- bg = bg0;
- for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
- if (bg & 1){
- if (fg & 1)
- *(u32 *)dest = 0xffffffff;
- else
- *(u32 *)dest = ~d;
- }else{
- if (fg & 1)
- *(u32 *)dest = d;
- else
- *(u32 *)dest = 0x00000000;
- }
- bg >>= 1;
- fg >>= 1;
- }
- }
- s += 4;
- dest0 += 4;
- xx += 4;
- count -= 3;
- }
-}
-
-void fbcon_ilbm_revc(struct display *p, int xx, int yy)
-{
- u8 *dest, *dest0;
- u_int rows, i;
- int mask;
-
- dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- mask = p->fgcol ^ p->bgcol;
-
- /*
- * This should really obey the individual character's
- * background and foreground colors instead of simply
- * inverting.
- */
-
- for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
- if (mask & 1) {
- dest = dest0;
- for (rows = fontheight(p); rows--; dest += p->next_line)
- *dest = ~*dest;
- }
- mask >>= 1;
- }
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_ilbm = {
- setup: fbcon_ilbm_setup,
- bmove: fbcon_ilbm_bmove,
- clear: fbcon_ilbm_clear,
- putc: fbcon_ilbm_putc,
- putcs: fbcon_ilbm_putcs,
- revc: fbcon_ilbm_revc,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_ilbm);
-EXPORT_SYMBOL(fbcon_ilbm_setup);
-EXPORT_SYMBOL(fbcon_ilbm_bmove);
-EXPORT_SYMBOL(fbcon_ilbm_clear);
-EXPORT_SYMBOL(fbcon_ilbm_putc);
-EXPORT_SYMBOL(fbcon_ilbm_putcs);
-EXPORT_SYMBOL(fbcon_ilbm_revc);
diff --git a/drivers/video/fbcon-iplan2p2.c b/drivers/video/fbcon-iplan2p2.c
deleted file mode 100644
index 9eea32a4efb9..000000000000
--- a/drivers/video/fbcon-iplan2p2.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * 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
- *
- * 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/byteorder.h>
-
-#ifdef __mc68000__
-#include <asm/setup.h>
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-iplan2p2.h>
-
-
- /*
- * Interleaved bitplanes à la Atari (2 planes, 2 bytes interleave)
- */
-
-/* Increment/decrement 2 plane addresses */
-
-#define INC_2P(p) do { if (!((long)(++(p)) & 1)) (p) += 2; } while(0)
-#define DEC_2P(p) do { if ((long)(--(p)) & 1) (p) -= 2; } while(0)
-
- /* Convert a standard 4 bit color to our 2 bit color assignment:
- * If at least two RGB channels are active, the low bit is turned on;
- * The intensity bit (b3) is shifted into b1.
- */
-
-static const u8 color_2p[] = { 0, 0, 0, 1, 0, 1, 1, 1, 2, 2, 2, 3, 2, 3, 3, 3 };
-#define COLOR_2P(c) color_2p[c]
-
-/* Perform the m68k movepw operation. */
-static inline void movepw(u8 *d, u16 val)
-{
-#if defined __mc68000__ && !defined CPU_M68060_ONLY
- asm volatile ("movepw %1,%0@(0)" : : "a" (d), "d" (val));
-#else
- d[0] = (val >> 16) & 0xff;
- d[2] = val & 0xff;
-#endif
-}
-
-/* Sets the bytes in the visible column at d, height h, to the value
- * 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)
- * *d = (color & 1) ? 0xff : 0;
- * *(d+2) = (color & 2) ? 0xff : 0;
- */
-
-static __inline__ void memclear_2p_col(void *d, size_t h, u16 val, int bpr)
-{
- u8 *dd = d;
- do {
- movepw(dd, val);
- dd += bpr;
- } while (--h);
-}
-
-/* Sets a 2 plane region from 'd', length 'count' bytes, to the color
- * in val1. 'd' has to be an even address and count must be divisible
- * by 8, because only whole words and all planes are accessed. I.e.:
- *
- * for(count/4 times)
- * *d = *(d+1) = (color & 1) ? 0xff : 0;
- * *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
- */
-
-static __inline__ void memset_even_2p(void *d, size_t count, u32 val)
-{
- u32 *dd = d;
-
- count /= 4;
- while (count--)
- *dd++ = val;
-}
-
-/* Copies a 2 plane column from 's', height 'h', to 'd'. */
-
-static __inline__ void memmove_2p_col (void *d, void *s, int h, int bpr)
-{
- u8 *dd = d, *ss = s;
-
- while (h--) {
- dd[0] = ss[0];
- dd[2] = ss[2];
- dd += bpr;
- ss += bpr;
- }
-}
-
-
-/* This expands a 2 bit color into a short for movepw (2 plane) operations. */
-
-static const u16 two2byte[] = {
- 0x0000, 0xff00, 0x00ff, 0xffff
-};
-
-static __inline__ u16 expand2w(u8 c)
-{
- return two2byte[c];
-}
-
-
-/* This expands a 2 bit color into one long for a movel operation
- * (2 planes).
- */
-
-static const u32 two2word[] = {
-#ifndef __LITTLE_ENDIAN
- 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
-#else
- 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
-#endif
-};
-
-static __inline__ u32 expand2l(u8 c)
-{
- return two2word[c];
-}
-
-
-/* This duplicates a byte 2 times into a short. */
-
-static __inline__ u16 dup2w(u8 c)
-{
- u16 rv;
-
- rv = c;
- rv |= c << 8;
- return rv;
-}
-
-
-void fbcon_iplan2p2_setup(struct display *p)
-{
- p->next_line = p->var.xres_virtual>>2;
- p->next_plane = 2;
-}
-
-void fbcon_iplan2p2_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- /* bmove() has to distinguish two major cases: If both, source and
- * destination, start at even addresses or both are at odd
- * addresses, just the first odd and last even column (if present)
- * require special treatment (memmove_col()). The rest between
- * then can be copied by normal operations, because all adjacent
- * bytes are affected and are to be stored in the same order.
- * The pathological case is when the move should go from an odd
- * address to an even or vice versa. Since the bytes in the plane
- * words must be assembled in new order, it seems wisest to make
- * all movements by memmove_col().
- */
-
- if (sx == 0 && dx == 0 && width * 2 == p->next_line) {
- /* Special (but often used) case: Moving whole lines can be
- * done with memmove()
- */
- fb_memmove(p->fb_info->screen_base + dy * p->next_line * fontheight(p),
- p->fb_info->screen_base + sy * p->next_line * fontheight(p),
- p->next_line * height * fontheight(p));
- } else {
- int rows, cols;
- u8 *src;
- u8 *dst;
- int bytes = p->next_line;
- int linesize;
- u_int colsize;
- u_int upwards = (dy < sy) || (dy == sy && dx < sx);
-
- if (fontheightlog(p)) {
- linesize = bytes << fontheightlog(p);
- colsize = height << fontheightlog(p);
- } else {
- linesize = bytes * fontheight(p);
- colsize = height * fontheight(p);
- }
- if ((sx & 1) == (dx & 1)) {
- /* odd->odd or even->even */
- if (upwards) {
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
- if (sx & 1) {
- memmove_2p_col(dst, src, colsize, bytes);
- src += 3;
- dst += 3;
- --width;
- }
- if (width > 1) {
- for (rows = colsize; rows > 0; --rows) {
- fb_memmove(dst, src, (width>>1)*4);
- src += bytes;
- dst += bytes;
- }
- }
- if (width & 1) {
- src -= colsize * bytes;
- dst -= colsize * bytes;
- memmove_2p_col(dst + (width>>1)*4, src + (width>>1)*4,
- colsize, bytes);
- }
- } else {
- if (!((sx+width-1) & 1)) {
- src = p->fb_info->screen_base + sy * linesize + ((sx+width-1)>>1)*4;
- dst = p->fb_info->screen_base + dy * linesize + ((dx+width-1)>>1)*4;
- memmove_2p_col(dst, src, colsize, bytes);
- --width;
- }
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
- if (width > 1) {
- src += colsize * bytes + (sx & 1)*3;
- dst += colsize * bytes + (sx & 1)*3;
- for(rows = colsize; rows > 0; --rows) {
- src -= bytes;
- dst -= bytes;
- fb_memmove(dst, src, (width>>1)*4);
- }
- }
- if (width & 1)
- memmove_2p_col(dst-3, src-3, colsize, bytes);
- }
- } else {
- /* odd->even or even->odd */
- if (upwards) {
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
- for (cols = width; cols > 0; --cols) {
- memmove_2p_col(dst, src, colsize, bytes);
- INC_2P(src);
- INC_2P(dst);
- }
- } else {
- sx += width-1;
- dx += width-1;
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
- for(cols = width; cols > 0; --cols) {
- memmove_2p_col(dst, src, colsize, bytes);
- DEC_2P(src);
- DEC_2P(dst);
- }
- }
- }
- }
-}
-
-void fbcon_iplan2p2_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- u32 offset;
- u8 *start;
- int rows;
- int bytes = p->next_line;
- int lines;
- u32 size;
- u32 cval;
- u16 pcval;
-
- cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp)));
-
- if (fontheightlog(p))
- lines = height << fontheightlog(p);
- else
- lines = height * fontheight(p);
-
- if (sx == 0 && width * 2 == bytes) {
- if (fontheightlog(p))
- offset = (sy * bytes) << fontheightlog(p);
- else
- offset = sy * bytes * fontheight(p);
- size = lines * bytes;
- memset_even_2p(p->fb_info->screen_base+offset, size, cval);
- } else {
- if (fontheightlog(p))
- offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*4 + (sx & 1);
- else
- offset = sy * bytes * fontheight(p) + (sx>>1)*4 + (sx & 1);
- start = p->fb_info->screen_base + offset;
- pcval = expand2w(COLOR_2P(attr_bgcol_ec(p,conp)));
-
- /* Clears are split if the region starts at an odd column or
- * end at an even column. These extra columns are spread
- * across the interleaved planes. All in between can be
- * cleared by normal fb_memclear_small(), because both bytes of
- * the single plane words are affected.
- */
-
- if (sx & 1) {
- memclear_2p_col(start, lines, pcval, bytes);
- start += 3;
- width--;
- }
- if (width & 1) {
- memclear_2p_col(start + (width>>1)*4, lines, pcval, bytes);
- width--;
- }
- if (width) {
- for (rows = lines; rows-- ; start += bytes)
- memset_even_2p(start, width*2, cval);
- }
- }
-}
-
-void fbcon_iplan2p2_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- u8 *dest;
- u8 *cdat;
- int rows;
- int bytes = p->next_line;
- u16 eorx, fgx, bgx, fdx;
-
- if (fontheightlog(p)) {
- dest = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
- (xx>>1)*4 + (xx & 1));
- cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
- } else {
- dest = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
- (xx>>1)*4 + (xx & 1));
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- }
-
- fgx = expand2w(COLOR_2P(attr_fgcol(p,c)));
- bgx = expand2w(COLOR_2P(attr_bgcol(p,c)));
- eorx = fgx ^ bgx;
-
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- fdx = dup2w(*cdat++);
- movepw(dest, (fdx & eorx) ^ bgx);
- }
-}
-
-void fbcon_iplan2p2_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *dest, *dest0;
- u8 *cdat;
- u16 c;
- int rows;
- int bytes;
- u16 eorx, fgx, bgx, fdx;
-
- bytes = p->next_line;
- if (fontheightlog(p))
- dest0 = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
- (xx>>1)*4 + (xx & 1));
- else
- dest0 = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
- (xx>>1)*4 + (xx & 1));
- c = scr_readw(s);
- fgx = expand2w(COLOR_2P(attr_fgcol(p, c)));
- bgx = expand2w(COLOR_2P(attr_bgcol(p, c)));
- eorx = fgx ^ bgx;
-
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- if (fontheightlog(p))
- cdat = p->fontdata + (c << fontheightlog(p));
- else
- cdat = p->fontdata + c * fontheight(p);
-
- for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
- fdx = dup2w(*cdat++);
- movepw(dest, (fdx & eorx) ^ bgx);
- }
- INC_2P(dest0);
- }
-}
-
-void fbcon_iplan2p2_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int j;
- int bytes;
-
- if (fontheightlog(p))
- dest = (p->fb_info->screen_base + ((yy * p->next_line) << fontheightlog(p)) + (xx>>1)*4 + (xx & 1));
- else
- dest = (p->fb_info->screen_base + yy * p->next_line * fontheight(p) +
- (xx>>1)*4 + (xx & 1));
- j = fontheight(p);
- bytes = p->next_line;
- while (j--) {
- /* This should really obey the individual character's
- * background and foreground colors instead of simply
- * inverting.
- */
- dest[0] = ~dest[0];
- dest[2] = ~dest[2];
- dest += bytes;
- }
-}
-
-void fbcon_iplan2p2_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- u32 offset;
- int bytes;
- int lines;
- u32 cval;
-
-/* No need to handle right margin, cannot occur with fontwidth == 8 */
-
- bytes = p->next_line;
- if (fontheightlog(p)) {
- lines = p->var.yres - (conp->vc_rows << fontheightlog(p));
- offset = ((p->yscroll + conp->vc_rows) * bytes) << fontheightlog(p);
- } else {
- lines = p->var.yres - conp->vc_rows * fontheight(p);
- offset = (p->yscroll + conp->vc_rows) * bytes * fontheight(p);
- }
- if (lines) {
- cval = expand2l(COLOR_2P(attr_bgcol_ec(p,conp)));
- memset_even_2p(p->fb_info->screen_base+offset, lines * bytes, cval);
- }
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_iplan2p2 = {
- setup: fbcon_iplan2p2_setup,
- bmove: fbcon_iplan2p2_bmove,
- clear: fbcon_iplan2p2_clear,
- putc: fbcon_iplan2p2_putc,
- putcs: fbcon_iplan2p2_putcs,
- revc: fbcon_iplan2p2_revc,
- clear_margins: fbcon_iplan2p2_clear_margins,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_iplan2p2);
-EXPORT_SYMBOL(fbcon_iplan2p2_setup);
-EXPORT_SYMBOL(fbcon_iplan2p2_bmove);
-EXPORT_SYMBOL(fbcon_iplan2p2_clear);
-EXPORT_SYMBOL(fbcon_iplan2p2_putc);
-EXPORT_SYMBOL(fbcon_iplan2p2_putcs);
-EXPORT_SYMBOL(fbcon_iplan2p2_revc);
-EXPORT_SYMBOL(fbcon_iplan2p2_clear_margins);
diff --git a/drivers/video/fbcon-iplan2p4.c b/drivers/video/fbcon-iplan2p4.c
deleted file mode 100644
index fdbb6a4d2790..000000000000
--- a/drivers/video/fbcon-iplan2p4.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * 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
- *
- * 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/byteorder.h>
-
-#ifdef __mc68000__
-#include <asm/setup.h>
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-iplan2p4.h>
-
-
- /*
- * Interleaved bitplanes à la Atari (4 planes, 2 bytes interleave)
- */
-
-/* Increment/decrement 4 plane addresses */
-
-#define INC_4P(p) do { if (!((long)(++(p)) & 1)) (p) += 6; } while(0)
-#define DEC_4P(p) do { if ((long)(--(p)) & 1) (p) -= 6; } while(0)
-
-/* Perform the m68k movepl operation. */
-static inline void movepl(u8 *d, u32 val)
-{
-#if defined __mc68000__ && !defined CPU_M68060_ONLY
- asm volatile ("movepl %1,%0@(0)" : : "a" (d), "d" (val));
-#else
- d[0] = (val >> 24) & 0xff;
- d[2] = (val >> 16) & 0xff;
- d[4] = (val >> 8) & 0xff;
- d[6] = val & 0xff;
-#endif
-}
-
-/* Sets the bytes in the visible column at d, height h, to the value
- * 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)
- * *d = (color & 1) ? 0xff : 0;
- * *(d+2) = (color & 2) ? 0xff : 0;
- * *(d+4) = (color & 4) ? 0xff : 0;
- * *(d+6) = (color & 8) ? 0xff : 0;
- */
-
-static __inline__ void memclear_4p_col(void *d, size_t h, u32 val, int bpr)
-{
- u8 *dd = d;
- do {
- movepl(dd, val);
- dd += bpr;
- } while (--h);
-}
-
-/* Sets a 4 plane region from 'd', length 'count' bytes, to the color
- * in val1/val2. 'd' has to be an even address and count must be divisible
- * by 8, because only whole words and all planes are accessed. I.e.:
- *
- * for(count/8 times)
- * *d = *(d+1) = (color & 1) ? 0xff : 0;
- * *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
- * *(d+4) = *(d+5) = (color & 4) ? 0xff : 0;
- * *(d+6) = *(d+7) = (color & 8) ? 0xff : 0;
- */
-
-static __inline__ void memset_even_4p(void *d, size_t count, u32 val1,
- u32 val2)
-{
- u32 *dd = d;
-
- count /= 8;
- while (count--) {
- *dd++ = val1;
- *dd++ = val2;
- }
-}
-
-/* Copies a 4 plane column from 's', height 'h', to 'd'. */
-
-static __inline__ void memmove_4p_col (void *d, void *s, int h, int bpr)
-{
- u8 *dd = d, *ss = s;
-
- while (h--) {
- dd[0] = ss[0];
- dd[2] = ss[2];
- dd[4] = ss[4];
- dd[6] = ss[6];
- dd += bpr;
- ss += bpr;
- }
-}
-
-
-/* This expands a 4 bit color into a long for movepl (4 plane) operations. */
-
-static const u32 four2byte[] = {
- 0x00000000, 0xff000000, 0x00ff0000, 0xffff0000,
- 0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00,
- 0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff,
- 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff
-};
-
-static __inline__ u32 expand4l(u8 c)
-{
- return four2byte[c];
-}
-
-
-/* This expands a 4 bit color into two longs for two movel operations
- * (4 planes).
- */
-
-static const u32 two2word[] = {
-#ifndef __LITTLE_ENDIAN
- 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff,
-#else
- 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff,
-#endif
-};
-
-static __inline__ void expand4dl(u8 c, u32 *ret1, u32 *ret2)
-{
- *ret1 = two2word[c & 3];
- *ret2 = two2word[c >> 2];
-}
-
-
-/* This duplicates a byte 4 times into a long. */
-
-static __inline__ u32 dup4l(u8 c)
-{
- u32 rv;
-
- rv = c;
- rv |= rv << 8;
- rv |= rv << 16;
- return rv;
-}
-
-
-void fbcon_iplan2p4_setup(struct display *p)
-{
- p->next_line = p->var.xres_virtual>>1;
- p->next_plane = 2;
-}
-
-void fbcon_iplan2p4_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- /* bmove() has to distinguish two major cases: If both, source and
- * destination, start at even addresses or both are at odd
- * addresses, just the first odd and last even column (if present)
- * require special treatment (memmove_col()). The rest between
- * then can be copied by normal operations, because all adjacent
- * bytes are affected and are to be stored in the same order.
- * The pathological case is when the move should go from an odd
- * address to an even or vice versa. Since the bytes in the plane
- * words must be assembled in new order, it seems wisest to make
- * all movements by memmove_col().
- */
-
- if (sx == 0 && dx == 0 && width * 4 == p->next_line) {
- /* Special (but often used) case: Moving whole lines can be
- *done with memmove()
- */
- fb_memmove(p->fb_info->screen_base + dy * p->next_line * fontheight(p),
- p->fb_info->screen_base + sy * p->next_line * fontheight(p),
- p->next_line * height * fontheight(p));
- } else {
- int rows, cols;
- u8 *src;
- u8 *dst;
- int bytes = p->next_line;
- int linesize;
- u_int colsize;
- u_int upwards = (dy < sy) || (dy == sy && dx < sx);
-
- if (fontheightlog(p)) {
- linesize = bytes << fontheightlog(p);
- colsize = height << fontheightlog(p);
- } else {
- linesize = bytes * fontheight(p);
- colsize = height * fontheight(p);
- }
- if ((sx & 1) == (dx & 1)) {
- /* odd->odd or even->even */
-
- if (upwards) {
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
- if (sx & 1) {
- memmove_4p_col(dst, src, colsize, bytes);
- src += 7;
- dst += 7;
- --width;
- }
- if (width > 1) {
- for(rows = colsize; rows > 0; --rows) {
- fb_memmove(dst, src, (width>>1)*8);
- src += bytes;
- dst += bytes;
- }
- }
- if (width & 1) {
- src -= colsize * bytes;
- dst -= colsize * bytes;
- memmove_4p_col(dst + (width>>1)*8, src + (width>>1)*8,
- colsize, bytes);
- }
- } else {
- if (!((sx+width-1) & 1)) {
- src = p->fb_info->screen_base + sy * linesize + ((sx+width-1)>>1)*8;
- dst = p->fb_info->screen_base + dy * linesize + ((dx+width-1)>>1)*8;
- memmove_4p_col(dst, src, colsize, bytes);
- --width;
- }
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
- if (width > 1) {
- src += colsize * bytes + (sx & 1)*7;
- dst += colsize * bytes + (sx & 1)*7;
- for(rows = colsize; rows > 0; --rows) {
- src -= bytes;
- dst -= bytes;
- fb_memmove(dst, src, (width>>1)*8);
- }
- }
- if (width & 1) {
- memmove_4p_col(dst-7, src-7, colsize, bytes);
- }
- }
- } else {
- /* odd->even or even->odd */
-
- if (upwards) {
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
- for(cols = width; cols > 0; --cols) {
- memmove_4p_col(dst, src, colsize, bytes);
- INC_4P(src);
- INC_4P(dst);
- }
- } else {
- sx += width-1;
- dx += width-1;
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
- for(cols = width; cols > 0; --cols) {
- memmove_4p_col(dst, src, colsize, bytes);
- DEC_4P(src);
- DEC_4P(dst);
- }
- }
- }
- }
-}
-
-void fbcon_iplan2p4_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- u32 offset;
- u8 *start;
- int rows;
- int bytes = p->next_line;
- int lines;
- u32 size;
- u32 cval1, cval2, pcval;
-
- expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
-
- if (fontheightlog(p))
- lines = height << fontheightlog(p);
- else
- lines = height * fontheight(p);
-
- if (sx == 0 && width * 4 == bytes) {
- if (fontheightlog(p))
- offset = (sy * bytes) << fontheightlog(p);
- else
- offset = sy * bytes * fontheight(p);
- size = lines * bytes;
- memset_even_4p(p->fb_info->screen_base+offset, size, cval1, cval2);
- } else {
- if (fontheightlog(p))
- offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*8 + (sx & 1);
- else
- offset = sy * bytes * fontheight(p) + (sx>>1)*8 + (sx & 1);
- start = p->fb_info->screen_base + offset;
- pcval = expand4l(attr_bgcol_ec(p,conp));
-
- /* Clears are split if the region starts at an odd column or
- * end at an even column. These extra columns are spread
- * across the interleaved planes. All in between can be
- * cleared by normal fb_memclear_small(), because both bytes of
- * the single plane words are affected.
- */
-
- if (sx & 1) {
- memclear_4p_col(start, lines, pcval, bytes);
- start += 7;
- width--;
- }
- if (width & 1) {
- memclear_4p_col(start + (width>>1)*8, lines, pcval, bytes);
- width--;
- }
- if (width) {
- for(rows = lines; rows-- ; start += bytes)
- memset_even_4p(start, width*4, cval1, cval2);
- }
- }
-}
-
-void fbcon_iplan2p4_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- u8 *dest;
- u8 *cdat;
- int rows;
- int bytes = p->next_line;
- u32 eorx, fgx, bgx, fdx;
-
- if (fontheightlog(p)) {
- dest = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
- (xx>>1)*8 + (xx & 1));
- cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
- } else {
- dest = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
- (xx>>1)*8 + (xx & 1));
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- }
-
- fgx = expand4l(attr_fgcol(p,c));
- bgx = expand4l(attr_bgcol(p,c));
- eorx = fgx ^ bgx;
-
- for(rows = fontheight(p) ; rows-- ; dest += bytes) {
- fdx = dup4l(*cdat++);
- movepl(dest, (fdx & eorx) ^ bgx);
- }
-}
-
-void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *dest, *dest0;
- u8 *cdat;
- u16 c;
- int rows;
- int bytes;
- u32 eorx, fgx, bgx, fdx;
-
- bytes = p->next_line;
- if (fontheightlog(p))
- dest0 = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
- (xx>>1)*8 + (xx & 1));
- else
- dest0 = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
- (xx>>1)*8 + (xx & 1));
- c = scr_readw(s);
- fgx = expand4l(attr_fgcol(p, c));
- bgx = expand4l(attr_bgcol(p, c));
- eorx = fgx ^ bgx;
-
- while (count--) {
- /* I think, unrolling the loops like in the 1 plane case isn't
- * practicable here, because the body is much longer for 4
- * planes (mostly the dup4l()). I guess, unrolling this would
- * need more than 256 bytes and so exceed the instruction
- * cache :-(
- */
-
- c = scr_readw(s++) & p->charmask;
- if (fontheightlog(p))
- cdat = p->fontdata + (c << fontheightlog(p));
- else
- cdat = p->fontdata + c * fontheight(p);
-
- for(rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
- fdx = dup4l(*cdat++);
- movepl(dest, (fdx & eorx) ^ bgx);
- }
- INC_4P(dest0);
- }
-}
-
-void fbcon_iplan2p4_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int j;
- int bytes;
-
- if (fontheightlog(p))
- dest = (p->fb_info->screen_base + ((yy * p->next_line) << fontheightlog(p)) +
- (xx>>1)*8 + (xx & 1));
- else
- dest = (p->fb_info->screen_base + yy * p->next_line * fontheight(p) +
- (xx>>1)*8 + (xx & 1));
- j = fontheight(p);
- bytes = p->next_line;
-
- while (j--) {
- /* This should really obey the individual character's
- * background and foreground colors instead of simply
- * inverting.
- */
- dest[0] = ~dest[0];
- dest[2] = ~dest[2];
- dest[4] = ~dest[4];
- dest[6] = ~dest[6];
- dest += bytes;
- }
-}
-
-void fbcon_iplan2p4_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- u32 offset;
- int bytes;
- int lines;
- u32 cval1, cval2;
-
-/* No need to handle right margin, cannot occur with fontwidth == 8 */
-
- bytes = p->next_line;
- if (fontheightlog(p)) {
- lines = p->var.yres - (conp->vc_rows << fontheightlog(p));
- offset = ((p->yscroll + conp->vc_rows) * bytes) << fontheightlog(p);
- } else {
- lines = p->var.yres - conp->vc_rows * fontheight(p);
- offset = (p->yscroll + conp->vc_rows) * bytes * fontheight(p);
- }
- if (lines) {
- expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
- memset_even_4p(p->fb_info->screen_base+offset, lines * bytes, cval1, cval2);
- }
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_iplan2p4 = {
- setup: fbcon_iplan2p4_setup,
- bmove: fbcon_iplan2p4_bmove,
- clear: fbcon_iplan2p4_clear,
- putc: fbcon_iplan2p4_putc,
- putcs: fbcon_iplan2p4_putcs,
- revc: fbcon_iplan2p4_revc,
- clear_margins: fbcon_iplan2p4_clear_margins,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_iplan2p4);
-EXPORT_SYMBOL(fbcon_iplan2p4_setup);
-EXPORT_SYMBOL(fbcon_iplan2p4_bmove);
-EXPORT_SYMBOL(fbcon_iplan2p4_clear);
-EXPORT_SYMBOL(fbcon_iplan2p4_putc);
-EXPORT_SYMBOL(fbcon_iplan2p4_putcs);
-EXPORT_SYMBOL(fbcon_iplan2p4_revc);
-EXPORT_SYMBOL(fbcon_iplan2p4_clear_margins);
diff --git a/drivers/video/fbcon-iplan2p8.c b/drivers/video/fbcon-iplan2p8.c
deleted file mode 100644
index 416f28fd1e59..000000000000
--- a/drivers/video/fbcon-iplan2p8.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * linux/drivers/video/iplan2p8.c -- Low level frame buffer operations for
- * interleaved bitplanes à la Atari (8
- * planes, 2 bytes interleave)
- *
- * Created 5 Apr 1997 by 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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <asm/byteorder.h>
-
-#ifdef __mc68000__
-#include <asm/setup.h>
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-iplan2p8.h>
-
-
- /*
- * Interleaved bitplanes à la Atari (8 planes, 2 bytes interleave)
- *
- * In 8 plane mode, 256 colors would be possible, but only the first
- * 16 are used by the console code (the upper 4 bits are
- * background/unused). For that, the following functions mask off the
- * higher 4 bits of each color.
- */
-
-/* Increment/decrement 8 plane addresses */
-
-#define INC_8P(p) do { if (!((long)(++(p)) & 1)) (p) += 14; } while(0)
-#define DEC_8P(p) do { if ((long)(--(p)) & 1) (p) -= 14; } while(0)
-
-/* Perform the m68k movepl operation extended to 64 bits. */
-static inline void movepl2(u8 *d, u32 val1, u32 val2)
-{
-#if defined __mc68000__ && !defined CPU_M68060_ONLY
- asm volatile ("movepl %1,%0@(0); movepl %2,%0@(8)"
- : : "a" (d), "d" (val1), "d" (val2));
-#else
- d[0] = (val1 >> 24) & 0xff;
- d[2] = (val1 >> 16) & 0xff;
- d[4] = (val1 >> 8) & 0xff;
- d[6] = val1 & 0xff;
- d[8] = (val2 >> 24) & 0xff;
- d[10] = (val2 >> 16) & 0xff;
- d[12] = (val2 >> 8) & 0xff;
- d[14] = val2 & 0xff;
-#endif
-}
-
-/* Sets the bytes in the visible column at d, height h, to the value
- * val1,val2 for a 8 plane screen. The bits of the color in 'color' are
- * moved (8 times) to the respective bytes. This means:
- *
- * for(h times; d += bpr)
- * *d = (color & 1) ? 0xff : 0;
- * *(d+2) = (color & 2) ? 0xff : 0;
- * *(d+4) = (color & 4) ? 0xff : 0;
- * *(d+6) = (color & 8) ? 0xff : 0;
- * *(d+8) = (color & 16) ? 0xff : 0;
- * *(d+10) = (color & 32) ? 0xff : 0;
- * *(d+12) = (color & 64) ? 0xff : 0;
- * *(d+14) = (color & 128) ? 0xff : 0;
- */
-
-static __inline__ void memclear_8p_col(void *d, size_t h, u32 val1,
- u32 val2, int bpr)
-{
- u8 *dd = d;
- do {
- movepl2(dd, val1, val2);
- dd += bpr;
- } while (--h);
-}
-
-/* Sets a 8 plane region from 'd', length 'count' bytes, to the color
- * val1..val4. 'd' has to be an even address and count must be divisible
- * by 16, because only whole words and all planes are accessed. I.e.:
- *
- * for(count/16 times)
- * *d = *(d+1) = (color & 1) ? 0xff : 0;
- * *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
- * *(d+4) = *(d+5) = (color & 4) ? 0xff : 0;
- * *(d+6) = *(d+7) = (color & 8) ? 0xff : 0;
- * *(d+8) = *(d+9) = (color & 16) ? 0xff : 0;
- * *(d+10) = *(d+11) = (color & 32) ? 0xff : 0;
- * *(d+12) = *(d+13) = (color & 64) ? 0xff : 0;
- * *(d+14) = *(d+15) = (color & 128) ? 0xff : 0;
- */
-
-static __inline__ void memset_even_8p(void *d, size_t count, u32 val1,
- u32 val2, u32 val3, u32 val4)
-{
- u32 *dd = d;
-
- count /= 16;
- while (count--) {
- *dd++ = val1;
- *dd++ = val2;
- *dd++ = val3;
- *dd++ = val4;
- }
-}
-
-/* Copies a 8 plane column from 's', height 'h', to 'd'. */
-
-static __inline__ void memmove_8p_col (void *d, void *s, int h, int bpr)
-{
- u8 *dd = d, *ss = s;
-
- while (h--) {
- dd[0] = ss[0];
- dd[2] = ss[2];
- dd[4] = ss[4];
- dd[6] = ss[6];
- dd[8] = ss[8];
- dd[10] = ss[10];
- dd[12] = ss[12];
- dd[14] = ss[14];
- dd += bpr;
- ss += bpr;
- }
-}
-
-
-/* This expands a 8 bit color into two longs for two movepl (8 plane)
- * operations.
- */
-
-static const u32 four2long[] =
-{
- 0x00000000, 0xff000000, 0x00ff0000, 0xffff0000,
- 0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00,
- 0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff,
- 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff,
-};
-
-static __inline__ void expand8dl(u8 c, u32 *ret1, u32 *ret2)
-{
- *ret1 = four2long[c & 15];
- *ret2 = four2long[c >> 4];
-}
-
-
-/* This expands a 8 bit color into four longs for four movel operations
- * (8 planes).
- */
-
-static const u32 two2word[] =
-{
-#ifndef __LITTLE_ENDIAN
- 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
-#else
- 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
-#endif
-};
-
-static inline void expand8ql(u8 c, u32 *rv1, u32 *rv2, u32 *rv3, u32 *rv4)
-{
- *rv1 = two2word[c & 4];
- *rv2 = two2word[(c >> 2) & 4];
- *rv3 = two2word[(c >> 4) & 4];
- *rv4 = two2word[c >> 6];
-}
-
-
-/* This duplicates a byte 4 times into a long. */
-
-static __inline__ u32 dup4l(u8 c)
-{
- u32 rv;
-
- rv = c;
- rv |= rv << 8;
- rv |= rv << 16;
- return rv;
-}
-
-
-void fbcon_iplan2p8_setup(struct display *p)
-{
- p->next_line = p->var.xres_virtual;
- p->next_plane = 2;
-}
-
-void fbcon_iplan2p8_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- /* bmove() has to distinguish two major cases: If both, source and
- * destination, start at even addresses or both are at odd
- * addresses, just the first odd and last even column (if present)
- * require special treatment (memmove_col()). The rest between
- * then can be copied by normal operations, because all adjacent
- * bytes are affected and are to be stored in the same order.
- * The pathological case is when the move should go from an odd
- * address to an even or vice versa. Since the bytes in the plane
- * words must be assembled in new order, it seems wisest to make
- * all movements by memmove_col().
- */
-
- if (sx == 0 && dx == 0 && width * 8 == p->next_line) {
- /* Special (but often used) case: Moving whole lines can be
- * done with memmove()
- */
- fast_memmove(p->fb_info->screen_base + dy * p->next_line * fontheight(p),
- p->fb_info->screen_base + sy * p->next_line * fontheight(p),
- p->next_line * height * fontheight(p));
- } else {
- int rows, cols;
- u8 *src;
- u8 *dst;
- int bytes = p->next_line;
- int linesize;
- u_int colsize;
- u_int upwards = (dy < sy) || (dy == sy && dx < sx);
-
- if (fontheightlog(p)) {
- linesize = bytes << fontheightlog(p);
- colsize = height << fontheightlog(p);
- } else {
- linesize = bytes * fontheight(p);
- colsize = height * fontheight(p);
- }
- if ((sx & 1) == (dx & 1)) {
- /* odd->odd or even->even */
-
- if (upwards) {
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
- if (sx & 1) {
- memmove_8p_col(dst, src, colsize, bytes);
- src += 15;
- dst += 15;
- --width;
- }
- if (width > 1) {
- for(rows = colsize; rows > 0; --rows) {
- fast_memmove (dst, src, (width >> 1) * 16);
- src += bytes;
- dst += bytes;
- }
- }
-
- if (width & 1) {
- src -= colsize * bytes;
- dst -= colsize * bytes;
- memmove_8p_col(dst + (width>>1)*16, src + (width>>1)*16,
- colsize, bytes);
- }
- } else {
- if (!((sx+width-1) & 1)) {
- src = p->fb_info->screen_base + sy * linesize + ((sx+width-1)>>1)*16;
- dst = p->fb_info->screen_base + dy * linesize + ((dx+width-1)>>1)*16;
- memmove_8p_col(dst, src, colsize, bytes);
- --width;
- }
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
- if (width > 1) {
- src += colsize * bytes + (sx & 1)*15;
- dst += colsize * bytes + (sx & 1)*15;
- for(rows = colsize; rows > 0; --rows) {
- src -= bytes;
- dst -= bytes;
- fast_memmove (dst, src, (width>>1)*16);
- }
- }
- if (width & 1)
- memmove_8p_col(dst-15, src-15, colsize, bytes);
- }
- } else {
- /* odd->even or even->odd */
-
- if (upwards) {
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
- for(cols = width; cols > 0; --cols) {
- memmove_8p_col(dst, src, colsize, bytes);
- INC_8P(src);
- INC_8P(dst);
- }
- } else {
- sx += width-1;
- dx += width-1;
- src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
- dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
- for(cols = width; cols > 0; --cols) {
- memmove_8p_col(dst, src, colsize, bytes);
- DEC_8P(src);
- DEC_8P(dst);
- }
- }
- }
- }
-}
-
-void fbcon_iplan2p8_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- u32 offset;
- u8 *start;
- int rows;
- int bytes = p->next_line;
- int lines;
- u32 size;
- u32 cval1, cval2, cval3, cval4, pcval1, pcval2;
-
- expand8ql(attr_bgcol_ec(p,conp), &cval1, &cval2, &cval3, &cval4);
-
- if (fontheightlog(p))
- lines = height << fontheightlog(p);
- else
- lines = height * fontheight(p);
-
- if (sx == 0 && width * 8 == bytes) {
- if (fontheightlog(p))
- offset = (sy * bytes) << fontheightlog(p);
- else
- offset = sy * bytes * fontheight(p);
- size = lines * bytes;
- memset_even_8p(p->fb_info->screen_base+offset, size, cval1, cval2, cval3, cval4);
- } else {
- if (fontheightlog(p))
- offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*16 + (sx & 1);
- else
- offset = sy * bytes * fontheight(p) + (sx>>1)*16 + (sx & 1);
- start = p->fb_info->screen_base + offset;
- expand8dl(attr_bgcol_ec(p,conp), &pcval1, &pcval2);
-
- /* Clears are split if the region starts at an odd column or
- * end at an even column. These extra columns are spread
- * across the interleaved planes. All in between can be
- * cleared by normal fb_memclear_small(), because both bytes of
- * the single plane words are affected.
- */
-
- if (sx & 1) {
- memclear_8p_col(start, lines, pcval1, pcval2, bytes);
- start += 7;
- width--;
- }
- if (width & 1) {
- memclear_8p_col(start + (width>>1)*16, lines, pcval1,
- pcval2, bytes);
- width--;
- }
- if (width)
- for(rows = lines; rows-- ; start += bytes)
- memset_even_8p(start, width*8, cval1, cval2, cval3, cval4);
- }
-}
-
-void fbcon_iplan2p8_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- u8 *dest;
- u8 *cdat;
- int rows;
- int bytes = p->next_line;
- u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
-
- if (fontheightlog(p)) {
- dest = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
- (xx>>1)*16 + (xx & 1));
- cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
- } else {
- dest = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
- (xx>>1)*16 + (xx & 1));
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- }
-
- expand8dl(attr_fgcol(p,c), &fgx1, &fgx2);
- expand8dl(attr_bgcol(p,c), &bgx1, &bgx2);
- eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2;
-
- for(rows = fontheight(p) ; rows-- ; dest += bytes) {
- fdx = dup4l(*cdat++);
- movepl2(dest, (fdx & eorx1) ^ bgx1, (fdx & eorx2) ^ bgx2);
- }
-}
-
-void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- u8 *dest, *dest0;
- u8 *cdat;
- u16 c;
- int rows;
- int bytes;
- u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
-
- bytes = p->next_line;
- if (fontheightlog(p))
- dest0 = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
- (xx>>1)*16 + (xx & 1));
- else
- dest0 = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
- (xx>>1)*16 + (xx & 1));
-
- c = scr_readw(s);
- expand8dl(attr_fgcol(p, c), &fgx1, &fgx2);
- expand8dl(attr_bgcol(p, c), &bgx1, &bgx2);
- eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2;
-
- while (count--) {
-
- /* I think, unrolling the loops like in the 1 plane case isn't
- * practicable here, because the body is much longer for 4
- * planes (mostly the dup4l()). I guess, unrolling this would
- * need more than 256 bytes and so exceed the instruction
- * cache :-(
- */
-
- c = scr_readw(s++) & p->charmask;
- if (fontheightlog(p))
- cdat = p->fontdata + (c << fontheightlog(p));
- else
- cdat = p->fontdata + c * fontheight(p);
-
- for(rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
- fdx = dup4l(*cdat++);
- movepl2(dest, (fdx & eorx1) ^ bgx1, (fdx & eorx2) ^ bgx2);
- }
- INC_8P(dest0);
- }
-}
-
-void fbcon_iplan2p8_revc(struct display *p, int xx, int yy)
-{
- u8 *dest;
- int j;
- int bytes;
-
- if (fontheightlog(p))
- dest = (p->fb_info->screen_base + ((yy * p->next_line) << fontheightlog(p)) +
- (xx>>1)*16 + (xx & 1));
- else
- dest = (p->fb_info->screen_base + yy * p->next_line * fontheight(p) +
- (xx>>1)*16 + (xx & 1));
- j = fontheight(p);
- bytes = p->next_line;
-
- while (j--) {
- /* This should really obey the individual character's
- * background and foreground colors instead of simply
- * inverting. For 8 plane mode, only the lower 4 bits of the
- * color are inverted, because only these color registers have
- * been set up.
- */
- dest[0] = ~dest[0];
- dest[2] = ~dest[2];
- dest[4] = ~dest[4];
- dest[6] = ~dest[6];
- dest += bytes;
- }
-}
-
-void fbcon_iplan2p8_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- u32 offset;
- int bytes;
- int lines;
- u32 cval1, cval2, cval3, cval4;
-
-/* No need to handle right margin, cannot occur with fontwidth == 8 */
-
- bytes = p->next_line;
- if (fontheightlog(p)) {
- lines = p->var.yres - (conp->vc_rows << fontheightlog(p));
- offset = ((p->yscroll + conp->vc_rows) * bytes) << fontheightlog(p);
- } else {
- lines = p->var.yres - conp->vc_rows * fontheight(p);
- offset = (p->yscroll + conp->vc_rows) * bytes * fontheight(p);
- }
- if (lines) {
- expand8ql(attr_bgcol_ec(p,conp), &cval1, &cval2, &cval3, &cval4);
- memset_even_8p(p->fb_info->screen_base+offset, lines * bytes,
- cval1, cval2, cval3, cval4);
- }
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_iplan2p8 = {
- setup: fbcon_iplan2p8_setup,
- bmove: fbcon_iplan2p8_bmove,
- clear: fbcon_iplan2p8_clear,
- putc: fbcon_iplan2p8_putc,
- putcs: fbcon_iplan2p8_putcs,
- revc: fbcon_iplan2p8_revc,
- clear_margins: fbcon_iplan2p8_clear_margins,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_iplan2p8);
-EXPORT_SYMBOL(fbcon_iplan2p8_setup);
-EXPORT_SYMBOL(fbcon_iplan2p8_bmove);
-EXPORT_SYMBOL(fbcon_iplan2p8_clear);
-EXPORT_SYMBOL(fbcon_iplan2p8_putc);
-EXPORT_SYMBOL(fbcon_iplan2p8_putcs);
-EXPORT_SYMBOL(fbcon_iplan2p8_revc);
-EXPORT_SYMBOL(fbcon_iplan2p8_clear_margins);
diff --git a/drivers/video/fbcon-mfb.c b/drivers/video/fbcon-mfb.c
deleted file mode 100644
index 21b7b3ddaba7..000000000000
--- a/drivers/video/fbcon-mfb.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * linux/drivers/video/mfb.c -- Low level frame buffer operations for
- * monochrome
- *
- * Created 5 Apr 1997 by 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/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-
-
- /*
- * Monochrome
- */
-
-void fbcon_mfb_setup(struct display *p)
-{
- if (p->fb_info->fix.line_length)
- p->next_line = p->fb_info->fix.line_length;
- else
- p->next_line = p->var.xres_virtual>>3;
- p->next_plane = 0;
-}
-
-void fbcon_mfb_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- u8 *src, *dest;
- u_int rows;
-
- if (sx == 0 && dx == 0 && width == p->next_line) {
- src = p->fb_info->screen_base+sy*fontheight(p)*width;
- dest = p->fb_info->screen_base+dy*fontheight(p)*width;
- fb_memmove(dest, src, height*fontheight(p)*width);
- } else if (dy <= sy) {
- src = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
- dest = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
- for (rows = height*fontheight(p); rows--;) {
- fb_memmove(dest, src, width);
- src += p->next_line;
- dest += p->next_line;
- }
- } else {
- src = p->fb_info->screen_base+((sy+height)*fontheight(p)-1)*p->next_line+sx;
- dest = p->fb_info->screen_base+((dy+height)*fontheight(p)-1)*p->next_line+dx;
- for (rows = height*fontheight(p); rows--;) {
- fb_memmove(dest, src, width);
- src -= p->next_line;
- dest -= p->next_line;
- }
- }
-}
-
-void fbcon_mfb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- u8 *dest;
- u_int rows;
- int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
- dest = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-
- if (sx == 0 && width == p->next_line) {
- if (inverse)
- fb_memset255(dest, height*fontheight(p)*width);
- else
- fb_memclear(dest, height*fontheight(p)*width);
- } else
- for (rows = height*fontheight(p); rows--; dest += p->next_line)
- if (inverse)
- fb_memset255(dest, width);
- else
- fb_memclear_small(dest, width);
-}
-
-void fbcon_mfb_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- u8 *dest, *cdat;
- u_int rows, bold, revs, underl;
- u8 d;
-
- dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- cdat = p->fontdata+(c&p->charmask)*fontheight(p);
- bold = attr_bold(p,c);
- revs = attr_reverse(p,c);
- underl = attr_underline(p,c);
-
- for (rows = fontheight(p); rows--; dest += p->next_line) {
- d = *cdat++;
- if (underl && !rows)
- d = 0xff;
- else if (bold)
- d |= d>>1;
- if (revs)
- d = ~d;
- fb_writeb (d, dest);
- }
-}
-
-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 d;
- u16 c;
-
- dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- c = scr_readw(s);
- bold = attr_bold(p, c);
- revs = attr_reverse(p, c);
- underl = attr_underline(p, c);
-
- while (count--) {
- c = scr_readw(s++) & p->charmask;
- dest = dest0++;
- cdat = p->fontdata+c*fontheight(p);
- for (rows = fontheight(p); rows--; dest += p->next_line) {
- d = *cdat++;
- if (underl && !rows)
- d = 0xff;
- else if (bold)
- d |= d>>1;
- if (revs)
- d = ~d;
- fb_writeb (d, dest);
- }
- }
-}
-
-void fbcon_mfb_revc(struct display *p, int xx, int yy)
-{
- u8 *dest, d;
- u_int rows;
-
- dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
- for (rows = fontheight(p); rows--; dest += p->next_line) {
- d = fb_readb(dest);
- fb_writeb (~d, dest);
- }
-}
-
-void fbcon_mfb_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- u8 *dest;
- int height, bottom;
- int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
- /* XXX Need to handle right margin? */
-
- height = p->var.yres - conp->vc_rows * fontheight(p);
- if (!height)
- return;
- bottom = conp->vc_rows + p->yscroll;
- if (bottom >= p->vrows)
- bottom -= p->vrows;
- dest = p->fb_info->screen_base + bottom * fontheight(p) * p->next_line;
- if (inverse)
- fb_memset255(dest, height * p->next_line);
- else
- fb_memclear(dest, height * p->next_line);
-}
-
-
- /*
- * `switch' for the low level operations
- */
-
-struct display_switch fbcon_mfb = {
- setup: fbcon_mfb_setup,
- bmove: fbcon_mfb_bmove,
- clear: fbcon_mfb_clear,
- putc: fbcon_mfb_putc,
- putcs: fbcon_mfb_putcs,
- revc: fbcon_mfb_revc,
- clear_margins: fbcon_mfb_clear_margins,
- fontwidthmask: FONTWIDTH(8)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_mfb);
-EXPORT_SYMBOL(fbcon_mfb_setup);
-EXPORT_SYMBOL(fbcon_mfb_bmove);
-EXPORT_SYMBOL(fbcon_mfb_clear);
-EXPORT_SYMBOL(fbcon_mfb_putc);
-EXPORT_SYMBOL(fbcon_mfb_putcs);
-EXPORT_SYMBOL(fbcon_mfb_revc);
-EXPORT_SYMBOL(fbcon_mfb_clear_margins);
diff --git a/drivers/video/fbcon-vga-planes.c b/drivers/video/fbcon-vga-planes.c
deleted file mode 100644
index b350820fd3c1..000000000000
--- a/drivers/video/fbcon-vga-planes.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * linux/drivers/video/fbcon-vga-planes.c -- Low level frame buffer operations
- * for VGA 4-plane modes
- *
- * Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
- * Based on code by Michael Schmitz
- * Based on the old macfb.c 4bpp code by Alan Cox
- *
- * 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 <linux/vt_buffer.h>
-
-#include <asm/io.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-vga-planes.h>
-
-#define GRAPHICS_ADDR_REG 0x3ce /* Graphics address register. */
-#define GRAPHICS_DATA_REG 0x3cf /* Graphics data register. */
-
-#define SET_RESET_INDEX 0 /* Set/Reset Register index. */
-#define ENABLE_SET_RESET_INDEX 1 /* Enable Set/Reset Register index. */
-#define DATA_ROTATE_INDEX 3 /* Data Rotate Register index. */
-#define GRAPHICS_MODE_INDEX 5 /* Graphics Mode Register index. */
-#define BIT_MASK_INDEX 8 /* Bit Mask Register index. */
-
-/* The VGA's weird architecture often requires that we read a byte and
- write a byte to the same location. It doesn't matter *what* byte
- we write, however. This is because all the action goes on behind
- the scenes in the VGA's 32-bit latch register, and reading and writing
- video memory just invokes latch behavior.
-
- To avoid race conditions (is this necessary?), reading and writing
- the memory byte should be done with a single instruction. One
- suitable instruction is the x86 bitwise OR. The following
- read-modify-write routine should optimize to one such bitwise
- OR. */
-static inline void rmw(volatile char *p)
-{
- readb(p);
- writeb(1, p);
-}
-
-/* Set the Graphics Mode Register. Bits 0-1 are write mode, bit 3 is
- read mode. */
-static inline void setmode(int mode)
-{
- outb(GRAPHICS_MODE_INDEX, GRAPHICS_ADDR_REG);
- outb(mode, GRAPHICS_DATA_REG);
-}
-
-/* Select the Bit Mask Register. */
-static inline void selectmask(void)
-{
- outb(BIT_MASK_INDEX, GRAPHICS_ADDR_REG);
-}
-
-/* Set the value of the Bit Mask Register. It must already have been
- selected with selectmask(). */
-static inline void setmask(int mask)
-{
- outb(mask, GRAPHICS_DATA_REG);
-}
-
-/* Set the Data Rotate Register. Bits 0-2 are rotate count, bits 3-4
- are logical operation (0=NOP, 1=AND, 2=OR, 3=XOR). */
-static inline void setop(int op)
-{
- outb(DATA_ROTATE_INDEX, GRAPHICS_ADDR_REG);
- outb(op, GRAPHICS_DATA_REG);
-}
-
-/* Set the Enable Set/Reset Register. The code here always uses value
- 0xf for this register. */
-static inline void setsr(int sr)
-{
- outb(ENABLE_SET_RESET_INDEX, GRAPHICS_ADDR_REG);
- outb(sr, GRAPHICS_DATA_REG);
-}
-
-/* Set the Set/Reset Register. */
-static inline void setcolor(int color)
-{
- outb(SET_RESET_INDEX, GRAPHICS_ADDR_REG);
- outb(color, GRAPHICS_DATA_REG);
-}
-
-/* Set the value in the Graphics Address Register. */
-static inline void setindex(int index)
-{
- outb(index, GRAPHICS_ADDR_REG);
-}
-
-void fbcon_vga_planes_setup(struct display *p)
-{
-}
-
-void fbcon_vga_planes_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- char *src;
- char *dest;
- int line_ofs;
- int x;
-
- setmode(1);
- setop(0);
- setsr(0xf);
-
- sy *= fontheight(p);
- dy *= fontheight(p);
- height *= fontheight(p);
-
- if (dy < sy || (dy == sy && dx < sx)) {
- line_ofs = p->fb_info->fix.line_length - width;
- dest = p->fb_info->screen_base + dx + dy * p->fb_info->fix.line_length;
- src = p->fb_info->screen_base + sx + sy * p->fb_info->fix.line_length;
- while (height--) {
- for (x = 0; x < width; x++) {
- readb(src);
- writeb(0, dest);
- dest++;
- src++;
- }
- src += line_ofs;
- dest += line_ofs;
- }
- } else {
- line_ofs = p->fb_info->fix.line_length - width;
- dest = p->fb_info->screen_base + dx + width + (dy + height - 1) * p->fb_info->fix.line_length;
- src = p->fb_info->screen_base + sx + width + (sy + height - 1) * p->fb_info->fix.line_length;
- while (height--) {
- for (x = 0; x < width; x++) {
- dest--;
- src--;
- readb(src);
- writeb(0, dest);
- }
- src -= line_ofs;
- dest -= line_ofs;
- }
- }
-}
-
-void fbcon_vga_planes_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- int line_ofs = p->fb_info->fix.line_length - width;
- char *where;
- int x;
-
- setmode(0);
- setop(0);
- setsr(0xf);
- setcolor(attr_bgcol_ec(p, conp));
- selectmask();
-
- setmask(0xff);
-
- sy *= fontheight(p);
- height *= fontheight(p);
-
- where = p->fb_info->screen_base + sx + sy * p->fb_info->fix.line_length;
- while (height--) {
- for (x = 0; x < width; x++) {
- writeb(0, where);
- where++;
- }
- where += line_ofs;
- }
-}
-
-void fbcon_ega_planes_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
-{
- int fg = attr_fgcol(p,c);
- int bg = attr_bgcol(p,c);
-
- int y;
- u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- char *where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
-
- setmode(0);
- setop(0);
- setsr(0xf);
- setcolor(bg);
- selectmask();
-
- setmask(0xff);
- for (y = 0; y < fontheight(p); y++, where += p->fb_info->fix.line_length)
- rmw(where);
-
- where -= p->fb_info->fix.line_length * y;
- setcolor(fg);
- selectmask();
- for (y = 0; y < fontheight(p); y++, where += p->fb_info->fix.line_length)
- if (cdat[y]) {
- setmask(cdat[y]);
- rmw(where);
- }
-}
-
-void fbcon_vga_planes_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
-{
- int fg = attr_fgcol(p,c);
- int bg = attr_bgcol(p,c);
-
- int y;
- u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- char *where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
-
- setmode(2);
- setop(0);
- setsr(0xf);
- setcolor(fg);
- selectmask();
-
- setmask(0xff);
- writeb(bg, where);
- rmb();
- readb(where); /* fill latches */
- setmode(3);
- wmb();
- for (y = 0; y < fontheight(p); y++, where += p->fb_info->fix.line_length)
- writeb(cdat[y], where);
- wmb();
-}
-
-/* 28.50 in my test */
-void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
- int count, int yy, int xx)
-{
- u16 c = scr_readw(s);
- int fg = attr_fgcol(p, c);
- int bg = attr_bgcol(p, c);
-
- char *where;
- int n;
-
- setmode(2);
- setop(0);
- selectmask();
-
- setmask(0xff);
- where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
- writeb(bg, where);
- rmb();
- readb(where); /* fill latches */
- wmb();
- selectmask();
- for (n = 0; n < count; n++) {
- int c = scr_readw(s++) & p->charmask;
- u8 *cdat = p->fontdata + c * fontheight(p);
- u8 *end = cdat + fontheight(p);
-
- while (cdat < end) {
- outb(*cdat++, GRAPHICS_DATA_REG);
- wmb();
- writeb(fg, where);
- where += p->fb_info->fix.line_length;
- }
- where += 1 - p->fb_info->fix.line_length * fontheight(p);
- }
-
- wmb();
-}
-
-/* 6.96 in my test */
-void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
- int count, int yy, int xx)
-{
- u16 c = scr_readw(s);
- int fg = attr_fgcol(p, c);
- int bg = attr_bgcol(p, c);
-
- char *where;
- int n;
-
- setmode(2);
- setop(0);
- setsr(0xf);
- setcolor(fg);
- selectmask();
-
- setmask(0xff);
- where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
- writeb(bg, where);
- rmb();
- readb(where); /* fill latches */
- setmode(3);
- wmb();
- for (n = 0; n < count; n++) {
- int y;
- int c = scr_readw(s++) & p->charmask;
- u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-
- for (y = 0; y < fontheight(p); y++, cdat++) {
- writeb (*cdat, where);
- where += p->fb_info->fix.line_length;
- }
- where += 1 - p->fb_info->fix.line_length * fontheight(p);
- }
-
- wmb();
-}
-
-void fbcon_vga_planes_revc(struct display *p, int xx, int yy)
-{
- char *where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
- int y;
-
- setmode(0);
- setop(0x18);
- setsr(0xf);
- setcolor(0xf);
- selectmask();
-
- setmask(0xff);
- for (y = 0; y < fontheight(p); y++) {
- rmw(where);
- where += p->fb_info->fix.line_length;
- }
-}
-
-struct display_switch fbcon_vga_planes = {
- setup: fbcon_vga_planes_setup,
- bmove: fbcon_vga_planes_bmove,
- clear: fbcon_vga_planes_clear,
- putc: fbcon_vga_planes_putc,
- putcs: fbcon_vga_planes_putcs,
- revc: fbcon_vga_planes_revc,
- fontwidthmask: FONTWIDTH(8)
-};
-
-struct display_switch fbcon_ega_planes = {
- setup: fbcon_vga_planes_setup,
- bmove: fbcon_vga_planes_bmove,
- clear: fbcon_vga_planes_clear,
- putc: fbcon_ega_planes_putc,
- putcs: fbcon_ega_planes_putcs,
- revc: fbcon_vga_planes_revc,
- fontwidthmask: FONTWIDTH(8)
-};
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fbcon_vga_planes);
-EXPORT_SYMBOL(fbcon_vga_planes_setup);
-EXPORT_SYMBOL(fbcon_vga_planes_bmove);
-EXPORT_SYMBOL(fbcon_vga_planes_clear);
-EXPORT_SYMBOL(fbcon_vga_planes_putc);
-EXPORT_SYMBOL(fbcon_vga_planes_putcs);
-EXPORT_SYMBOL(fbcon_vga_planes_revc);
-
-EXPORT_SYMBOL(fbcon_ega_planes);
-EXPORT_SYMBOL(fbcon_ega_planes_putc);
-EXPORT_SYMBOL(fbcon_ega_planes_putcs);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/video/fbcon.c b/drivers/video/fbcon.c
deleted file mode 100644
index 69374876d64f..000000000000
--- a/drivers/video/fbcon.c
+++ /dev/null
@@ -1,2508 +0,0 @@
-/*
- * linux/drivers/video/fbcon.c -- Low level frame buffer based console driver
- *
- * Copyright (C) 1995 Geert Uytterhoeven
- *
- *
- * This file is based on the original Amiga console driver (amicon.c):
- *
- * Copyright (C) 1993 Hamish Macdonald
- * Greg Harp
- * Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
- *
- * with work by William Rucklidge (wjr@cs.cornell.edu)
- * Geert Uytterhoeven
- * Jes Sorensen (jds@kom.auc.dk)
- * Martin Apel
- *
- * and on the original Atari console driver (atacon.c):
- *
- * Copyright (C) 1993 Bjoern Brauel
- * Roman Hodek
- *
- * with work by Guenther Kelleter
- * 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
- * and software scrollback added by
- * Jakub Jelinek (jj@ultra.linux.cz)
- *
- * Random hacking by Martin Mares <mj@ucw.cz>
- *
- * 2001 - Documented with DocBook
- * - Brad Douglas <brad@neruo.com>
- *
- * The low level operations for the various display memory organizations are
- * now in separate source files.
- *
- * Currently the following organizations are supported:
- *
- * o afb Amiga bitplanes
- * o cfb{2,4,8,16,24,32} Packed pixels
- * 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)
- *
- *
- * 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.
- */
-
-#undef FBCONDEBUG
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/delay.h> /* MSch: for IRQ probe */
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/kd.h>
-#include <linux/slab.h>
-#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>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-#endif /* CONFIG_AMIGA */
-#ifdef CONFIG_ATARI
-#include <asm/atariints.h>
-#endif
-#ifdef CONFIG_MAC
-#include <asm/macints.h>
-#endif
-#if defined(__mc68000__) || defined(CONFIG_APUS)
-#include <asm/machdep.h>
-#include <asm/setup.h>
-#endif
-#ifdef CONFIG_FBCON_VGA_PLANES
-#include <asm/io.h>
-#endif
-#define INCLUDE_LINUX_LOGO_DATA
-#include <asm/linux_logo.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mac.h> /* for 6x11 font on mac */
-#include <video/font.h>
-
-#ifdef FBCONDEBUG
-# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-#else
-# define DPRINTK(fmt, args...)
-#endif
-
-#define LOGO_H 80
-#define LOGO_W 80
-#define LOGO_LINE (LOGO_W/8)
-
-struct display fb_display[MAX_NR_CONSOLES];
-char con2fb_map[MAX_NR_CONSOLES];
-static int logo_lines;
-static int logo_shown = -1;
-/* Software scrollback */
-int fbcon_softback_size = 32768;
-static unsigned long softback_buf, softback_curr;
-static unsigned long softback_in;
-static unsigned long softback_top, softback_end;
-static int softback_lines;
-
-#define REFCOUNT(fd) (((int *)(fd))[-1])
-#define FNTSIZE(fd) (((int *)(fd))[-2])
-#define FNTCHARCNT(fd) (((int *)(fd))[-3])
-#define FNTSUM(fd) (((int *)(fd))[-4])
-#define FONT_EXTRA_WORDS 4
-
-#define CM_SOFTBACK (8)
-
-#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * conp->vc_size_row)
-
-static void fbcon_free_font(struct display *);
-static int fbcon_set_origin(struct vc_data *);
-
-/*
- * 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
- */
-
-static int cursor_drawn;
-
-#define CURSOR_DRAW_DELAY (1)
-
-/* # VBL ints between cursor state changes */
-#define ARM_CURSOR_BLINK_RATE (10)
-#define AMIGA_CURSOR_BLINK_RATE (20)
-#define ATARI_CURSOR_BLINK_RATE (42)
-#define MAC_CURSOR_BLINK_RATE (32)
-#define DEFAULT_CURSOR_BLINK_RATE (20)
-
-static int vbl_cursor_cnt;
-static int cursor_on;
-static int cursor_blink_rate;
-
-static inline void cursor_undrawn(void)
-{
- vbl_cursor_cnt = 0;
- cursor_drawn = 0;
-}
-
-
-#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
-
-
-/*
- * Interface used by the world
- */
-
-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 unsigned short *s, int count,
- int ypos, int xpos);
-static void fbcon_cursor(struct vc_data *conp, int mode);
-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(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(struct vc_data *conp, int lines);
-
-
-/*
- * Internal routines
- */
-
-static void fbcon_setup(int con, int init, int logo);
-static __inline__ int real_y(struct display *p, int ypos);
-static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
-static __inline__ void updatescrollmode(struct display *p);
-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);
-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,
- struct display *p, int count);
-static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width, u_int y_break);
-
-static int fbcon_show_logo(void);
-
-#ifdef CONFIG_MAC
-/*
- * On the Macintoy, there may or may not be a working VBL int. We need to probe
- */
-static int vbl_detected;
-
-static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
-{
- vbl_detected++;
-}
-#endif
-
-static void cursor_timer_handler(unsigned long dev_addr);
-
-static struct timer_list cursor_timer =
- TIMER_INITIALIZER(cursor_timer_handler, 0, 0);
-
-static void cursor_timer_handler(unsigned long dev_addr)
-{
- fbcon_vbl_handler(0, NULL, NULL);
- cursor_timer.expires = jiffies+HZ/50;
- add_timer(&cursor_timer);
-}
-
-
-/**
- * PROC_CONSOLE - find the attached tty or visible console
- * @info: frame buffer info structure
- *
- * Finds the tty attached to the process or visible console if
- * the process is not directly attached to a tty (e.g. remote
- * user) for device @info.
- *
- * Returns -1 errno on error, or tty/visible console number
- * on success.
- *
- */
-
-int PROC_CONSOLE(const struct fb_info *info)
-{
- int fgc;
-
- if (info->display_fg != NULL)
- fgc = info->display_fg->vc_num;
- else
- return -1;
-
- if (!current->tty)
- return fgc;
-
- if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
- /* XXX Should report error here? */
- return fgc;
-
- if (minor(current->tty->device) < 1)
- return fgc;
-
- return minor(current->tty->device) - 1;
-}
-
-
-/**
- * set_all_vcs - set all virtual consoles to match
- * @fbidx: frame buffer index (e.g. fb0, fb1, ...)
- * @fb: frame buffer ops structure
- * @var: frame buffer screen structure to set
- * @info: frame buffer info structure
- *
- * Set all virtual consoles to match screen info set in @var
- * for device @info.
- *
- * Returns negative errno on error, or zero on success.
- *
- */
-
-int set_all_vcs(int fbidx, struct fb_ops *fb, struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- int unit, err;
-
- var->activate |= FB_ACTIVATE_TEST;
- err = fb->fb_set_var(var, PROC_CONSOLE(info), info);
- var->activate &= ~FB_ACTIVATE_TEST;
- if (err)
- return err;
- for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
- if (fb_display[unit].conp && con2fb_map[unit] == fbidx)
- fb->fb_set_var(var, unit, info);
- return 0;
-}
-
-
-/**
- * set_con2fb_map - map console to frame buffer device
- * @unit: virtual console number to map
- * @newidx: frame buffer index to map virtual console to
- *
- * Maps a virtual console @unit to a frame buffer device
- * @newidx.
- *
- */
-
-void set_con2fb_map(int unit, int newidx)
-{
- int oldidx = con2fb_map[unit];
- struct fb_info *oldfb, *newfb;
- struct vc_data *conp;
- char *fontdata;
- unsigned short fontwidth, fontheight, fontwidthlog, fontheightlog;
- int userfont;
-
- if (newidx != con2fb_map[unit]) {
- oldfb = registered_fb[oldidx];
- newfb = registered_fb[newidx];
- if (newfb->fbops->owner)
- __MOD_INC_USE_COUNT(newfb->fbops->owner);
- if (newfb->fbops->fb_open && newfb->fbops->fb_open(newfb,0)) {
- if (newfb->fbops->owner)
- __MOD_DEC_USE_COUNT(newfb->fbops->owner);
- return;
- }
- if (oldfb->fbops->fb_release)
- oldfb->fbops->fb_release(oldfb,0);
- if (oldfb->fbops->owner)
- __MOD_DEC_USE_COUNT(oldfb->fbops->owner);
- conp = fb_display[unit].conp;
- fontdata = fb_display[unit].fontdata;
- fontwidth = fb_display[unit]._fontwidth;
- fontheight = fb_display[unit]._fontheight;
- fontwidthlog = fb_display[unit]._fontwidthlog;
- fontheightlog = fb_display[unit]._fontheightlog;
- userfont = fb_display[unit].userfont;
- con2fb_map[unit] = newidx;
- fb_display[unit] = *(newfb->disp);
- fb_display[unit].conp = conp;
- fb_display[unit].fontdata = fontdata;
- fb_display[unit]._fontwidth = fontwidth;
- fb_display[unit]._fontheight = fontheight;
- fb_display[unit]._fontwidthlog = fontwidthlog;
- fb_display[unit]._fontheightlog = fontheightlog;
- fb_display[unit].userfont = userfont;
- fb_display[unit].fb_info = newfb;
- if (conp)
- conp->vc_display_fg = &newfb->display_fg;
- if (!newfb->display_fg)
- newfb->display_fg = conp;
- if (!newfb->changevar)
- newfb->changevar = oldfb->changevar;
- /* tell console var has changed */
- if (newfb->changevar)
- newfb->changevar(unit);
- }
-}
-
-/*
- * Low Level Operations
- */
-
-struct display_switch fbcon_dummy;
-
-/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */
-
-static const char *fbcon_startup(void)
-{
- const char *display_desc = "frame buffer device";
- int irqres = 1;
- static int done = 0;
-
- /*
- * 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) {
- cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
- irqres = request_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0,
- "console/cursor", fbcon_vbl_handler);
- }
-#endif /* CONFIG_AMIGA */
-#ifdef CONFIG_ATARI
- if (MACH_IS_ATARI) {
- cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
- irqres = request_irq(IRQ_AUTO_4, fbcon_vbl_handler, IRQ_TYPE_PRIO,
- "console/cursor", fbcon_vbl_handler);
- }
-#endif /* CONFIG_ATARI */
-
-#ifdef CONFIG_MAC
- /*
- * On a Macintoy, the VBL interrupt may or may not be active.
- * As interrupt based cursor is more reliable and race free, we
- * probe for VBL interrupts.
- */
- if (MACH_IS_MAC) {
- int ct = 0;
- /*
- * Probe for VBL: set temp. handler ...
- */
- irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_detect, 0,
- "console/cursor", fbcon_vbl_detect);
- vbl_detected = 0;
-
- /*
- * ... and spin for 20 ms ...
- */
- while (!vbl_detected && ++ct<1000)
- udelay(20);
-
- if(ct==1000)
- printk("fbcon_startup: No VBL detected, using timer based cursor.\n");
-
- free_irq(IRQ_MAC_VBL, fbcon_vbl_detect);
-
- if (vbl_detected) {
- /*
- * interrupt based cursor ok
- */
- cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
- irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_handler, 0,
- "console/cursor", fbcon_vbl_handler);
- } else {
- /*
- * VBL not detected: fall through, use timer based cursor
- */
- irqres = 1;
- }
- }
-#endif /* CONFIG_MAC */
-
-#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
- cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
- 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;
- add_timer(&cursor_timer);
- }
-
- return display_desc;
-}
-
-
-static void fbcon_init(struct vc_data *conp, int init)
-{
- int unit = conp->vc_num;
- struct fb_info *info;
-
- /* on which frame buffer will we open this console? */
- info = registered_fb[(int)con2fb_map[unit]];
-
- info->changevar = &fbcon_changevar;
- fb_display[unit] = *(info->disp); /* copy from default */
- DPRINTK("mode: %s\n",info->modename);
- DPRINTK("visual: %d\n",fb_display[unit].visual);
- DPRINTK("res: %dx%d-%d\n",fb_display[unit].var.xres,
- fb_display[unit].var.yres,
- fb_display[unit].var.bits_per_pixel);
- fb_display[unit].conp = conp;
- fb_display[unit].fb_info = info;
- /* clear out the cmap so we don't have dangling pointers */
- fb_display[unit].cmap.len = 0;
- fb_display[unit].cmap.red = 0;
- fb_display[unit].cmap.green = 0;
- fb_display[unit].cmap.blue = 0;
- fb_display[unit].cmap.transp = 0;
- fbcon_setup(unit, init, !init);
- /* Must be done after fbcon_setup to prevent excess updates */
- conp->vc_display_fg = &info->display_fg;
- if (!info->display_fg)
- info->display_fg = conp;
-}
-
-
-static void fbcon_deinit(struct vc_data *conp)
-{
- int unit = conp->vc_num;
- struct display *p = &fb_display[unit];
-
- fbcon_free_font(p);
- p->dispsw = &fbcon_dummy;
- p->conp = 0;
-}
-
-
-static int fbcon_changevar(int con)
-{
- if (fb_display[con].conp)
- fbcon_setup(con, 0, 0);
- return 0;
-}
-
-
-static __inline__ void updatescrollmode(struct display *p)
-{
- struct fb_info *info = p->fb_info;
-
- int m;
- if (p->scrollmode & __SCROLL_YFIXED)
- return;
- if (divides(info->fix.ywrapstep, fontheight(p)) &&
- divides(fontheight(p), info->var.yres_virtual))
- m = __SCROLL_YWRAP;
- else if (divides(info->fix.ypanstep, fontheight(p)) &&
- p->var.yres_virtual >= p->var.yres+fontheight(p))
- m = __SCROLL_YPAN;
- else if (p->scrollmode & __SCROLL_YNOMOVE)
- m = __SCROLL_YREDRAW;
- else
- m = __SCROLL_YMOVE;
- p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;
-}
-
-static void fbcon_font_widths(struct display *p)
-{
- int i;
-
- p->_fontwidthlog = 0;
- for (i = 2; i <= 6; i++)
- if (fontwidth(p) == (1 << i))
- p->_fontwidthlog = i;
- p->_fontheightlog = 0;
- for (i = 2; i <= 6; i++)
- if (fontheight(p) == (1 << i))
- p->_fontheightlog = i;
-}
-
-#define fontwidthvalid(p,w) ((p)->dispsw->fontwidthmask & FONTWIDTH(w))
-
-static void fbcon_setup(int con, int init, int logo)
-{
- struct display *p = &fb_display[con];
- struct fb_info *info = p->fb_info;
- struct vc_data *conp = p->conp;
- int nr_rows, nr_cols;
- int old_rows, old_cols;
- unsigned short *save = NULL, *r, *q;
- int i, charcnt = 256;
- struct fbcon_font_desc *font;
-
- if (con != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
- info->fix.type == FB_TYPE_TEXT)
- logo = 0;
-
- p->var.xoffset = p->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
-
- if (con == fg_console && info->fix.type != FB_TYPE_TEXT) {
- if (fbcon_softback_size) {
- if (!softback_buf) {
- softback_buf = (unsigned long)kmalloc(fbcon_softback_size, GFP_KERNEL);
- if (!softback_buf) {
- fbcon_softback_size = 0;
- softback_top = 0;
- }
- }
- } else {
- if (softback_buf) {
- kfree((void *)softback_buf);
- softback_buf = 0;
- softback_top = 0;
- }
- }
- if (softback_buf)
- softback_in = softback_top = softback_curr = softback_buf;
- softback_lines = 0;
- }
-
- for (i = 0; i < MAX_NR_CONSOLES; i++)
- if (i != con && fb_display[i].fb_info == p->fb_info &&
- fb_display[i].conp && fb_display[i].fontdata)
- break;
-
- fbcon_free_font(p);
- if (i < MAX_NR_CONSOLES) {
- struct display *q = &fb_display[i];
-
- if (fontwidthvalid(p,fontwidth(q))) {
- /* If we are not the first console on this
- fb, copy the font from that console */
- p->_fontwidth = q->_fontwidth;
- p->_fontheight = q->_fontheight;
- p->_fontwidthlog = q->_fontwidthlog;
- p->_fontheightlog = q->_fontheightlog;
- p->fontdata = q->fontdata;
- p->userfont = q->userfont;
- if (p->userfont) {
- REFCOUNT(p->fontdata)++;
- charcnt = FNTCHARCNT(p->fontdata);
- }
- con_copy_unimap(con, i);
- }
- }
-
- if (!p->fontdata) {
- if (!p->fb_info->fontname[0] ||
- !(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,fontwidth(p))) {
-#if defined(CONFIG_FBCON_MAC) && defined(CONFIG_MAC)
- if (MACH_IS_MAC)
- /* ++Geert: hack to make 6x11 fonts work on mac */
- p->dispsw = &fbcon_mac;
- else
-#endif
- {
- /* ++Geert: changed from panic() to `correct and continue' */
- printk(KERN_ERR "fbcon_setup: No support for fontwidth %d\n", fontwidth(p));
- p->dispsw = &fbcon_dummy;
- }
- }
- if (p->dispsw->set_font)
- p->dispsw->set_font(p, fontwidth(p), fontheight(p));
- updatescrollmode(p);
-
- old_cols = conp->vc_cols;
- old_rows = conp->vc_rows;
-
- nr_cols = p->var.xres/fontwidth(p);
- nr_rows = p->var.yres/fontheight(p);
-
- if (logo) {
- /* Need to make room for the logo */
- int cnt;
- int step;
-
- logo_lines = (LOGO_H + fontheight(p) - 1) / fontheight(p);
- 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 (scr_readw(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
- * resizing the console.
- */
- if (init) {
- conp->vc_cols = nr_cols;
- conp->vc_rows = nr_rows;
- }
- p->vrows = p->var.yres_virtual/fontheight(p);
- if ((p->var.yres % fontheight(p)) &&
- (p->var.yres_virtual % fontheight(p) < p->var.yres % fontheight(p)))
- p->vrows--;
- conp->vc_can_do_color = p->var.bits_per_pixel != 1;
- conp->vc_complement_mask = conp->vc_can_do_color ? 0x7700 : 0x0800;
- if (charcnt == 256) {
- conp->vc_hi_font_mask = 0;
- p->fgshift = 8;
- p->bgshift = 12;
- p->charmask = 0xff;
- } else {
- conp->vc_hi_font_mask = 0x100;
- if (conp->vc_can_do_color)
- conp->vc_complement_mask <<= 1;
- p->fgshift = 9;
- p->bgshift = 13;
- p->charmask = 0x1ff;
- }
-
- if (p->dispsw == &fbcon_dummy)
- printk(KERN_WARNING "fbcon_setup: type %d (aux %d, depth %d) not "
- "supported\n", info->fix.type, info->fix.type_aux,
- p->var.bits_per_pixel);
- p->dispsw->setup(p);
-
- p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
- p->bgcol = 0;
-
- if (!init) {
- if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows)
- vc_resize_con(nr_rows, nr_cols, con);
- else if (CON_IS_VISIBLE(conp) &&
- vt_cons[conp->vc_num]->vc_mode == KD_TEXT) {
- if (p->dispsw->clear_margins)
- p->dispsw->clear_margins(conp, p, 0);
- update_screen(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 (logo) {
- logo_shown = -2;
- conp->vc_top = logo_lines;
- }
-
- if (con == fg_console && softback_buf) {
- int l = fbcon_softback_size / conp->vc_size_row;
- if (l > 5)
- softback_end = softback_buf + l * conp->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0 would screw
- the operation totally */
- softback_top = 0;
- }
- }
-}
-
-
-/* ====================================================================== */
-
-/* fbcon_XXX routines - interface used by the world
- *
- * This system is now divided into two levels because of complications
- * caused by hardware scrolling. Top level functions:
- *
- * fbcon_bmove(), fbcon_clear(), fbcon_putc()
- *
- * handles y values in range [0, scr_height-1] that correspond to real
- * screen positions. y_wrap shift means that first line of bitmap may be
- * anywhere on this display. These functions convert lineoffsets to
- * bitmap offsets and deal with the wrap-around case by splitting blits.
- *
- * fbcon_bmove_physical_8() -- These functions fast implementations
- * fbcon_clear_physical_8() -- of original fbcon_XXX fns.
- * fbcon_putc_physical_8() -- (fontwidth != 8) may be added later
- *
- * WARNING:
- *
- * At the moment fbcon_putc() cannot blit across vertical wrap boundary
- * Implies should only really hardware scroll in rows. Only reason for
- * restriction is simplicity & efficiency at the moment.
- */
-
-static __inline__ int real_y(struct display *p, int ypos)
-{
- int rows = p->vrows;
-
- ypos += p->yscroll;
- return ypos < rows ? ypos : ypos-rows;
-}
-
-
-static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
- int width)
-{
- 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;
-
- if (!height || !width)
- return;
-
- if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
- (sx <= p->cursor_x) && (p->cursor_x < sx+width)) {
- cursor_undrawn();
- redraw_cursor = 1;
- }
-
- /* Split blits that cross physical y_wrap boundary */
-
- y_break = p->vrows-p->yscroll;
- if (sy < y_break && sy+height-1 >= y_break) {
- u_int b = y_break-sy;
- p->dispsw->clear(conp, p, real_y(p, sy), sx, b, width);
- 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;
-}
-
-
-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 (vt_cons[unit]->vc_mode != KD_TEXT)
- return;
-
- 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 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 (vt_cons[unit]->vc_mode != KD_TEXT)
- return;
-
- if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
- (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;
-}
-
-
-static void fbcon_cursor(struct vc_data *conp, int mode)
-{
- int unit = conp->vc_num;
- struct display *p = &fb_display[unit];
- int y = conp->vc_y;
-
- if (mode & CM_SOFTBACK) {
- mode &= ~CM_SOFTBACK;
- if (softback_lines) {
- if (y + softback_lines >= conp->vc_rows)
- mode = CM_ERASE;
- else
- y += softback_lines;
- }
- } else if (softback_lines)
- fbcon_set_origin(conp);
-
- /* do we have a hardware cursor ? */
- if (p->dispsw->cursor) {
- p->cursor_x = conp->vc_x;
- p->cursor_y = 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 == y &&
- (mode == CM_ERASE) == !cursor_on)
- return;
-
- 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 = 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;
- }
-}
-
-
-static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
-{
- struct display *p;
-
- if (!cursor_on)
- return;
-
- if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
- p = &fb_display[fg_console];
- 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;
- }
-}
-
-static int scrollback_phys_max = 0;
-static int scrollback_max = 0;
-static int scrollback_current = 0;
-
-static __inline__ void ywrap_up(int unit, struct vc_data *conp,
- struct display *p, int count)
-{
- p->yscroll += count;
- if (p->yscroll >= p->vrows) /* Deal with wrap */
- p->yscroll -= p->vrows;
- p->var.xoffset = 0;
- p->var.yoffset = p->yscroll*fontheight(p);
- 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;
-}
-
-
-static __inline__ void ywrap_down(int unit, struct vc_data *conp,
- struct display *p, int count)
-{
- p->yscroll -= count;
- if (p->yscroll < 0) /* Deal with wrap */
- p->yscroll += p->vrows;
- p->var.xoffset = 0;
- p->var.yoffset = p->yscroll*fontheight(p);
- 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 __inline__ void ypan_up(int unit, struct vc_data *conp,
- struct display *p, int count)
-{
- p->yscroll += count;
- 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*fontheight(p);
- p->var.vmode &= ~FB_VMODE_YWRAP;
- p->fb_info->updatevar(unit, p->fb_info);
- if (p->dispsw->clear_margins)
- p->dispsw->clear_margins(conp, p, 1);
- scrollback_max += count;
- if (scrollback_max > scrollback_phys_max)
- scrollback_max = scrollback_phys_max;
- scrollback_current = 0;
-}
-
-
-static __inline__ void ypan_down(int unit, struct vc_data *conp,
- struct display *p, int count)
-{
- p->yscroll -= count;
- if (p->yscroll < 0) {
- 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*fontheight(p);
- p->var.vmode &= ~FB_VMODE_YWRAP;
- p->fb_info->updatevar(unit, p->fb_info);
- if (p->dispsw->clear_margins)
- p->dispsw->clear_margins(conp, p, 1);
- scrollback_max -= count;
- if (scrollback_max < 0)
- scrollback_max = 0;
- scrollback_current = 0;
-}
-
-static void fbcon_redraw_softback(struct vc_data *conp, struct display *p, long delta)
-{
- unsigned short *d, *s;
- unsigned long n;
- int line = 0;
- int count = conp->vc_rows;
-
- d = (u16 *)softback_curr;
- if (d == (u16 *)softback_in)
- d = (u16 *)conp->vc_origin;
- n = softback_curr + delta * conp->vc_size_row;
- softback_lines -= delta;
- if (delta < 0) {
- if (softback_curr < softback_top && n < softback_buf) {
- n += softback_end - softback_buf;
- if (n < softback_top) {
- softback_lines -= (softback_top - n) / conp->vc_size_row;
- n = softback_top;
- }
- } else if (softback_curr >= softback_top && n < softback_top) {
- softback_lines -= (softback_top - n) / conp->vc_size_row;
- n = softback_top;
- }
- } else {
- if (softback_curr > softback_in && n >= softback_end) {
- n += softback_buf - softback_end;
- if (n > softback_in) {
- n = softback_in;
- softback_lines = 0;
- }
- } else if (softback_curr <= softback_in && n > softback_in) {
- n = softback_in;
- softback_lines = 0;
- }
- }
- if (n == softback_curr)
- return;
- softback_curr = n;
- s = (u16 *)softback_curr;
- if (s == (u16 *)softback_in)
- s = (u16 *)conp->vc_origin;
- while (count--) {
- unsigned short *start;
- unsigned short *le;
- unsigned short c;
- int x = 0;
- unsigned short attr = 1;
-
- start = s;
- le = advance_row(s, 1);
- do {
- c = scr_readw(s);
- if (attr != (c & 0xff00)) {
- attr = c & 0xff00;
- if (s > start) {
- p->dispsw->putcs(conp, p, start, s - start,
- real_y(p, line), x);
- x += s - start;
- start = s;
- }
- }
- if (c == scr_readw(d)) {
- if (s > start) {
- p->dispsw->putcs(conp, p, start, s - start,
- real_y(p, line), x);
- x += s - start + 1;
- start = s + 1;
- } else {
- x++;
- start++;
- }
- }
- s++;
- d++;
- } while (s < le);
- if (s > start)
- p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
- line++;
- if (d == (u16 *)softback_end)
- d = (u16 *)softback_buf;
- if (d == (u16 *)softback_in)
- d = (u16 *)conp->vc_origin;
- if (s == (u16 *)softback_end)
- s = (u16 *)softback_buf;
- if (s == (u16 *)softback_in)
- s = (u16 *)conp->vc_origin;
- }
-}
-
-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 = advance_row(s, 1);
- 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,
- real_y(p, line), x);
- x += s - start;
- start = s;
- }
- }
- if (c == scr_readw(d)) {
- if (s > start) {
- p->dispsw->putcs(conp, p, start, s - start,
- real_y(p, line), x);
- x += s - start + 1;
- start = s + 1;
- } else {
- x++;
- start++;
- }
- }
- scr_writew(c, d);
- console_conditional_schedule();
- s++;
- d++;
- } while (s < le);
- if (s > start)
- p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
- console_conditional_schedule();
- if (offset > 0)
- line++;
- else {
- line--;
- /* NOTE: We subtract two lines from these pointers */
- s -= conp->vc_size_row;
- d -= conp->vc_size_row;
- }
- }
-}
-
-/**
- * fbcon_redraw_clear - clear area of the screen
- * @conp: stucture pointing to current active virtual console
- * @p: display structure
- * @sy: starting Y coordinate
- * @sx: starting X coordinate
- * @height: height of area to clear
- * @width: width of area to clear
- *
- * Clears a specified area of the screen. All dimensions are in
- * pixels.
- *
- */
-
-void fbcon_redraw_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
-{
- int x, y;
- for (y=0; y<height; y++)
- for (x=0; x<width; x++)
- fbcon_putc(conp, ' ', sy+y, sx+x);
-}
-
-
-/**
- * fbcon_redraw_bmove - copy area of screen to another area
- * @p: display structure
- * @sy: origin Y coordinate
- * @sx: origin X coordinate
- * @dy: destination Y coordinate
- * @dx: destination X coordinate
- * @h: height of area to copy
- * @w: width of area to copy
- *
- * Copies an area of the screen to another area of the same screen.
- * All dimensions are in pixels.
- *
- * Note that this function 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 inline void fbcon_softback_note(struct vc_data *conp, int t, int count)
-{
- unsigned short *p;
-
- if (conp->vc_num != fg_console)
- return;
- p = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
-
- while (count) {
- scr_memcpyw((u16 *)softback_in, p, conp->vc_size_row);
- count--;
- p = advance_row(p, 1);
- softback_in += conp->vc_size_row;
- if (softback_in == softback_end)
- softback_in = softback_buf;
- if (softback_in == softback_top) {
- softback_top += conp->vc_size_row;
- if (softback_top == softback_end)
- softback_top = softback_buf;
- }
- }
- softback_curr = softback_in;
-}
-
-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 scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
-
- if (!p->can_soft_blank && console_blanked)
- return 0;
-
- if (!count || vt_cons[unit]->vc_mode != KD_TEXT)
- 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) {
- case SM_UP:
- if (count > conp->vc_rows) /* Maximum realistic size */
- count = conp->vc_rows;
- if (softback_top)
- fbcon_softback_note(conp, t, count);
- if (logo_shown >= 0) goto redraw_up;
- switch (p->scrollmode & __SCROLL_YMASK) {
- case __SCROLL_YMOVE:
- p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
- conp->vc_cols);
- p->dispsw->clear(conp, p, b-count, 0, count,
- conp->vc_cols);
- break;
-
- case __SCROLL_YWRAP:
- if (b-t-count > 3*conp->vc_rows>>2) {
- if (t > 0)
- fbcon_bmove(conp, 0, 0, count, 0, t,
- conp->vc_cols);
- ywrap_up(unit, conp, p, count);
- if (conp->vc_rows-b > 0)
- fbcon_bmove(conp, b-count, 0, b, 0,
- conp->vc_rows-b, conp->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_up;
- else
- fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,
- conp->vc_cols);
- fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
- break;
-
- case __SCROLL_YPAN:
- if (( p->yscroll + count <= 2 * (p->vrows - conp->vc_rows)) &&
- (( !scroll_partial && (b-t == conp->vc_rows)) ||
- ( scroll_partial && (b-t-count > 3*conp->vc_rows>>2)))) {
- if (t > 0)
- fbcon_bmove(conp, 0, 0, count, 0, t,
- conp->vc_cols);
- ypan_up(unit, conp, p, count);
- if (conp->vc_rows-b > 0)
- fbcon_bmove(conp, b-count, 0, b, 0,
- conp->vc_rows-b, conp->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_up;
- else
- fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,
- conp->vc_cols);
- fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
- break;
-
- case __SCROLL_YREDRAW:
- redraw_up:
- fbcon_redraw(conp, p, t, b-t-count, count*conp->vc_cols);
- p->dispsw->clear(conp, p, real_y(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;
- }
- break;
-
- case SM_DOWN:
- if (count > conp->vc_rows) /* Maximum realistic size */
- count = conp->vc_rows;
- switch (p->scrollmode & __SCROLL_YMASK) {
- case __SCROLL_YMOVE:
- p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
- conp->vc_cols);
- p->dispsw->clear(conp, p, t, 0,
- count, conp->vc_cols);
- break;
-
- case __SCROLL_YWRAP:
- if (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);
- ywrap_down(unit, conp, p, count);
- if (t > 0)
- fbcon_bmove(conp, count, 0, 0, 0, t,
- conp->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_down;
- else
- fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,
- conp->vc_cols);
- fbcon_clear(conp, t, 0, count, conp->vc_cols);
- break;
-
- case __SCROLL_YPAN:
- if (( count-p->yscroll <= p->vrows-conp->vc_rows) &&
- (( !scroll_partial && (b-t == conp->vc_rows)) ||
- ( scroll_partial && (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);
- ypan_down(unit, conp, p, count);
- if (t > 0)
- fbcon_bmove(conp, count, 0, 0, 0, t,
- conp->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_down;
- else
- fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,
- conp->vc_cols);
- fbcon_clear(conp, t, 0, count, conp->vc_cols);
- break;
-
- case __SCROLL_YREDRAW:
- redraw_down:
- fbcon_redraw(conp, p, b - 1, b-t-count, -count*conp->vc_cols);
- p->dispsw->clear(conp, p, real_y(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;
- }
- }
- return 0;
-}
-
-
-static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- int unit = conp->vc_num;
- struct display *p = &fb_display[unit];
-
- if (!p->can_soft_blank && console_blanked)
- return;
-
- if (!width || !height)
- 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)))
- fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);
-
- /* Split blits that cross physical y_wrap case.
- * Pathological case involves 4 blits, better to use recursive
- * code rather than unrolled case
- *
- * Recursive invocations don't need to erase the cursor over and
- * over again, so we use fbcon_bmove_rec()
- */
- 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)
-{
- u_int b;
-
- if (sy < y_break && sy+height > y_break) {
- b = y_break-sy;
- if (dy < sy) { /* Avoid trashing self */
- fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
- fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
- } else {
- fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
- fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
- }
- return;
- }
-
- if (dy < y_break && dy+height > y_break) {
- b = y_break-dy;
- if (dy < sy) { /* Avoid trashing self */
- fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
- fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
- } else {
- fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
- fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
- }
- return;
- }
- p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
-}
-
-
-static int fbcon_switch(struct vc_data *conp)
-{
- int unit = conp->vc_num;
- struct display *p = &fb_display[unit];
- struct fb_info *info = p->fb_info;
-
- if (softback_top) {
- int l = fbcon_softback_size / conp->vc_size_row;
- if (softback_lines)
- fbcon_set_origin(conp);
- softback_top = softback_curr = softback_in = softback_buf;
- softback_lines = 0;
-
- if (l > 5)
- softback_end = softback_buf + l * conp->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0 would screw
- the operation totally */
- softback_top = 0;
- }
- }
- 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 = 0;
- switch (p->scrollmode & __SCROLL_YMASK) {
- 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;
-
- if (info && info->switch_con)
- (*info->switch_con)(unit, info);
- if (p->dispsw->clear_margins && vt_cons[unit]->vc_mode == KD_TEXT)
- p->dispsw->clear_margins(conp, p, 0);
- if (logo_shown == -2) {
- logo_shown = fg_console;
- fbcon_show_logo(); /* This is protected above by initmem_freed */
- update_region(fg_console,
- conp->vc_origin + conp->vc_size_row * conp->vc_top,
- conp->vc_size_row * (conp->vc_bottom - conp->vc_top) / 2);
- return 0;
- }
- return 1;
-}
-
-
-static int fbcon_blank(struct vc_data *conp, int blank)
-{
- 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) {
- if (info->fix.visual == FB_VISUAL_MONO01) {
- if (info->screen_base)
- fb_memset255(info->screen_base,
- p->var.xres_virtual*p->var.yres_virtual*
- p->var.bits_per_pixel>>3);
- } else {
- unsigned short oldc;
- u_int height;
- u_int y_break;
-
- oldc = conp->vc_video_erase_char;
- conp->vc_video_erase_char &= p->charmask;
- height = conp->vc_rows;
- y_break = p->vrows-p->yscroll;
- if (height > y_break) {
- p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols);
- p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols);
- } else
- p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols);
- conp->vc_video_erase_char = oldc;
- }
- return 0;
- } else {
- /* Tell console.c that it has to restore the screen itself */
- return 1;
- }
- }
- if (info->fbops->fb_blank)
- (*info->fbops->fb_blank)(blank, info);
- return 0;
-}
-
-static void fbcon_free_font(struct display *p)
-{
- if (p->userfont && p->fontdata &&
- (--REFCOUNT(p->fontdata) == 0))
- kfree(p->fontdata - FONT_EXTRA_WORDS*sizeof(int));
- p->fontdata = NULL;
- p->userfont = 0;
-}
-
-static inline int fbcon_get_font(int unit, struct console_font_op *op)
-{
- struct display *p = &fb_display[unit];
- u8 *data = op->data;
- u8 *fontdata = p->fontdata;
- int i, j;
-
-#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
- if (fontwidth(p) != 8) return -EINVAL;
-#endif
- op->width = fontwidth(p);
- op->height = fontheight(p);
- op->charcount = (p->charmask == 0x1ff) ? 512 : 256;
- if (!op->data) return 0;
-
- if (op->width <= 8) {
- j = fontheight(p);
- for (i = 0; i < op->charcount; i++) {
- memcpy(data, fontdata, j);
- memset(data+j, 0, 32-j);
- data += 32;
- fontdata += j;
- }
- }
-#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
- else if (op->width <= 16) {
- j = fontheight(p) * 2;
- for (i = 0; i < op->charcount; i++) {
- memcpy(data, fontdata, j);
- memset(data+j, 0, 64-j);
- data += 64;
- fontdata += j;
- }
- } else if (op->width <= 24) {
- for (i = 0; i < op->charcount; i++) {
- for (j = 0; j < fontheight(p); j++) {
- *data++ = fontdata[0];
- *data++ = fontdata[1];
- *data++ = fontdata[2];
- fontdata += sizeof(u32);
- }
- memset(data, 0, 3*(32-j));
- data += 3 * (32 - j);
- }
- } else {
- j = fontheight(p) * 4;
- for (i = 0; i < op->charcount; i++) {
- memcpy(data, fontdata, j);
- memset(data+j, 0, 128-j);
- data += 128;
- fontdata += j;
- }
- }
-#endif
- return 0;
-}
-
-static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int userfont)
-{
- struct display *p = &fb_display[unit];
- int resize;
- int w = op->width;
- int h = op->height;
- int cnt;
- char *old_data = NULL;
-
- if (!fontwidthvalid(p,w)) {
- if (userfont && op->op != KD_FONT_OP_COPY)
- kfree(data - FONT_EXTRA_WORDS*sizeof(int));
- return -ENXIO;
- }
-
- if (CON_IS_VISIBLE(p->conp) && softback_lines)
- fbcon_set_origin(p->conp);
-
- resize = (w != fontwidth(p)) || (h != fontheight(p));
- if (p->userfont)
- 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;
- if (p->conp->vc_can_do_color)
- p->conp->vc_complement_mask >>= 1;
- p->fgshift--;
- p->bgshift--;
- p->charmask = 0xff;
-
- /* ++Edmund: reorder the attribute bits */
- if (p->conp->vc_can_do_color) {
- struct vc_data *conp = p->conp;
- unsigned short *cp = (unsigned short *) conp->vc_origin;
- int count = conp->vc_screenbuf_size/2;
- unsigned short c;
- for (; count > 0; count--, cp++) {
- c = scr_readw(cp);
- scr_writew(((c & 0xfe00) >> 1) | (c & 0xff), cp);
- }
- c = conp->vc_video_erase_char;
- conp->vc_video_erase_char = ((c & 0xfe00) >> 1) | (c & 0xff);
- conp->vc_attr >>= 1;
- }
-
- } else if (!p->conp->vc_hi_font_mask && cnt == 512) {
- p->conp->vc_hi_font_mask = 0x100;
- if (p->conp->vc_can_do_color)
- p->conp->vc_complement_mask <<= 1;
- p->fgshift++;
- p->bgshift++;
- p->charmask = 0x1ff;
-
- /* ++Edmund: reorder the attribute bits */
- {
- struct vc_data *conp = p->conp;
- unsigned short *cp = (unsigned short *) conp->vc_origin;
- int count = conp->vc_screenbuf_size/2;
- unsigned short c;
- for (; count > 0; count--, cp++) {
- unsigned short newc;
- c = scr_readw(cp);
- if (conp->vc_can_do_color)
- newc = ((c & 0xff00) << 1) | (c & 0xff);
- else
- newc = c & ~0x100;
- scr_writew(newc, cp);
- }
- c = conp->vc_video_erase_char;
- if (conp->vc_can_do_color) {
- conp->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff);
- conp->vc_attr <<= 1;
- } else
- conp->vc_video_erase_char = c & ~0x100;
- }
-
- }
- fbcon_font_widths(p);
-
- if (resize) {
- struct vc_data *conp = p->conp;
- /* reset wrap/pan */
- p->var.xoffset = p->var.yoffset = p->yscroll = 0;
- p->vrows = p->var.yres_virtual/h;
- if ((p->var.yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
- p->vrows--;
- updatescrollmode(p);
- vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
- if (CON_IS_VISIBLE(conp) && softback_buf) {
- int l = fbcon_softback_size / conp->vc_size_row;
- if (l > 5)
- softback_end = softback_buf + l * conp->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0 would screw
- the operation totally */
- softback_top = 0;
- }
- }
- } else if (CON_IS_VISIBLE(p->conp) && vt_cons[unit]->vc_mode == KD_TEXT) {
- if (p->dispsw->clear_margins)
- p->dispsw->clear_margins(p->conp, p, 0);
- update_screen(unit);
- }
-
- if (old_data && (--REFCOUNT(old_data) == 0))
- kfree(old_data - FONT_EXTRA_WORDS*sizeof(int));
-
- 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 = fontwidth(od);
- op->height = fontheight(od);
- 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, k;
- u8 *new_data, *data = op->data, *p;
-
-#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
- if (w != 8)
- return -EINVAL;
-#endif
- if ((w <= 0) || (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(FONT_EXTRA_WORDS*sizeof(int)+size, GFP_USER)))
- return -ENOMEM;
- new_data += FONT_EXTRA_WORDS*sizeof(int);
- FNTSIZE(new_data) = size;
- FNTCHARCNT(new_data) = op->charcount;
- REFCOUNT(new_data) = 0; /* usage counter */
- p = new_data;
- if (w <= 8) {
- for (i = 0; i < op->charcount; i++) {
- memcpy(p, data, h);
- data += 32;
- p += h;
- }
- }
-#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
- else if (w <= 16) {
- h *= 2;
- for (i = 0; i < op->charcount; i++) {
- memcpy(p, data, h);
- data += 64;
- p += h;
- }
- } else if (w <= 24) {
- for (i = 0; i < op->charcount; i++) {
- int j;
- for (j = 0; j < h; j++) {
- memcpy(p, data, 3);
- p[3] = 0;
- data += 3;
- p += sizeof(u32);
- }
- data += 3*(32 - h);
- }
- } else {
- h *= 4;
- for (i = 0; i < op->charcount; i++) {
- memcpy(p, data, h);
- data += 128;
- p += h;
- }
- }
-#endif
- /* we can do it in u32 chunks because of charcount is 256 or 512, so
- font length must be multiple of 256, at least. And 256 is multiple
- of 4 */
- k = 0;
- while (p > new_data) k += *--(u32 *)p;
- 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 &&
- fontwidth(&fb_display[i]) == w &&
- !memcmp(fb_display[i].fontdata, new_data, size)) {
- kfree(new_data - FONT_EXTRA_WORDS*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];
-static u16 palette_green[16];
-static u16 palette_blue[16];
-
-static struct fb_cmap palette_cmap = {
- 0, 16, palette_red, palette_green, palette_blue, NULL
-};
-
-static int fbcon_set_palette(struct vc_data *conp, unsigned char *table)
-{
- int unit = conp->vc_num;
- struct display *p = &fb_display[unit];
- int i, j, k;
- u8 val;
-
- if (!conp->vc_can_do_color || (!p->can_soft_blank && console_blanked))
- return -EINVAL;
- for (i = j = 0; i < 16; i++) {
- k = table[i];
- val = conp->vc_palette[j++];
- palette_red[k] = (val<<8)|val;
- val = conp->vc_palette[j++];
- palette_green[k] = (val<<8)|val;
- val = conp->vc_palette[j++];
- palette_blue[k] = (val<<8)|val;
- }
- 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 u16 *fbcon_screen_pos(struct vc_data *conp, int offset)
-{
- int line;
- unsigned long p;
-
- if (conp->vc_num != fg_console || !softback_lines)
- return (u16 *)(conp->vc_origin + offset);
- line = offset / conp->vc_size_row;
- if (line >= softback_lines)
- return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row);
- p = softback_curr + offset;
- if (p >= softback_end)
- p += softback_buf - softback_end;
- return (u16 *)p;
-}
-
-static unsigned long fbcon_getxy(struct vc_data *conp, unsigned long pos, int *px, int *py)
-{
- int x, y;
- unsigned long ret;
- if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
- unsigned long offset = (pos - conp->vc_origin) / 2;
-
- x = offset % conp->vc_cols;
- y = offset / conp->vc_cols;
- if (conp->vc_num == fg_console)
- y += softback_lines;
- ret = pos + (conp->vc_cols - x) * 2;
- } else if (conp->vc_num == fg_console && softback_lines) {
- unsigned long offset = pos - softback_curr;
-
- if (pos < softback_curr)
- offset += softback_end - softback_buf;
- offset /= 2;
- x = offset % conp->vc_cols;
- y = offset / conp->vc_cols;
- ret = pos + (conp->vc_cols - x) * 2;
- if (ret == softback_end)
- ret = softback_buf;
- if (ret == softback_in)
- ret = conp->vc_origin;
- } else {
- /* Should not happen */
- x = y = 0;
- ret = conp->vc_origin;
- }
- if (px) *px = x;
- if (py) *py = y;
- return ret;
-}
-
-/* As we might be inside of softback, we may work with non-contiguous buffer,
- that's why we have to use a separate routine. */
-static void fbcon_invert_region(struct vc_data *conp, u16 *p, int cnt)
-{
- while (cnt--) {
- u16 a = scr_readw(p);
- if (!conp->vc_can_do_color)
- a ^= 0x0800;
- else if (conp->vc_hi_font_mask == 0x100)
- a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
- else
- a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
- scr_writew(a, p++);
- if (p == (u16 *)softback_end)
- p = (u16 *)softback_buf;
- if (p == (u16 *)softback_in)
- p = (u16 *)conp->vc_origin;
- }
-}
-
-static int fbcon_scrolldelta(struct vc_data *conp, int lines)
-{
- int unit, offset, limit, scrollback_old;
- struct display *p;
-
- unit = fg_console;
- p = &fb_display[unit];
- if (softback_top) {
- if (conp->vc_num != unit)
- return 0;
- if (vt_cons[unit]->vc_mode != KD_TEXT || !lines)
- return 0;
- 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;
- if (logo_shown == unit) {
- unsigned long p, q;
- int i;
-
- p = softback_in;
- q = conp->vc_origin + logo_lines * conp->vc_size_row;
- for (i = 0; i < logo_lines; i++) {
- if (p == softback_top) break;
- if (p == softback_buf) p = softback_end;
- p -= conp->vc_size_row;
- q -= conp->vc_size_row;
- scr_memcpyw((u16 *)q, (u16 *)p, conp->vc_size_row);
- }
- softback_in = p;
- update_region(unit, conp->vc_origin, logo_lines * conp->vc_cols);
- }
- logo_shown = -1;
- }
- fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);
- fbcon_redraw_softback(conp, p, lines);
- fbcon_cursor(conp, CM_DRAW|CM_SOFTBACK);
- return 0;
- }
-
- 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;
-
- 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 && __SCROLL_YMASK) {
- 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 += limit;
- else if (offset >= limit)
- offset -= limit;
- p->var.xoffset = 0;
- p->var.yoffset = offset*fontheight(p);
- p->fb_info->updatevar(unit, p->fb_info);
- if (!scrollback_current)
- fbcon_cursor(conp, CM_DRAW);
- return 0;
-}
-
-static int fbcon_set_origin(struct vc_data *conp)
-{
- if (softback_lines && !console_blanked)
- fbcon_scrolldelta(conp, softback_lines);
- return 0;
-}
-
-static inline unsigned safe_shift(unsigned d,int n)
-{
- return n<0 ? d>>-n : d<<n;
-}
-
-static int __init fbcon_show_logo( void )
-{
- struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
- struct fb_info *info = p->fb_info;
- int depth = p->var.bits_per_pixel;
- int line = p->next_line;
- unsigned char *fb = info->screen_base;
- unsigned char *logo;
- unsigned char *dst, *src;
- int i, j, n, x1, y1, x;
- int logo_depth, done = 0;
-
- /* 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
- * DIRECTCOLOR
- * We don't have to set the colors for the 16-color logo, since that logo
- * uses the standard VGA text console palette
- */
- if ((info->fix.visual == FB_VISUAL_PSEUDOCOLOR && depth >= 8) ||
- (info->fix.visual == FB_VISUAL_DIRECTCOLOR && depth >= 24))
- for (i = 0; i < LINUX_LOGO_COLORS; i += n) {
- n = LINUX_LOGO_COLORS - i;
- if (n > 16)
- /* palette_cmap provides space for only 16 colors at once */
- n = 16;
- palette_cmap.start = 32 + i;
- palette_cmap.len = n;
- for( j = 0; j < n; ++j ) {
- palette_cmap.red[j] = (linux_logo_red[i+j] << 8) |
- linux_logo_red[i+j];
- palette_cmap.green[j] = (linux_logo_green[i+j] << 8) |
- linux_logo_green[i+j];
- palette_cmap.blue[j] = (linux_logo_blue[i+j] << 8) |
- linux_logo_blue[i+j];
- }
- info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console, info);
- }
-
- if (depth >= 8) {
- logo = linux_logo;
- logo_depth = 8;
- }
- else if (depth >= 4) {
- logo = linux_logo16;
- logo_depth = 4;
- }
- else {
- logo = linux_logo_bw;
- logo_depth = 1;
- }
-
- if (info->fbops->fb_rasterimg)
- info->fbops->fb_rasterimg(info, 1);
-
- for (x = 0; x < num_online_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) || defined(CONFIG_FB_SBUS)
- if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
- 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;
-
- 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);
- if (bdepth == 4 && !((long)dst & 3)) {
- /* Some cards require 32bit access */
- fb_writel (val, dst);
- dst += 4;
- } else if (bdepth == 2 && !((long)dst & 1)) {
- /* others require 16bit access */
- fb_writew (val,dst);
- dst +=2;
- } else {
-#ifdef __LITTLE_ENDIAN
- for( i = 0; i < bdepth; ++i )
-#else
- for( i = bdepth-1; i >= 0; --i )
-#endif
- fb_writeb (val >> (i*8), dst++);
- }
- }
- }
- }
- else if (depth >= 12 && depth <= 23) {
- /* have 4..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; /* upper nibble */
- val = (pix << redshift) |
- (pix << greenshift) |
- (pix << blueshift);
-#ifdef __LITTLE_ENDIAN
- for( i = 0; i < bdepth; ++i )
-#else
- for( i = bdepth-1; i >= 0; --i )
-#endif
- fb_writeb (val >> (i*8), dst++);
- pix = *src & 0x0f; /* lower nibble */
- val = (pix << redshift) |
- (pix << greenshift) |
- (pix << blueshift);
-#ifdef __LITTLE_ENDIAN
- for( i = 0; i < bdepth; ++i )
-#else
- for( i = bdepth-1; i >= 0; --i )
-#endif
- fb_writeb (val >> (i*8), dst++);
- }
- }
- }
- done = 1;
- }
-#endif
-#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
- defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)
- if ((depth % 8 == 0) && (info->fix.visual == FB_VISUAL_TRUECOLOR)) {
- /* 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 + x*bdepth;
- for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
- val = safe_shift((linux_logo_red[*src-32] & redmask), redshift) |
- safe_shift((linux_logo_green[*src-32] & greenmask), greenshift) |
- safe_shift((linux_logo_blue[*src-32] & bluemask), blueshift);
- if (bdepth == 4 && !((long)dst & 3)) {
- /* Some cards require 32bit access */
- fb_writel (val, dst);
- dst += 4;
- } else if (bdepth == 2 && !((long)dst & 1)) {
- /* others require 16bit access */
- fb_writew (val,dst);
- dst +=2;
- } else {
-#ifdef __LITTLE_ENDIAN
- for( i = 0; i < bdepth; ++i )
-#else
- for( i = bdepth-1; i >= 0; --i )
-#endif
- fb_writeb (val >> (i*8), dst++);
- }
- }
- }
- done = 1;
- }
-#endif
-#if defined(CONFIG_FBCON_CFB4)
- if (depth == 4 && info->fix.type == FB_TYPE_PACKED_PIXELS) {
- src = logo;
- for( y1 = 0; y1 < LOGO_H; y1++) {
- dst = fb + y1*line + x/2;
- for( x1 = 0; x1 < LOGO_W/2; x1++) {
- u8 q = *src++;
- q = (q << 4) | (q >> 4);
- fb_writeb (q, dst++);
- }
- }
- done = 1;
- }
-#endif
-#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FB_SBUS)
- if (depth == 8 && info->fix.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 + x;
- for( x1 = 0; x1 < LOGO_W; x1++ )
- fb_writeb (*src++, dst++);
- }
- 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 && (info->fix.type == FB_TYPE_PLANES ||
- info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) {
- /* planes (normal or interleaved), with color registers */
- int bit;
- unsigned char val, mask;
- int plane = p->next_plane;
-
-#if defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
- defined(CONFIG_FBCON_IPLAN2P8)
- int line_length = info->fix.line_length;
-
- /* for support of Atari interleaved planes */
-#define MAP_X(x) (line_length ? (x) : ((x) & ~1)*depth + ((x) & 1))
-#else
-#define MAP_X(x) (x)
-#endif
- /* 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(x/8+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;
- }
- }
- }
-
- /* fill remaining planes */
- if (depth > logo_depth) {
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
- dst = fb + y1*line + MAP_X(x/8+x1) + logo_depth*plane;
- for( i = logo_depth; i < depth; i++, dst += plane )
- *dst = 0x00;
- }
- }
- }
- done = 1;
- break;
- }
-#endif
-#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_AFB) || \
- defined(CONFIG_FBCON_ILBM) || defined(CONFIG_FBCON_HGA)
-
- if (depth == 1 && (info->fix.type == FB_TYPE_PACKED_PIXELS ||
- info->fix.type == FB_TYPE_PLANES ||
- info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) {
-
- /* monochrome */
- unsigned char inverse = p->inverse || info->fix.visual == FB_VISUAL_MONO01
- ? 0x00 : 0xff;
-
- int is_hga = !strncmp(p->fb_info->modename, "HGA", 3);
- /* can't use simply memcpy because need to apply inverse */
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- src = logo + y1*LOGO_LINE;
- if (is_hga)
- dst = fb + (y1%4)*8192 + (y1>>2)*line + x/8;
- else
- dst = fb + y1*line + x/8;
- for( x1 = 0; x1 < LOGO_LINE; ++x1 )
- fb_writeb(*src++ ^ inverse, dst++);
- }
- done = 1;
- }
-#endif
-#if defined(CONFIG_FBCON_VGA_PLANES)
- if (depth == 4 && info->fix.type == FB_TYPE_VGA_PLANES) {
- outb_p(1,0x3ce); outb_p(0xf,0x3cf);
- outb_p(3,0x3ce); outb_p(0,0x3cf);
- outb_p(5,0x3ce); outb_p(0,0x3cf);
-
- src = logo;
- for (y1 = 0; y1 < LOGO_H; y1++) {
- for (x1 = 0; x1 < LOGO_W / 2; x1++) {
- dst = fb + y1*line + x1/4 + x/8;
-
- outb_p(0,0x3ce);
- outb_p(*src >> 4,0x3cf);
- outb_p(8,0x3ce);
- outb_p(1 << (7 - x1 % 4 * 2),0x3cf);
- fb_readb (dst);
- fb_writeb (0, dst);
-
- outb_p(0,0x3ce);
- outb_p(*src & 0xf,0x3cf);
- outb_p(8,0x3ce);
- outb_p(1 << (7 - (1 + x1 % 4 * 2)),0x3cf);
- fb_readb (dst);
- fb_writeb (0, dst);
-
- src++;
- }
- }
- done = 1;
- }
-#endif
- }
-
- if (p->fb_info->fbops->fb_rasterimg)
- p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
-
- /* Modes not yet supported: packed pixels with depth != 8 (does such a
- * thing exist in reality?) */
-
- return done ? (LOGO_H + fontheight(p) - 1) / fontheight(p) : 0 ;
-}
-
-/*
- * The console `switch' structure for the frame buffer based console
- */
-
-const struct consw fb_con = {
- .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 = fbcon_set_origin,
- .con_invert_region = fbcon_invert_region,
- .con_screen_pos = fbcon_screen_pos,
- .con_getxy = fbcon_getxy,
-};
-
-
-/*
- * Dummy Low Level Operations
- */
-
-static void fbcon_dummy_op(void) {}
-
-#define DUMMY (void *)fbcon_dummy_op
-
-struct display_switch fbcon_dummy = {
- .setup = DUMMY,
- .bmove = DUMMY,
- .clear = DUMMY,
- .putc = DUMMY,
- .putcs = DUMMY,
- .revc = DUMMY,
-};
-
-
-/*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fb_display);
-EXPORT_SYMBOL(fbcon_redraw_bmove);
-EXPORT_SYMBOL(fbcon_redraw_clear);
-EXPORT_SYMBOL(fbcon_dummy);
-EXPORT_SYMBOL(fb_con);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbgen.c b/drivers/video/fbgen.c
deleted file mode 100644
index e13783ed31d8..000000000000
--- a/drivers/video/fbgen.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * linux/drivers/video/fbgen.c -- Generic routines for frame buffer devices
- *
- * Created 3 Jan 1998 by Geert Uytterhoeven
- *
- * 2001 - Documented with DocBook
- * - Brad Douglas <brad@neruo.com>
- *
- * 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/string.h>
-#include <linux/tty.h>
-#include <linux/fb.h>
-#include <linux/slab.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb2.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#include "fbcon-accel.h"
-
-int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
- int err;
-
- if (con < 0 || (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo)))) {
- if (!info->fbops->fb_check_var) {
- *var = info->var;
- return 0;
- }
-
- if ((err = info->fbops->fb_check_var(var, info)))
- return err;
-
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
- info->var = *var;
-
- if (con == info->currcon) {
- if (info->fbops->fb_set_par)
- info->fbops->fb_set_par(info);
-
- if (info->fbops->fb_pan_display)
- info->fbops->fb_pan_display(&info->var, con, info);
-
- gen_set_disp(con, info);
- fb_set_cmap(&info->cmap, 1, info);
- }
-
- if (info->changevar)
- info->changevar(con);
- }
- }
- return 0;
-}
-
-int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
- fb_copy_cmap (&info->cmap, cmap, kspc ? 0 : 2);
- return 0;
-}
-
-int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- struct display *disp = (con < 0) ? info->disp : (fb_display + con);
- struct fb_cmap *dcmap = &disp->cmap;
- int err = 0;
-
- /* No colormap allocated ? */
- if (!dcmap->len) {
- int size = info->cmap.len;
-
- err = fb_alloc_cmap(dcmap, size, 0);
- }
-
-
- if (!err && con == info->currcon) {
- err = fb_set_cmap(cmap, kspc, info);
- dcmap = &info->cmap;
- }
-
- if (!err)
- fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
- return err;
-}
-
-int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- int xoffset = var->xoffset;
- int yoffset = var->yoffset;
- int err;
-
- if (xoffset < 0 || yoffset < 0 ||
- xoffset + info->var.xres > info->var.xres_virtual ||
- yoffset + info->var.yres > info->var.yres_virtual)
- return -EINVAL;
- if (con == info->currcon) {
- if (info->fbops->fb_pan_display) {
- if ((err = info->fbops->fb_pan_display(var, con, info)))
- return err;
- } else
- return -EINVAL;
- }
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- info->var.vmode |= FB_VMODE_YWRAP;
- else
- info->var.vmode &= ~FB_VMODE_YWRAP;
- return 0;
-}
-
-
-/* ---- Helper functions --------------------------------------------------- */
-
-void gen_set_disp(int con, struct fb_info *info)
-{
- struct display *display = (con < 0) ? info->disp : (fb_display + con);
-
- if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR ||
- info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
- display->can_soft_blank = info->fbops->fb_blank ? 1 : 0;
- display->dispsw_data = NULL;
- } else {
- display->can_soft_blank = 0;
- display->dispsw_data = info->pseudo_palette;
- }
- display->var = info->var;
-
- /*
- * If we are setting all the virtual consoles, also set
- * the defaults used to create new consoles.
- */
- if (con < 0 || info->var.activate & FB_ACTIVATE_ALL)
- info->disp->var = info->var;
-
- if (info->var.bits_per_pixel == 24) {
-#ifdef FBCON_HAS_CFB24
- display->scrollmode = SCROLL_YREDRAW;
- display->dispsw = &fbcon_cfb24;
- return;
-#endif
- }
-
-#ifdef FBCON_HAS_ACCEL
- display->scrollmode = SCROLL_YNOMOVE;
- display->dispsw = &fbcon_accel;
-#else
- display->dispsw = &fbcon_dummy;
-#endif
- return;
-}
-
-/**
- * do_install_cmap - install the current colormap
- * @con: virtual console number
- * @info: generic frame buffer info structure
- *
- * Installs the current colormap for virtual console @con on
- * device @info.
- *
- */
-
-void do_install_cmap(int con, struct fb_info *info)
-{
- if (con != info->currcon)
- return;
- if (fb_display[con].cmap.len)
- fb_set_cmap(&fb_display[con].cmap, 1, info);
- else {
- int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
- fb_set_cmap(fb_default_cmap(size), 1, info);
- }
-}
-
-int gen_update_var(int con, struct fb_info *info)
-{
- struct display *disp = (con < 0) ? info->disp : (fb_display + con);
- int err;
-
- if (con == info->currcon) {
- info->var.xoffset = disp->var.xoffset;
- info->var.yoffset = disp->var.yoffset;
- info->var.vmode = disp->var.vmode;
- if (info->fbops->fb_pan_display) {
- if ((err = info->fbops->fb_pan_display(&info->var, con, info)))
- return err;
- }
- }
- return 0;
-}
-
-int gen_switch(int con, struct fb_info *info)
-{
- struct display *disp;
- struct fb_cmap *cmap;
-
- if (info->currcon >= 0) {
- disp = fb_display + info->currcon;
-
- /*
- * Save the old colormap and graphics mode.
- */
- disp->var = info->var;
- if (disp->cmap.len)
- fb_copy_cmap(&info->cmap, &disp->cmap, 0);
- }
-
- info->currcon = con;
- disp = fb_display + con;
-
- /*
- * Install the new colormap and change the graphics mode. By default
- * fbcon sets all the colormaps and graphics modes to the default
- * values at bootup.
- *
- * Really, we want to set the colormap size depending on the
- * depth of the new grpahics mode. For now, we leave it as its
- * default 256 entry.
- */
- if (disp->cmap.len)
- cmap = &disp->cmap;
- else
- cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
-
- fb_copy_cmap(cmap, &info->cmap, 0);
-
- disp->var.activate = FB_ACTIVATE_NOW;
- info->fbops->fb_set_var(&disp->var, con, info);
- return 0;
-}
-
-/**
- * fbgen_blank - blank the screen
- * @blank: boolean, 0 unblank, 1 blank
- * @info: frame buffer info structure
- *
- * Blank the screen on device @info.
- *
- */
-
-int fbgen_blank(int blank, struct fb_info *info)
-{
- struct fb_cmap cmap;
- u16 black[16];
-
- if (info->fbops->fb_blank && !info->fbops->fb_blank(blank, info))
- return 0;
- if (blank) {
- memset(black, 0, 16*sizeof(u16));
- cmap.red = black;
- cmap.green = black;
- cmap.blue = black;
- cmap.transp = NULL;
- cmap.start = 0;
- cmap.len = 16;
- fb_set_cmap(&cmap, 1, info);
- } else
- do_install_cmap(info->currcon, info);
- return 0;
-}
-
-/* generic frame buffer operations */
-EXPORT_SYMBOL(gen_set_var);
-EXPORT_SYMBOL(gen_get_cmap);
-EXPORT_SYMBOL(gen_set_cmap);
-EXPORT_SYMBOL(fbgen_pan_display);
-/* helper functions */
-EXPORT_SYMBOL(do_install_cmap);
-EXPORT_SYMBOL(gen_update_var);
-EXPORT_SYMBOL(gen_switch);
-EXPORT_SYMBOL(fbgen_blank);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 9115118e9d77..27dc6417cddd 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -24,7 +24,6 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/tty.h>
-#include <linux/console.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#ifdef CONFIG_KMOD
@@ -42,8 +41,9 @@
#include <asm/pgtable.h>
#include <linux/fb.h>
-#include <video/fbcon.h>
-
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+#include "console/fbcon.h"
+#endif
/*
* Frame buffer device initialization and setup routines
*/
@@ -130,9 +130,9 @@ extern int stifb_init(void);
extern int stifb_setup(char*);
extern int pmagbafb_init(void);
extern int pmagbbfb_init(void);
-extern void maxinefb_init(void);
+extern int maxinefb_init(void);
extern int tx3912fb_init(void);
-extern void tx3912fb_setup(char*);
+extern int tx3912fb_setup(char*);
extern int radeonfb_init(void);
extern int radeonfb_setup(char*);
extern int e1355fb_init(void);
@@ -356,11 +356,6 @@ static int num_pref_init_funcs __initdata = 0;
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
-extern int fbcon_softback_size;
-
-static int first_fb_vc;
-static int last_fb_vc = MAX_NR_CONSOLES-1;
-static int fbcon_is_default = 1;
#ifdef CONFIG_FB_OF
static int ofonly __initdata = 0;
@@ -376,8 +371,8 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset,
for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
if (*fi)
clen += sprintf(buf + clen, "%d %s\n",
- GET_FB_IDX((*fi)->node),
- (*fi)->modename);
+ minor((*fi)->node),
+ (*fi)->fix.id);
*start = buf + offset;
if (clen > offset)
clen -= offset;
@@ -391,12 +386,15 @@ fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
struct inode *inode = file->f_dentry->d_inode;
- int fbidx = GET_FB_IDX(inode->i_rdev);
+ int fbidx = minor(inode->i_rdev);
struct fb_info *info = registered_fb[fbidx];
if (!info || ! info->screen_base)
return -ENODEV;
+ if (info->fbops->fb_read)
+ return info->fbops->fb_read(file, buf, count, ppos);
+
if (p >= info->fix.smem_len)
return 0;
if (count >= info->fix.smem_len)
@@ -420,13 +418,16 @@ fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
struct inode *inode = file->f_dentry->d_inode;
- int fbidx = GET_FB_IDX(inode->i_rdev);
+ int fbidx = minor(inode->i_rdev);
struct fb_info *info = registered_fb[fbidx];
int err;
if (!info || !info->screen_base)
return -ENODEV;
+ if (info->fbops->fb_write)
+ return info->fbops->fb_write(file, buf, count, ppos);
+
if (p > info->fix.smem_len)
return -ENOSPC;
if (count >= info->fix.smem_len)
@@ -459,17 +460,91 @@ static void try_to_load(int fb)
}
#endif /* CONFIG_KMOD */
+int fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ int xoffset = var->xoffset;
+ int yoffset = var->yoffset;
+ int err;
+
+ if (xoffset < 0 || yoffset < 0 ||
+ xoffset + info->var.xres > info->var.xres_virtual ||
+ yoffset + info->var.yres > info->var.yres_virtual)
+ return -EINVAL;
+ if (info->fbops->fb_pan_display) {
+ if ((err = info->fbops->fb_pan_display(var, info)))
+ return err;
+ else
+ return -EINVAL;
+ }
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
+ if (var->vmode & FB_VMODE_YWRAP)
+ info->var.vmode |= FB_VMODE_YWRAP;
+ else
+ info->var.vmode &= ~FB_VMODE_YWRAP;
+ return 0;
+}
+
+int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ int err;
+
+ if (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
+ if (!info->fbops->fb_check_var) {
+ *var = info->var;
+ return 0;
+ }
+
+ if ((err = info->fbops->fb_check_var(var, info)))
+ return err;
+
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+ info->var = *var;
+
+ if (info->fbops->fb_set_par)
+ info->fbops->fb_set_par(info);
+
+ fb_pan_display(&info->var, info);
+
+ fb_set_cmap(&info->cmap, 1, info);
+ }
+ }
+ return 0;
+}
+
+int
+fb_blank(int blank, struct fb_info *info)
+{
+ u16 black[info->cmap.len];
+ struct fb_cmap cmap;
+
+ if (info->fbops->fb_blank && !info->fbops->fb_blank(blank, info))
+ return 0;
+ if (blank) {
+ memset(black, 0, info->cmap.len * sizeof(u16));
+ cmap.red = cmap.green = cmap.blue = black;
+ if (info->cmap.transp)
+ cmap.transp = black;
+ cmap.start = info->cmap.start;
+ cmap.len = info->cmap.len;
+ } else
+ cmap = info->cmap;
+ return fb_set_cmap(&cmap, 1, info);
+}
+
static int
fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
- int fbidx = GET_FB_IDX(inode->i_rdev);
+ int fbidx = minor(inode->i_rdev);
struct fb_info *info = registered_fb[fbidx];
struct fb_ops *fb = info->fbops;
- struct fb_cmap cmap;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
struct fb_con2fbmap con2fb;
+#endif
+ struct fb_cmap cmap;
int i;
if (! fb)
@@ -481,11 +556,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPUT_VSCREENINFO:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT;
- i = var.activate & FB_ACTIVATE_ALL
- ? set_all_vcs(fbidx, fb, &var, info)
- : fb->fb_set_var(&var, PROC_CONSOLE(info), info);
- if (i)
- return i;
+ i = fb_set_var(&var, info);
+ if (i) return i;
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
return 0;
@@ -494,21 +566,20 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPUTCMAP:
if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
return -EFAULT;
- return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE(info), info));
+ return (fb_set_cmap(&cmap, 0, info));
case FBIOGETCMAP:
if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
return -EFAULT;
- return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE(info), info));
+ fb_copy_cmap(&info->cmap, &cmap, 0);
case FBIOPAN_DISPLAY:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT;
- if (fb->fb_pan_display == NULL)
- return (var.xoffset || var.yoffset) ? -EINVAL : 0;
- if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(info), info)))
+ if ((i = fb_pan_display(&var, info)))
return i;
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
return i;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
return -EFAULT;
@@ -537,22 +608,20 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
for (i = 0; i < MAX_NR_CONSOLES; i++)
set_con2fb_map(i, con2fb.framebuffer);
return 0;
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
case FBIOBLANK:
- if (fb->fb_blank == NULL)
- return -EINVAL;
- return fb->fb_blank(arg, info);
+ return fb_blank(arg, info);
default:
if (fb->fb_ioctl == NULL)
return -EINVAL;
- return fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE(info),
- info);
+ return fb->fb_ioctl(inode, file, cmd, arg, info);
}
}
static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
{
- int fbidx = GET_FB_IDX(file->f_dentry->d_inode->i_rdev);
+ int fbidx = minor(file->f_dentry->d_inode->i_rdev);
struct fb_info *info = registered_fb[fbidx];
struct fb_ops *fb = info->fbops;
unsigned long off;
@@ -648,28 +717,10 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
#endif /* !sparc32 */
}
-#if 1 /* to go away in 2.5.0 */
-int GET_FB_IDX(kdev_t rdev)
-{
- int fbidx = minor(rdev);
- if (fbidx >= 32) {
- int newfbidx = fbidx >> 5;
- static int warned;
- if (!(warned & (1<<newfbidx))) {
- warned |= 1<<newfbidx;
- printk("Warning: Remapping obsolete /dev/fb* minor %d to %d\n",
- fbidx, newfbidx);
- }
- fbidx = newfbidx;
- }
- return fbidx;
-}
-#endif
-
static int
fb_open(struct inode *inode, struct file *file)
{
- int fbidx = GET_FB_IDX(inode->i_rdev);
+ int fbidx = minor(inode->i_rdev);
struct fb_info *info;
int res = 0;
@@ -679,12 +730,12 @@ fb_open(struct inode *inode, struct file *file)
#endif /* CONFIG_KMOD */
if (!(info = registered_fb[fbidx]))
return -ENODEV;
- if (info->fbops->owner)
- __MOD_INC_USE_COUNT(info->fbops->owner);
+ if (!try_module_get(info->fbops->owner))
+ return -ENODEV;
if (info->fbops->fb_open) {
res = info->fbops->fb_open(info,1);
- if (res && info->fbops->owner)
- __MOD_DEC_USE_COUNT(info->fbops->owner);
+ if (res)
+ module_put(info->fbops->owner);
}
return res;
}
@@ -692,15 +743,14 @@ fb_open(struct inode *inode, struct file *file)
static int
fb_release(struct inode *inode, struct file *file)
{
- int fbidx = GET_FB_IDX(inode->i_rdev);
+ int fbidx = minor(inode->i_rdev);
struct fb_info *info;
lock_kernel();
info = registered_fb[fbidx];
if (info->fbops->fb_release)
info->fbops->fb_release(info,1);
- if (info->fbops->owner)
- __MOD_DEC_USE_COUNT(info->fbops->owner);
+ module_put(info->fbops->owner);
unlock_kernel();
return 0;
}
@@ -731,10 +781,8 @@ static struct file_operations fb_fops = {
int
register_framebuffer(struct fb_info *fb_info)
{
- int i, j;
char name_buf[12];
- static int fb_ever_opened[FB_MAX];
- static int first = 1;
+ int i;
if (num_registered_fb == FB_MAX)
return -ENXIO;
@@ -744,35 +792,10 @@ register_framebuffer(struct fb_info *fb_info)
break;
fb_info->node = mk_kdev(FB_MAJOR, i);
registered_fb[i] = fb_info;
- if (!fb_ever_opened[i]) {
- struct module *owner = fb_info->fbops->owner;
- /*
- * We assume initial frame buffer devices can be opened this
- * many times
- */
- for (j = 0; j < MAX_NR_CONSOLES; j++)
- if (con2fb_map[j] == i) {
- if (owner)
- __MOD_INC_USE_COUNT(owner);
- if (!fb_info->fbops->fb_open)
- continue;
- if (!fb_info->fbops->fb_open(fb_info,0))
- continue;
- if (owner)
- __MOD_DEC_USE_COUNT(owner);
- }
- fb_ever_opened[i] = 1;
- }
-
- if (first) {
- first = 0;
- take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
- }
- sprintf (name_buf, "fb/%d", i);
+ sprintf(name_buf, "fb/%d", i);
devfs_register(NULL, name_buf, DEVFS_FL_DEFAULT,
- FB_MAJOR, i, S_IFCHR | S_IRUGO | S_IWUGO,
- &fb_fops, NULL);
-
+ FB_MAJOR, i, S_IFCHR | S_IRUGO | S_IWUGO,
+ &fb_fops, NULL);
return 0;
}
@@ -790,12 +813,9 @@ register_framebuffer(struct fb_info *fb_info)
int
unregister_framebuffer(struct fb_info *fb_info)
{
- int i, j;
+ int i;
- i = GET_FB_IDX(fb_info->node);
- for (j = 0; j < MAX_NR_CONSOLES; j++)
- if (con2fb_map[j] == i)
- return -EBUSY;
+ i = minor(fb_info->node);
if (!registered_fb[i])
return -EINVAL;
devfs_remove("fb/%d", i);
@@ -821,7 +841,7 @@ fbmem_init(void)
create_proc_read_entry("fb", 0, 0, fbmem_read_proc, NULL);
- devfs_mk_dir (NULL, "fb", NULL);
+ devfs_mk_dir(NULL, "fb", NULL);
if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
printk("unable to get major %d for fb devs\n", FB_MAJOR);
@@ -862,44 +882,7 @@ int __init video_setup(char *options)
if (!options || !*options)
return 0;
-
- if (!strncmp(options, "scrollback:", 11)) {
- options += 11;
- if (*options) {
- fbcon_softback_size = simple_strtoul(options, &options, 0);
- if (*options == 'k' || *options == 'K') {
- fbcon_softback_size *= 1024;
- options++;
- }
- if (*options != ',')
- return 0;
- options++;
- } else
- return 0;
- }
-
- if (!strncmp(options, "map:", 4)) {
- options += 4;
- if (*options)
- for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) {
- if (!options[j])
- j = 0;
- con2fb_map[i] = (options[j++]-'0') % FB_MAX;
- }
- return 0;
- }
-
- if (!strncmp(options, "vc:", 3)) {
- options += 3;
- if (*options)
- first_fb_vc = simple_strtoul(options, &options, 10) - 1;
- if (first_fb_vc < 0)
- first_fb_vc = 0;
- if (*options++ == '-')
- last_fb_vc = simple_strtoul(options, &options, 10) - 1;
- fbcon_is_default = 0;
- }
-
+
#ifdef CONFIG_FB_OF
if (!strcmp(options, "ofonly")) {
ofonly = 1;
@@ -947,8 +930,5 @@ EXPORT_SYMBOL(register_framebuffer);
EXPORT_SYMBOL(unregister_framebuffer);
EXPORT_SYMBOL(registered_fb);
EXPORT_SYMBOL(num_registered_fb);
-#if 1 /* to go away in 2.5.0 */
-EXPORT_SYMBOL(GET_FB_IDX);
-#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index 05ed2f341c12..4ce6d78cd212 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -21,8 +21,6 @@
#include <linux/zorro.h>
#include <asm/io.h>
-#include <video/fbcon.h>
-
/*
* Some technical notes:
*
@@ -133,7 +131,6 @@ static volatile unsigned char *fm2fb_reg;
static struct fb_info fb_info;
static u32 pseudo_palette[17];
-static struct display display;
static struct fb_fix_screeninfo fb_fix __initdata = {
.smem_len = FRAMEMASTER_REG,
@@ -176,14 +173,12 @@ static int fm2fb_blank(int blank, struct fb_info *info);
static struct fb_ops fm2fb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = fm2fb_setcolreg,
.fb_blank = fm2fb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
/*
@@ -264,7 +259,6 @@ int __init fm2fb_init(void)
if (fm2fb_mode == -1)
fm2fb_mode = FM2FB_MODE_PAL;
- strcpy(fb_info.modename, fb_fix.id);
fb_info.node = NODEV;
fb_info.fbops = &fm2fb_ops;
fb_info.var = fb_var_modes[fm2fb_mode];
@@ -274,19 +268,12 @@ int __init fm2fb_init(void)
fb_info.flags = FBINFO_FLAG_DEFAULT;
/* The below feilds will go away !!!! */
- fb_info.currcon = -1;
- strcpy(fb_info.modename, fb_info.fix.id);
- fb_info.disp = &display;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_alloc_cmap(&fb_info.cmap, 16, 0);
- gen_set_disp(-1, &fb_info);
-
if (register_framebuffer(&fb_info) < 0)
return -EINVAL;
- printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node), fb_fix.id);
+ printk("fb%d: %s frame buffer device\n", minor(fb_info.node), fb_fix.id);
return 0;
}
return -ENXIO;
diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c
index 6ee7d7d0fe1c..2e37b7d58852 100644
--- a/drivers/video/g364fb.c
+++ b/drivers/video/g364fb.c
@@ -31,8 +31,6 @@
#include <asm/io.h>
#include <asm/jazz.h>
-#include <video/fbcon.h>
-
/*
* Various defines for the G364
*/
@@ -74,34 +72,33 @@
#define MON_ID_REG 0xe4100000 /* unused */
#define RESET_REG 0xe4180000 /* Write only */
-static struct display disp;
static struct fb_info fb_info;
static struct fb_fix_screeninfo fb_fix __initdata = {
- .id = "G364 8plane",
- .smem_start = 0x40000000, /* physical address */
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .ypanstep = 1,
- .accel = FB_ACCEL_NONE,
+ .id = "G364 8plane",
+ .smem_start = 0x40000000, /* physical address */
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .ypanstep = 1,
+ .accel = FB_ACCEL_NONE,
};
static struct fb_var_screeninfo fb_var __initdata = {
- .bits_per_pixel =8,
- .red = { 0, 8, 0 },
- green: { 0, 8, 0 },
- blue: { 0, 8, 0 },
- activate:FB_ACTIVATE_NOW,
- height: -1,
- width: -1,
- pixclock:39722,
- left_margin: 40,
- right_margin: 24,
- upper_margin: 32,
- lower_margin: 11,
- hsync_len: 96,
- vsync_len: 2,
- vmode: FB_VMODE_NONINTERLACED,
+ .bits_per_pixel = 8,
+ .red = { 0, 8, 0 },
+ .green = { 0, 8, 0 },
+ .blue = { 0, 8, 0 },
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .pixclock = 39722,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .vmode = FB_VMODE_NONINTERLACED,
};
/*
@@ -109,29 +106,29 @@ static struct fb_var_screeninfo fb_var __initdata = {
*/
int g364fb_init(void);
-static int g364fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int g364fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
static int g364fb_setcolreg(u_int regno, u_int red, u_int green,
u_int blue, u_int transp,
struct fb_info *info);
+static int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
static int g364fb_blank(int blank, struct fb_info *info);
static struct fb_ops g364fb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = g364fb_setcolreg,
.fb_pan_display = g364fb_pan_display,
.fb_blank = g364fb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = g364fb_cursor,
};
-void fbcon_g364fb_cursor(struct display *p, int mode, int x, int y)
+int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
- switch (mode) {
+
+ switch (cursor->enable) {
case CM_ERASE:
*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
break;
@@ -141,9 +138,10 @@ void fbcon_g364fb_cursor(struct display *p, int mode, int x, int y)
*(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
*(unsigned int *) CURS_POS_REG =
((x * fontwidth(p)) << 12) | ((y * fontheight(p)) -
- p->var.yoffset);
+ info->var.yoffset);
break;
}
+ return 0;
}
/*
@@ -151,7 +149,7 @@ void fbcon_g364fb_cursor(struct display *p, int mode, int x, int y)
*
* This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
*/
-static int g364fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int g364fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
if (var->xoffset || var->yoffset + var->yres > var->yres_virtual)
@@ -239,7 +237,6 @@ int __init g364fb_init(void)
fb_fix.smem_len = (1 << (mem * 2)) * 512 * 1024;
fb_var.yres_virtual = fb_fix.smem_len / fb_var.xres;
- strcpy(fb_info.modename, fb_fix.id);
fb_info.node = NODEV;
fb_info.fbops = &g364fb_ops;
fb_info.screen_base = (char *) G364_MEM_BASE; /* virtual kernel address */
@@ -247,21 +244,10 @@ int __init g364fb_init(void)
fb_info.fix = fb_fix;
fb_info.flags = FBINFO_FLAG_DEFAULT;
- fb_info.disp = &disp;
- fb_info.currcon = -1;
- fb_info.fontname[0] = '\0';
- fb_info.changevar = NULL;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
-
fb_alloc_cmap(&fb_info.cmap, 255, 0);
- gen_set_disp(-1, &fb_info);
if (register_framebuffer(&fb_info) < 0)
return -EINVAL;
-
- printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
- fb_info.fix.id);
return 0;
}
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c
index c4e3f35c9124..54f70f95ff07 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/hgafb.c
@@ -7,6 +7,8 @@
*
* History:
*
+ * - Revision 0.1.8 (23 Oct 2002): Ported to new framebuffer api.
+ *
* - Revision 0.1.7 (23 Jan 2001): fix crash resulting from MDA only cards
* being detected as Hercules. (Paul G.)
* - Revision 0.1.6 (17 Aug 2000): new style structs
@@ -18,8 +20,6 @@
* - Revision 0.1.3 (22 Jan 2000): modified for the new fb_info structure
* screen is cleared after rmmod
* virtual resolutions
- * kernel parameter 'video=hga:font:{fontname}'
- * module parameter 'font={fontname}'
* module parameter 'nologo={0|1}'
* the most important: boot logo :)
* - Revision 0.1.0 (6 Dec 1999): faster scrolling and minor fixes
@@ -44,16 +44,10 @@
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/vga.h>
-#include <video/fbcon.h>
-#include <video/fbcon-hga.h>
-
-#ifdef MODULE
#define INCLUDE_LINUX_LOGO_DATA
#include <linux/linux_logo.h>
-#endif /* MODULE */
-
#if 0
#define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
#else
@@ -71,9 +65,15 @@
static unsigned long hga_vram_base; /* Base of video memory */
static unsigned long hga_vram_len; /* Size of video memory */
+#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
#define HGA_TXT 0
#define HGA_GFX 1
+static inline u8* rowaddr(struct fb_info *info, u_int row)
+{
+ return info->screen_base + HGA_ROWADDR(row);
+}
+
static int hga_mode = -1; /* 0 = txt, 1 = gfx mode */
static enum { TYPE_HERC, TYPE_HERCPLUS, TYPE_HERCCOLOR } hga_type;
@@ -111,58 +111,35 @@ static spinlock_t hga_reg_lock = SPIN_LOCK_UNLOCKED;
/* Framebuffer driver structures */
static struct fb_var_screeninfo hga_default_var = {
- .xres = 720,
- .yres = 348,
- .xres_virtual = 720,
- .yres_virtual = 348,
- .xoffset = 0,
- .yoffset = 0,
- .bits_per_pixel =1,
- .grayscale = 0,
- .red = {0, 1, 0},
- .green = {0, 1, 0},
- .blue = {0, 1, 0},
- .transp = {0, 0, 0},
- .nonstd = 0, /* (FB_NONSTD_HGA ?) */
- .activate = 0,
- .height = -1,
- .width = -1,
- .accel_flags = 0,
- /* pixclock */
- /* left_margin, right_margin */
- /* upper_margin, lower_margin */
- /* hsync_len, vsync_len */
- /* sync */
- /* vmode */
+ .xres = 720,
+ .yres = 348,
+ .xres_virtual = 720,
+ .yres_virtual = 348,
+ .bits_per_pixel = 1,
+ .red = {0, 1, 0},
+ .green = {0, 1, 0},
+ .blue = {0, 1, 0},
+ .transp = {0, 0, 0},
+ .height = -1,
+ .width = -1,
};
static struct fb_fix_screeninfo hga_fix = {
- .id = "HGA",
- .smem_start = (unsigned long) NULL,
- .smem_len = 0,
- .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */
- .type_aux = 0, /* (not sure) */
- .visual = FB_VISUAL_MONO10,
- .xpanstep = 8,
- .ypanstep = 8,
- .ywrapstep = 0,
- .line_length = 90,
- .mmio_start = 0,
- .mmio_len = 0,
- .accel = FB_ACCEL_NONE
+ .id = "HGA",
+ .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */
+ .visual = FB_VISUAL_MONO10,
+ .xpanstep = 8,
+ .ypanstep = 8,
+ .line_length = 90,
+ .accel = FB_ACCEL_NONE
};
static struct fb_info fb_info;
-static struct display disp;
/* Don't assume that tty1 will be the initial current console. */
static int release_io_port = 0;
static int release_io_ports = 0;
-
-#ifdef MODULE
-static char *font = NULL;
static int nologo = 0;
-#endif
/* -------------------------------------------------------------------------
*
@@ -205,8 +182,6 @@ static void hga_clear_screen(void)
isa_memset_io(hga_vram_base, fillchar, hga_vram_len);
}
-
-#ifdef MODULE
static void hga_txt_mode(void)
{
unsigned long flags;
@@ -237,7 +212,6 @@ static void hga_txt_mode(void)
hga_mode = HGA_TXT;
spin_unlock_irqrestore(&hga_reg_lock, flags);
}
-#endif /* MODULE */
static void hga_gfx_mode(void)
{
@@ -270,18 +244,16 @@ static void hga_gfx_mode(void)
spin_unlock_irqrestore(&hga_reg_lock, flags);
}
-#ifdef MODULE
-static void hga_show_logo(void)
+static void hga_show_logo(struct fb_info *info)
{
- int x, y;
unsigned long dest = hga_vram_base;
char *logo = linux_logo_bw;
+ int x, y;
+
for (y = 134; y < 134 + 80 ; y++) /* this needs some cleanup */
for (x = 0; x < 10 ; x++)
- isa_writeb(~*(logo++),
- (dest + (y%4)*8192 + (y>>2)*90 + x + 40));
+ isa_writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40));
}
-#endif /* MODULE */
static void hga_pan(unsigned int xoffset, unsigned int yoffset)
{
@@ -380,98 +352,34 @@ static int __init hga_card_detect(void)
return 1;
}
-/* ------------------------------------------------------------------------- *
- *
- * dispsw functions
- *
- * ------------------------------------------------------------------------- */
-
/**
- * hga_set_var - set the user defined part of the display
- * @var:new video mode
- * @con:unused
+ * hgafb_open - open the framebuffer device
* @info:pointer to fb_info object containing info for current hga board
- *
- * This function is called for changing video modes. Since HGA cards have
- * only one fixed mode we have not much to do. After checking input
- * parameters @var is copied to @info->var and @info->changevar is called.
- * A zero is returned on success and %-EINVAL for failure.
- *
- * FIXME:
- * This is the most mystical function (at least for me).
- * What is the exact specification of xxx_set_var()?
- * Should it handle xoffset, yoffset? Should it do panning?
- * What does vmode mean?
+ * @int:open by console system or userland.
*/
-int hga_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static int hgafb_open(struct fb_info *info, int init)
{
- CHKINFO(-EINVAL);
- DPRINTK("hga_set_var: con:%d, activate:%x, info:0x%x, fb_info:%x\n", con, var->activate, (unsigned)info, (unsigned)&fb_info);
-
- if (var->xres != 720 || var->yres != 348 ||
- var->xres_virtual != 720 ||
- var->yres_virtual < 348 || var->yres_virtual > 348 + 16 ||
- var->bits_per_pixel != 1 || var->grayscale != 0) {
- return -EINVAL;
- }
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
- info->var = *var;
- if (info->changevar)
- (*info->changevar)(con);
- }
+ hga_gfx_mode();
+ hga_clear_screen();
+ if (!nologo) hga_show_logo(info);
return 0;
}
/**
- * hga_getcolreg - read color registers
- * @regno:register index to read out
- * @red:red value
- * @green:green value
- * @blue:blue value
- * @transp:transparency value
- * @info:unused
- *
- * This callback function is used to read the color registers of a HGA
- * board. Since we have only two fixed colors, RGB values are 0x0000
- * for register0 and 0xaaaa for register1.
- * A zero is returned on success and 1 for failure.
+ * hgafb_open - open the framebuffer device
+ * @info:pointer to fb_info object containing info for current hga board
+ * @int:open by console system or userland.
*/
-static int hga_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info)
+static int hgafb_release(struct fb_info *info, int init)
{
- if (regno == 0) {
- *red = *green = *blue = 0x0000;
- *transp = 0;
- } else if (regno == 1) {
- *red = *green = *blue = 0xaaaa;
- *transp = 0;
- } else
- return 1;
+ hga_txt_mode();
+ hga_clear_screen();
return 0;
}
/**
- * hga_get_cmap - get the colormap
- * @cmap:struct fb_cmap to fill in
- * @kspc:called from kernel space?
- * @con:unused
- * @info:pointer to fb_info object containing info for current hga board
- *
- * This wrapper function passes it's input parameters to fb_get_cmap().
- * Callback function hga_getcolreg() is used to read the color registers.
- */
-
-int hga_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- CHKINFO(-EINVAL);
- DPRINTK("hga_get_cmap: con:%d\n", con);
- return fb_get_cmap(cmap, kspc, hga_getcolreg, info);
-}
-
-/**
* hgafb_setcolreg - set color registers
* @regno:register index to set
* @red:red value, unused
@@ -496,7 +404,6 @@ static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/**
* hga_pan_display - pan or wrap the display
* @var:contains new xoffset, yoffset and vmode values
- * @con:unused
* @info:pointer to fb_info object containing info for current hga board
*
* This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP
@@ -505,12 +412,8 @@ static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* A zero is returned on success and %-EINVAL for failure.
*/
-int hga_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+int hgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
- CHKINFO(-EINVAL);
- DPRINTK("pan_disp: con:%d, wrap:%d, xoff:%d, yoff:%d\n", con, var->vmode & FB_VMODE_YWRAP, var->xoffset, var->yoffset);
-
if (var->vmode & FB_VMODE_YWRAP) {
if (var->yoffset < 0 ||
var->yoffset >= info->var.yres_virtual ||
@@ -524,13 +427,6 @@ int hga_pan_display(struct fb_var_screeninfo *var, int con,
}
hga_pan(var->xoffset, var->yoffset);
-
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- info->var.vmode |= FB_VMODE_YWRAP;
- else
- info->var.vmode &= ~FB_VMODE_YWRAP;
return 0;
}
@@ -549,93 +445,92 @@ int hga_pan_display(struct fb_var_screeninfo *var, int con,
static int hgafb_blank(int blank_mode, struct fb_info *info)
{
- CHKINFO( );
- DPRINTK("hgafb_blank: blank_mode:%d, info:%x, fb_info:%x\n", blank_mode, (unsigned)info, (unsigned)&fb_info);
-
hga_blank(blank_mode);
return 0;
}
+static void hgafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+ u_int rows, y;
+ u8 *dest;
+
+ y = rect->dy;
+
+ for (rows = rect->height; rows--; y++) {
+ dest = rowaddr(info, y) + (rect->dx >> 3);
+ switch (rect->rop) {
+ case ROP_COPY:
+ //fb_memset(dest, rect->color, (rect->width >> 3));
+ break;
+ case ROP_XOR:
+ *dest = ~*dest;
+ break;
+ }
+ }
+}
+
+static void hgafb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+ u_int rows, y1, y2;
+ u8 *src, *dest;
+
+ if (area->dy <= area->sy) {
+ y1 = area->sy;
+ y2 = area->dy;
+
+ for (rows = area->height; rows--; ) {
+ src = rowaddr(info, y1) + (area->sx >> 3);
+ dest = rowaddr(info, y2) + (area->dx >> 3);
+ //fb_memmove(dest, src, (area->width >> 3));
+ y1++;
+ y2++;
+ }
+ } else {
+ y1 = area->sy + area->height - 1;
+ y2 = area->dy + area->height - 1;
+
+ for (rows = area->height; rows--;) {
+ src = rowaddr(info, y1) + (area->sx >> 3);
+ dest = rowaddr(info, y2) + (area->dx >> 3);
+ //fb_memmove(dest, src, (area->width >> 3));
+ y1--;
+ y2--;
+ }
+ }
+}
+
+static void hgafb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+ u8 *dest, *cdat = image->data;
+ u_int rows, y = image->dy;
+ u8 d;
+
+ for (rows = image->height; rows--; y++) {
+ d = *cdat++;
+ dest = rowaddr(info, y) + (image->dx >> 3);
+ *dest = d;
+ }
+}
+
+
static struct fb_ops hgafb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = hga_set_var,
- .fb_get_cmap = hga_get_cmap,
- .fb_set_cmap = gen_set_cmap,
+ .fb_open = hgafb_open,
+ .fb_release = hgafb_release,
.fb_setcolreg = hgafb_setcolreg,
- .fb_pan_display = hga_pan_display,
+ .fb_pan_display = hgafb_pan_display,
.fb_blank = hgafb_blank,
+ .fb_fillrect = cfb_fillrect, //hgafb_fillrect,
+ .fb_copyarea = cfb_copyarea, //hgafb_copyarea,
+ .fb_imageblit = cfb_imageblit,//hgafb_imageblit,
};
-
/* ------------------------------------------------------------------------- *
*
* Functions in fb_info
*
* ------------------------------------------------------------------------- */
-/**
- * hgafbcon_switch - switch console
- * @con:new console to switch to
- * @info:pointer to fb_info object containing info for current hga board
- *
- * This function should install a new colormap and change the video mode.
- * Since we have fixed colors and only one video mode we have nothing to
- * do.
- * Only console administration is done but it should go to fbcon.c IMHO.
- * A zero is returned on success and %-EINVAL for failure.
- */
-
-static int hgafbcon_switch(int con, struct fb_info *info)
-{
- CHKINFO(-EINVAL);
- DPRINTK("hgafbcon_switch: currcon:%d, con:%d, info:%x, fb_info:%x\n", info->currcon, con, (unsigned)info, (unsigned)&fb_info);
-
- /* Save the colormap and video mode */
-#if 0 /* Not necessary in hgafb, we use fixed colormap */
- fb_copy_cmap(&info->cmap, &fb_display[info->currcon].cmap, 0);
-#endif
-
- if (info->currcon != -1) /* this check is absolute necessary! */
- memcpy(&fb_display[info->currcon].var, &info->var,
- sizeof(struct fb_var_screeninfo));
-
- /* Install a new colormap and change the video mode. By default fbcon
- * sets all the colormaps and video modes to the default values at
- * bootup.
- */
-#if 0
- fb_copy_cmap(&fb_display[con].cmap, &info->cmap, 0);
- fb_set_cmap(&info->cmap, 1, info);
-#endif
-
- memcpy(&info->var, &fb_display[con].var,
- sizeof(struct fb_var_screeninfo));
- /* hga_set_var(&info->var, con, &fb_info); is it necessary? */
- info->currcon = con;
-
- /* Hack to work correctly with XF86_Mono */
- hga_gfx_mode();
- return 0;
-}
-
-/**
- * hgafbcon_updatevar - update the user defined part of the display
- * @con:console to update or -1 when no consoles defined on this fb
- * @info:pointer to fb_info object containing info for current hga board
- *
- * This function is called when @var is changed by fbcon.c without calling
- * hga_set_var(). It usually means scrolling. hga_pan_display() is called
- * to update the hardware and @info->var.
- * A zero is returned on success and %-EINVAL for failure.
- */
-
-static int hgafbcon_updatevar(int con, struct fb_info *info)
-{
- CHKINFO(-EINVAL);
- DPRINTK("hga_update_var: con:%d, info:%x, fb_info:%x\n", con, (unsigned)info, (unsigned)&fb_info);
- return (con < 0) ? -EINVAL : hga_pan_display(&fb_display[con].var, con, info);
-}
-
/* ------------------------------------------------------------------------- */
/*
@@ -652,35 +547,9 @@ int __init hgafb_init(void)
printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n",
hga_type_name, hga_vram_len/1024);
- hga_gfx_mode();
- hga_clear_screen();
-#ifdef MODULE
- if (!nologo) hga_show_logo();
-#endif /* MODULE */
-
hga_fix.smem_start = VGA_MAP_MEM(hga_vram_base);
hga_fix.smem_len = hga_vram_len;
- disp.var = hga_default_var;
- disp.visual = hga_fix.visual;
- disp.type = hga_fix.type;
- disp.type_aux = hga_fix.type_aux;
- disp.ypanstep = hga_fix.ypanstep;
- disp.ywrapstep = hga_fix.ywrapstep;
- disp.line_length = hga_fix.line_length;
- disp.can_soft_blank = 1;
- disp.inverse = 0;
-#ifdef FBCON_HAS_HGA
- disp.dispsw = &fbcon_hga;
-#else
-#warning HGAFB will not work as a console!
- disp.dispsw = &fbcon_dummy;
-#endif
- disp.dispsw_data = NULL;
-
- disp.scrollmode = SCROLL_YREDRAW;
-
- strcpy (fb_info.modename, hga_fix.id);
fb_info.node = NODEV;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.var = hga_default_var;
@@ -692,20 +561,12 @@ int __init hgafb_init(void)
fb_info.monspecs.dpms = 0;
fb_info.fbops = &hgafb_ops;
fb_info.screen_base = (char *)hga_fix.smem_start;
- fb_info.disp = &disp;
- fb_info.currcon = 1;
- fb_info.changevar = NULL;
- fb_info.switch_con = hgafbcon_switch;
- fb_info.updatevar = hgafbcon_updatevar;
- fb_info.pseudo_palette = NULL; /* ??? */
- fb_info.par = NULL;
if (register_framebuffer(&fb_info) < 0)
return -EINVAL;
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(fb_info.node), fb_info.modename);
-
+ minor(fb_info.node), fb_info.fix.id);
return 0;
}
@@ -713,49 +574,21 @@ int __init hgafb_init(void)
* Setup
*/
-#ifndef MODULE
int __init hgafb_setup(char *options)
{
- /*
- * Parse user speficied options
- * `video=hga:font:VGA8x16' or
- * `video=hga:font:SUN8x16' recommended
- * Other supported fonts: VGA8x8, Acorn8x8, PEARL8x8
- * More different fonts can be used with the `setfont' utility.
- */
-
- char *this_opt;
-
- fb_info.fontname[0] = '\0';
-
- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ","))) {
- if (!strncmp(this_opt, "font:", 5))
- strcpy(fb_info.fontname, this_opt+5);
- }
return 0;
}
-#endif /* !MODULE */
-
-
- /*
- * Cleanup
- */
#ifdef MODULE
-static void hgafb_cleanup(struct fb_info *info)
+static void __exit hgafb_exit(void)
{
hga_txt_mode();
hga_clear_screen();
- unregister_framebuffer(info);
+ unregister_framebuffer(&fb_info);
if (release_io_ports) release_region(0x3b0, 12);
if (release_io_port) release_region(0x3bf, 1);
}
-#endif /* MODULE */
-
-
+#endif
/* -------------------------------------------------------------------------
*
@@ -763,29 +596,14 @@ static void hgafb_cleanup(struct fb_info *info)
*
* ------------------------------------------------------------------------- */
-#ifdef MODULE
-int init_module(void)
-{
- if (font)
- strncpy(fb_info.fontname, font, sizeof(fb_info.fontname)-1);
- else
- fb_info.fontname[0] = '\0';
-
- return hgafb_init();
-}
-
-void cleanup_module(void)
-{
- hgafb_cleanup(&fb_info);
-}
-
MODULE_AUTHOR("Ferenc Bakonyi (fero@drama.obuda.kando.hu)");
MODULE_DESCRIPTION("FBDev driver for Hercules Graphics Adaptor");
MODULE_LICENSE("GPL");
-MODULE_PARM(font, "s");
-MODULE_PARM_DESC(font, "Specifies one of the compiled-in fonts (VGA8x8, VGA8x16, SUN8x16, Acorn8x8, PEARL8x8) (default=none)");
MODULE_PARM(nologo, "i");
MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)");
-#endif /* MODULE */
+#ifdef MODULE
+module_init(hgafb_init);
+module_exit(hgafb_exit);
+#endif
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index a18844098a6c..2fd15b181731 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -29,8 +29,6 @@
#include <asm/io.h>
#include <asm/hd64461.h>
-#include <video/fbcon.h>
-
static struct fb_var_screeninfo hitfb_var __initdata = {
.activate = FB_ACTIVATE_NOW,
.height = -1,
@@ -46,7 +44,6 @@ static struct fb_fix_screeninfo hitfb_fix __initdata = {
};
static u16 pseudo_palette[17];
-static struct display display;
struct fb_info fb_info;
static int hitfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -125,15 +122,13 @@ static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green,
static struct fb_ops hitfb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_check_var = hitfb_check_var,
.fb_set_par = hitfb_set_par,
.fb_setcolreg = hitfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
int __init hitfb_init(void)
@@ -167,24 +162,16 @@ int __init hitfb_init(void)
fb_info.pseudo_palette = pseudo_palette;
fb_info.flags = FBINFO_FLAG_DEFAULT;
- strcpy(fb_info.modename, fb_info.fix.id);
- fb_info.currcon = -1;
- fb_info.disp = &display;
- fb_info.changevar = NULL;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_info.screen_base = (void *) hitfb_fix.smem_start;
size = (fb_info.var.bits_per_pixel == 8) ? 256 : 16;
fb_alloc_cmap(&fb_info.cmap, size, 0);
- gen_set_var(&fb_info.var, -1, &fb_info);
-
if (register_framebuffer(&fb_info) < 0)
return -EINVAL;
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(fb_info.node), fb_info.fix.id);
+ minor(fb_info.node), fb_info.fix.id);
return 0;
}
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index e3fed03b4445..595a226a56f3 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -19,8 +19,6 @@
#include <asm/blinken.h>
#include <asm/hwtest.h>
-#include <video/fbcon.h>
-
static struct fb_info fb_info;
unsigned long fb_regs;
@@ -67,8 +65,6 @@ static struct fb_var_screeninfo hpfb_defined = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct display display;
-
/*
* Set the palette. This may not work on all boards but only experimentation
* will tell.
@@ -105,13 +101,11 @@ void hpfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
static struct fb_ops hpfb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = hpfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = hpfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
#define TOPCAT_FBOMSB 0x5d
@@ -163,16 +157,8 @@ int __init hpfb_init_one(unsigned long base)
fb_info.fix = hpfb_fix;
fb_info.screen_base = (char *)hpfb_fix.smem_start; // FIXME
- /* The below feilds will go away !!!! */
- fb_info.currcon = -1;
- strcpy(fb_info.modename, fb_info.fix.id);
- fb_info.disp = &display;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_alloc_cmap(&fb_info.cmap, 256, 0);
- gen_set_disp(-1, &fb_info);
-
if (register_framebuffer(&fb_info) < 0)
return 1;
return 0;
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index a906dcbee668..f72ab497c041 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -39,13 +39,9 @@
#include <linux/delay.h>
#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/kd.h>
-#include <linux/vt_kern.h>
#include <asm/io.h>
@@ -54,16 +50,7 @@
#include <asm/pcic.h>
#endif
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
-#include "iga.h"
-
-static char igafb_name[16] = "IGA 1682";
-static char fontname[40] __initdata = { 0 };
+#include <video/iga.h>
struct pci_mmap_map {
unsigned long voff;
@@ -73,35 +60,18 @@ struct pci_mmap_map {
unsigned long prot_mask;
};
-struct fb_info_iga {
- struct fb_info fb_info;
- unsigned long frame_buffer_phys;
- char *frame_buffer;
- unsigned long io_base_phys;
- unsigned long io_base;
- u32 total_vram;
- struct pci_mmap_map *mmap_map;
- struct { u_short blue, green, red, pad; } palette[256];
- int video_cmap_len;
- struct display disp;
- struct display_switch dispsw;
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
- u32 cfb24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
-#endif
- } fbcon_cmap;
-#ifdef __sparc__
- u8 open;
- u8 mmaped;
- int vtconsole;
- int consolecnt;
-#endif
+struct iga_par {
+ struct pci_mmap_map *mmap_map;
+ unsigned long frame_buffer_phys;
+ unsigned long io_base;
+};
+
+struct fb_info fb_info;
+
+struct fb_fix_screeninfo igafb_fix __initdata = {
+ .id = "IGA 1682",
+ .type = FB_TYPE_PACKED_PIXELS;
+ .mmio_len = 1000;
};
struct fb_var_screeninfo default_var = {
@@ -142,21 +112,21 @@ struct fb_var_screeninfo default_var_1280x1024 __initdata = {
*
* On sparc we happen to access I/O with memory mapped functions too.
*/
-#define pci_inb(info, reg) readb(info->io_base+(reg))
-#define pci_outb(info, val, reg) writeb(val, info->io_base+(reg))
+#define pci_inb(par, reg) readb(par->io_base+(reg))
+#define pci_outb(par, val, reg) writeb(val, par->io_base+(reg))
-static inline unsigned int iga_inb(struct fb_info_iga *info,
- unsigned int reg, unsigned int idx )
+static inline unsigned int iga_inb(struct iga_par *par, unsigned int reg,
+ unsigned int idx)
{
- pci_outb(info, idx, reg);
- return pci_inb(info, reg + 1);
+ pci_outb(par, idx, reg);
+ return pci_inb(par, reg + 1);
}
-static inline void iga_outb(struct fb_info_iga *info, unsigned char val,
+static inline void iga_outb(struct iga_par *par, unsigned char val,
unsigned int reg, unsigned int idx )
{
- pci_outb(info, idx, reg);
- pci_outb(info, val, reg+1);
+ pci_outb(par, idx, reg);
+ pci_outb(par, val, reg+1);
}
#endif /* __sparc__ */
@@ -165,20 +135,19 @@ static inline void iga_outb(struct fb_info_iga *info, unsigned char val,
* Very important functionality for the JavaEngine1 computer:
* make screen border black (usign special IGA registers)
*/
-static void iga_blank_border(struct fb_info_iga *info)
+static void iga_blank_border(struct iga_par *par)
{
int i;
-
#if 0
/*
* PROM does this for us, so keep this code as a reminder
* about required read from 0x3DA and writing of 0x20 in the end.
*/
- (void) pci_inb(info, 0x3DA); /* required for every access */
- pci_outb(info, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
- (void) pci_inb(info, IGA_ATTR_CTL+1);
- pci_outb(info, 0x38, IGA_ATTR_CTL);
- pci_outb(info, 0x20, IGA_ATTR_CTL); /* re-enable visual */
+ (void) pci_inb(par, 0x3DA); /* required for every access */
+ pci_outb(par, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
+ (void) pci_inb(par, IGA_ATTR_CTL+1);
+ pci_outb(par, 0x38, IGA_ATTR_CTL);
+ pci_outb(par, 0x20, IGA_ATTR_CTL); /* re-enable visual */
#endif
/*
* This does not work as it was designed because the overscan
@@ -186,68 +155,19 @@ static void iga_blank_border(struct fb_info_iga *info)
* overscan changes color.
*/
for (i=0; i < 3; i++)
- iga_outb(info, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
-}
-
-
-/*
- * Frame buffer device API
- */
-
-static int igafb_update_var(int con, struct fb_info *info)
-{
- return 0;
-}
-
-static int igafb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct fb_info_iga *fb = (struct fb_info_iga*)info;
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id, igafb_name);
-
- fix->smem_start = (unsigned long) fb->frame_buffer;
- fix->smem_len = fb->total_vram;
- fix->xpanstep = 0;
- fix->ypanstep = 0;
- fix->ywrapstep = 0;
-
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- fix->line_length = default_var.xres * (default_var.bits_per_pixel/8);
- fix->visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_DIRECTCOLOR;
- return 0;
-}
-
-static int igafb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- if(con == -1)
- memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
- else
- *var = fb_display[con].var;
- return 0;
-}
-
-static int igafb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
- return 0;
+ iga_outb(par, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
}
#ifdef __sparc__
static int igafb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma)
{
- struct fb_info_iga *fb = (struct fb_info_iga *)info;
+ struct iga_par *par = (struct iga_par *)info->par;
unsigned int size, page, map_size = 0;
unsigned long map_offset = 0;
int i;
- if (!fb->mmap_map)
+ if (!par->mmap_map)
return -ENXIO;
size = vma->vm_end - vma->vm_start;
@@ -258,9 +178,9 @@ static int igafb_mmap(struct fb_info *info, struct file *file,
/* 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;
+ for (i = 0; par->mmap_map[i].size; i++) {
+ unsigned long start = par->mmap_map[i].voff;
+ unsigned long end = start + par->mmap_map[i].size;
unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT) + page;
if (start > offset)
@@ -268,8 +188,8 @@ static int igafb_mmap(struct fb_info *info, struct file *file,
if (offset >= end)
continue;
- map_size = fb->mmap_map[i].size - (offset - start);
- map_offset = fb->mmap_map[i].poff + (offset - start);
+ map_size = par->mmap_map[i].size - (offset - start);
+ map_offset = par->mmap_map[i].poff + (offset - start);
break;
}
if (!map_size) {
@@ -279,8 +199,8 @@ static int igafb_mmap(struct fb_info *info, struct file *file,
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;
+ pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask);
+ pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
if (remap_page_range(vma, vma->vm_start + page, map_offset,
map_size, vma->vm_page_prot))
@@ -293,46 +213,13 @@ static int igafb_mmap(struct fb_info *info, struct file *file,
return -EINVAL;
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;
- }
- }
return 0;
}
#endif /* __sparc__ */
-
-static int iga_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.
- */
- struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
-
- if (regno >= info->video_cmap_len)
- return 1;
-
- *red = info->palette[regno].red;
- *green = info->palette[regno].green;
- *blue = info->palette[regno].blue;
- *transp = 0;
- return 0;
-}
-
static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
- struct fb_info *fb_info)
+ struct fb_info *info)
{
/*
* Set a single color register. The values supplied are
@@ -340,221 +227,100 @@ static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
* (according to the entries in the `var' structure). Return
* != 0 for invalid regno.
*/
-
- struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
+ struct iga_par *par = (struct iga_par *)info->par;
- if (regno >= info->video_cmap_len)
+ if (regno >= info->cmap.len)
return 1;
- info->palette[regno].red = red;
- info->palette[regno].green = green;
- info->palette[regno].blue = blue;
-
- pci_outb(info, regno, DAC_W_INDEX);
- pci_outb(info, red, DAC_DATA);
- pci_outb(info, green, DAC_DATA);
- pci_outb(info, blue, DAC_DATA);
+ pci_outb(par, regno, DAC_W_INDEX);
+ pci_outb(par, red, DAC_DATA);
+ pci_outb(par, green, DAC_DATA);
+ pci_outb(par, blue, DAC_DATA);
if (regno < 16) {
- switch (default_var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB16
+ switch (info->var.bits_per_pixel) {
case 16:
- info->fbcon_cmap.cfb16[regno] =
+ info->pseudo_palette[regno] =
(regno << 10) | (regno << 5) | regno;
break;
-#endif
-#ifdef FBCON_HAS_CFB24
case 24:
- info->fbcon_cmap.cfb24[regno] =
+ info->pseudo_palette[regno] =
(regno << 16) | (regno << 8) | regno;
break;
-#endif
-#ifdef FBCON_HAS_CFB32
case 32:
{ int i;
i = (regno << 8) | regno;
- info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+ info->pseudo_palette[regno] = (i << 16) | i;
}
break;
-#endif
}
}
return 0;
}
-static int igafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *fb_info)
-{
- struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
-
- if (con == fb_info->currcon) /* current console? */
- return fb_get_cmap(cmap, kspc, iga_getcolreg, &info->fb_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(info->video_cmap_len),
- cmap, kspc ? 0 : 2);
- return 0;
-}
-
/*
* Framebuffer option structure
*/
static struct fb_ops igafb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = igafb_get_fix,
- .fb_get_var = igafb_get_var,
- .fb_set_var = igafb_set_var,
- .fb_get_cmap = igafb_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = igafb_setcolreg,
+ .owner = THIS_MODULE,
+ .fb_setcolreg = igafb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
#ifdef __sparc__
- .fb_mmap = igafb_mmap,
+ .fb_mmap = igafb_mmap,
#endif
};
-static void igafb_set_disp(int con, struct fb_info_iga *info)
-{
- struct fb_fix_screeninfo fix;
- struct display *display;
- struct display_switch *sw;
-
- if (con >= 0)
- display = &fb_display[con];
- else
- display = &info->disp; /* used during initialization */
-
- igafb_get_fix(&fix, con, &info->fb_info);
-
- memset(display, 0, sizeof(struct display));
- 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;
- igafb_get_var(&display->var, -1, &info->fb_info);
-
- switch (default_var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- sw = &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 15:
- case 16:
- sw = &fbcon_cfb16;
- display->dispsw_data = info->fbcon_cmap.cfb16;
- break;
-#endif
-#ifdef FBCON_HAS_CFB24
- case 24:
- sw = &fbcon_cfb24;
- display->dispsw_data = info->fbcon_cmap.cfb24;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- sw = &fbcon_cfb32;
- display->dispsw_data = info->fbcon_cmap.cfb32;
- break;
-#endif
- default:
- printk(KERN_WARNING "igafb_set_disp: unknown resolution %d\n",
- default_var.bits_per_pixel);
- return;
- }
- memcpy(&info->dispsw, sw, sizeof(*sw));
- display->dispsw = &info->dispsw;
-
- display->scrollmode = SCROLL_YREDRAW;
- info->dispsw.bmove = fbcon_redraw_bmove;
-}
-
-static int igafb_switch(int con, struct fb_info *fb_info)
-{
- struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
-
- /* Do we have to save the colormap? */
- if (fb_display[fb_info->currcon].cmap.len)
- fb_get_cmap(&fb_display[fb_info->currcon].cmap, 1,
- iga_getcolreg, fb_info);
-
- fb_info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con, fb_info);
- igafb_update_var(con, fb_info);
- return 1;
-}
-
-static int __init iga_init(struct fb_info_iga *info)
+static int __init iga_init(struct fb_info *info, struct iga_par *par)
{
- char vramsz = iga_inb(info, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL)
+ char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL)
& MEM_SIZE_ALIAS;
+ int video_cmap_len;
+
switch (vramsz) {
case MEM_SIZE_1M:
- info->total_vram = 0x100000;
+ info->fix.smem_len = 0x100000;
break;
case MEM_SIZE_2M:
- info->total_vram = 0x200000;
+ info->fix.smem_len = 0x200000;
break;
case MEM_SIZE_4M:
case MEM_SIZE_RESERVED:
- info->total_vram = 0x400000;
+ info->fix.smem_len = 0x400000;
break;
}
- if (default_var.bits_per_pixel > 8) {
- info->video_cmap_len = 16;
- } else {
- info->video_cmap_len = 256;
- }
- {
- int j, k;
- 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 (info->var.bits_per_pixel > 8)
+ video_cmap_len = 16;
+ else
+ video_cmap_len = 256;
- strcpy(info->fb_info.modename, igafb_name);
- info->fb_info.node = NODEV;
- info->fb_info.fbops = &igafb_ops;
- info->fb_info.disp = &info->disp;
- info->fb_info.screen_base = info->frame_buffer;
- info->fb_info.currcon = -1;
- strcpy(info->fb_info.fontname, fontname);
- info->fb_info.changevar = NULL;
- info->fb_info.switch_con = &igafb_switch;
- info->fb_info.updatevar = &igafb_update_var;
- info->fb_info.flags=FBINFO_FLAG_DEFAULT;
-
- igafb_set_disp(-1, info);
-
- if (register_framebuffer(&info->fb_info) < 0)
+ info->node = NODEV;
+ info->fbops = &igafb_ops;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ fb_alloc_cmap(info->cmap, video_cmap_len, 0);
+
+ if (register_framebuffer(info) < 0)
return 0;
printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n",
- GET_FB_IDX(info->fb_info.node), igafb_name,
- info->frame_buffer_phys, info->total_vram >> 20);
+ minor(info->node), info->fix.id,
+ par->frame_buffer_phys, info->fix.smem_len >> 20);
- iga_blank_border(info);
+ iga_blank_border(par);
return 1;
}
int __init igafb_init(void)
{
- struct pci_dev *pdev;
- struct fb_info_iga *info;
- unsigned long addr;
extern int con_is_present(void);
- int iga2000 = 0;
+ struct fb_info *info;
+ struct pci_dev *pdev;
+ struct iga_par *par;
+ unsigned long addr;
+ int size, iga2000 = 0;
/* Do not attach when we have a serial console. */
if (!con_is_present())
@@ -573,13 +339,18 @@ int __init igafb_init(void)
}
iga2000 = 1;
}
+
+ size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16;
- info = kmalloc(sizeof(struct fb_info_iga), GFP_ATOMIC);
+ info = kmalloc(size, GFP_ATOMIC);
if (!info) {
- printk("igafb_init: can't alloc fb_info_iga\n");
+ printk("igafb_init: can't alloc fb_info\n");
return -ENOMEM;
}
- memset(info, 0, sizeof(struct fb_info_iga));
+ memset(info, 0, size);
+
+ par = (struct iga_par *) (info + 1);
+
if ((addr = pdev->resource[0].start) == 0) {
printk("igafb_init: no memory start\n");
@@ -587,13 +358,13 @@ int __init igafb_init(void)
return -ENXIO;
}
- if ((info->frame_buffer = ioremap(addr, 1024*1024*2)) == 0) {
+ if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) {
printk("igafb_init: can't remap %lx[2M]\n", addr);
kfree(info);
return -ENXIO;
}
- info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
+ par->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
#ifdef __sparc__
/*
@@ -616,14 +387,14 @@ int __init igafb_init(void)
* I/O addresses are.
*/
if (iga2000) {
- info->io_base_phys = info->frame_buffer_phys | 0x00800000;
+ igafb_fix.mmio_start = par->frame_buffer_phys | 0x00800000;
} else {
- info->io_base_phys = 0x30000000; /* XXX */
+ igafb_fix.mmio_start = 0x30000000; /* XXX */
}
- if ((info->io_base = (int) ioremap(info->io_base_phys, 0x1000)) == 0) {
- printk("igafb_init: can't remap %lx[4K]\n", info->io_base_phys);
- iounmap((void *)info->frame_buffer);
- kfree(info);
+ if ((par->io_base = (int) ioremap(igafb_fix.mmio_start, igafb_fix.smem_len)) == 0) {
+ printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start);
+ iounmap((void *)info->screen_base);
+ kfree(info);
return -ENXIO;
}
@@ -635,16 +406,16 @@ int __init igafb_init(void)
* one additional region with size == 0.
*/
- info->mmap_map = kmalloc(4 * sizeof(*info->mmap_map), GFP_ATOMIC);
- if (!info->mmap_map) {
+ par->mmap_map = kmalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC);
+ if (!par->mmap_map) {
printk("igafb_init: can't alloc mmap_map\n");
- iounmap((void *)info->io_base);
- iounmap(info->frame_buffer);
- kfree(info);
+ iounmap((void *)par->io_base);
+ iounmap(info->screen_base);
+ kfree(info);
return -ENOMEM;
}
- memset(info->mmap_map, 0, 4 * sizeof(*info->mmap_map));
+ memset(par->mmap_map, 0, 4 * sizeof(*par->mmap_map));
/*
* Set default vmode and cmode from PROM properties.
@@ -691,12 +462,19 @@ int __init igafb_init(void)
}
#endif
-
- if (!iga_init(info)) {
- iounmap((void *)info->io_base);
- iounmap(info->frame_buffer);
- if (info->mmap_map)
- kfree(info->mmap_map);
+ igafb_fix.smem_start = (unsigned long) info->screen_base;
+ igafb_fix.line_length = default_var.xres*(default_var.bits_per_pixel/8);
+ igafb_fix.visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+
+ info->var = default_var;
+ info->fix = igafb_fix;
+ info->pseudo_palette = (void *)(par + 1);
+
+ if (!iga_init(info, par)) {
+ iounmap((void *)par->io_base);
+ iounmap(info->screen_base);
+ if (par->mmap_map)
+ kfree(par->mmap_map);
kfree(info);
}
@@ -706,18 +484,18 @@ int __init igafb_init(void)
*/
/* First region is for video memory */
- info->mmap_map[0].voff = 0x0;
- info->mmap_map[0].poff = info->frame_buffer_phys & PAGE_MASK;
- info->mmap_map[0].size = info->total_vram & PAGE_MASK;
- info->mmap_map[0].prot_mask = SRMMU_CACHE;
- info->mmap_map[0].prot_flag = SRMMU_WRITE;
+ par->mmap_map[0].voff = 0x0;
+ par->mmap_map[0].poff = par->frame_buffer_phys & PAGE_MASK;
+ par->mmap_map[0].size = info->fix.smem_len & PAGE_MASK;
+ par->mmap_map[0].prot_mask = SRMMU_CACHE;
+ par->mmap_map[0].prot_flag = SRMMU_WRITE;
/* Second region is for I/O ports */
- info->mmap_map[1].voff = info->frame_buffer_phys & PAGE_MASK;
- info->mmap_map[1].poff = info->io_base_phys & PAGE_MASK;
- info->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
- info->mmap_map[1].prot_mask = SRMMU_CACHE;
- info->mmap_map[1].prot_flag = SRMMU_WRITE;
+ par->mmap_map[1].voff = par->frame_buffer_phys & PAGE_MASK;
+ par->mmap_map[1].poff = info->fix.smem_start & PAGE_MASK;
+ par->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
+ par->mmap_map[1].prot_mask = SRMMU_CACHE;
+ par->mmap_map[1].prot_flag = SRMMU_WRITE;
#endif /* __sparc__ */
return 0;
@@ -731,17 +509,6 @@ int __init igafb_setup(char *options)
return 0;
while ((this_opt = strsep(&options, ",")) != 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;
- }
}
return 0;
}
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index ac64a23248a2..40447a960a52 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -772,7 +772,7 @@ set_imstt_regvals (struct fb_info_imstt *p, u_int bpp)
static inline void
set_offset (struct display *disp, struct fb_info_imstt *p)
{
- __u32 off = disp->var.yoffset * (disp->line_length >> 3)
+ __u32 off = disp->var.yoffset * (p->info.fix.line_length >> 3)
+ ((disp->var.xoffset * (disp->var.bits_per_pixel >> 3)) >> 3);
out_le32(&p->dc_regs[SSR], off);
}
@@ -1020,7 +1020,7 @@ imsttfbcon_bmove (struct display *disp, int sy, int sx, int dy, int dx, int heig
width *= Bpp;
width--;
- line_pitch = disp->line_length;
+ line_pitch = p->info.fix.line_length;
bltctl = 0x05;
sp = line_pitch << 16;
cnt = height << 16;
@@ -1068,7 +1068,7 @@ imsttfbcon_clear (struct vc_data *conp, struct display *disp,
bgc |= (bgc << 16);
Bpp = disp->var.bits_per_pixel >> 3,
- line_pitch = disp->line_length;
+ line_pitch = p->info.fix.line_length;
sy *= fontheight(disp);
sy *= line_pitch;
@@ -1099,7 +1099,7 @@ imsttfbcon_revc (struct display *disp, int sx, int sy)
__u32 Bpp, line_pitch, height, width;
Bpp = disp->var.bits_per_pixel >> 3,
- line_pitch = disp->line_length;
+ line_pitch = p->info.fix.line_length;
height = fontheight(disp);
width = fontwidth(disp) * Bpp;
@@ -1246,28 +1246,6 @@ imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
return 0;
}
-static int
-imsttfb_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-{
- struct fb_info_imstt *p = (struct fb_info_imstt *)info;
- struct fb_var_screeninfo *var = &fb_display[con].var;
-
- *fix = p->fix;
- fix->visual = var->bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_DIRECTCOLOR;
- fix->line_length = var->xres * (var->bits_per_pixel >> 3);
-
- return 0;
-}
-
-static int
-imsttfb_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
- *var = fb_display[con].var;
-
- return 0;
-}
-
static void
set_dispsw (struct display *disp, struct fb_info_imstt *p)
{
@@ -1354,16 +1332,7 @@ set_disp (struct display *disp, struct fb_info_imstt *p)
set_dispsw(disp, p);
- disp->visual = disp->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_DIRECTCOLOR;
- disp->visual = p->fix.visual;
- disp->type = p->fix.type;
- disp->type_aux = p->fix.type_aux;
- disp->line_length = disp->var.xres * (disp->var.bits_per_pixel >> 3);
disp->can_soft_blank = 1;
- disp->inverse = inverse;
- disp->ypanstep = 1;
- disp->ywrapstep = 0;
if (accel) {
disp->scrollmode = SCROLL_YNOMOVE;
if (disp->var.yres == disp->var.yres_virtual) {
@@ -1625,8 +1594,6 @@ static struct pci_driver imsttfb_pci_driver = {
static struct fb_ops imsttfb_ops = {
.owner = THIS_MODULE,
- .fb_get_fix = imsttfb_get_fix,
- .fb_get_var = imsttfb_get_var,
.fb_set_var = imsttfb_set_var,
.fb_get_cmap = imsttfb_get_cmap,
.fb_set_cmap = gen_set_cmap,
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 252cf713c4a2..f589222abde0 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -40,8 +40,6 @@
#include <asm/io.h>
#include <asm/machw.h>
-#include <video/fbcon.h>
-
/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
#define DAC_BASE 0x50f24000
@@ -173,7 +171,6 @@ static struct fb_fix_screeninfo macfb_fix = {
.accel = FB_ACCEL_NONE,
};
-static struct display disp;
static struct fb_info fb_info;
static u32 pseudo_palette[17];
static int inverse = 0;
@@ -225,7 +222,7 @@ static int dafb_setpalette (unsigned int regno, unsigned int red,
local_irq_save(flags);
- /* fbcon will set an entire colourmap, but X won't. Hopefully
+ /* fbdev will set an entire colourmap, but X won't. Hopefully
this should accomodate both of them */
if (regno != lastreg+1) {
int i;
@@ -588,21 +585,17 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
static struct fb_ops macfb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = macfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
void __init macfb_setup(char *options, int *ints)
{
char *this_opt;
- fb_info.fontname[0] = '\0';
-
if (!options || !*options)
return;
@@ -611,8 +604,6 @@ void __init macfb_setup(char *options, int *ints)
if (! strcmp(this_opt, "inverse"))
inverse=1;
- else if (!strncmp(this_opt, "font:", 5))
- strcpy(fb_info.fontname, this_opt+5);
/* This means "turn on experimental CLUT code" */
else if (!strcmp(this_opt, "vidtest"))
vidtest=1;
@@ -952,27 +943,20 @@ void __init macfb_init(void)
break;
}
- strcpy(fb_info.modename, macfb_fix.id);
- fb_info.changevar = NULL;
fb_info.node = NODEV;
fb_info.fbops = &macfb_ops;
fb_info.var = macfb_defined;
fb_info.fix = macfb_fix;
- fb_info.currcon = -1;
- fb_info.disp = &disp;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_info.pseudo_palette = pseudo_palette;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
- gen_set_disp(-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_info.fix.id);
+ minor(fb_info.node), fb_info.fix.id);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index ee713a98a79d..3cd1145a6c66 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -20,8 +20,7 @@
#include <linux/fb.h>
#include <linux/string.h>
-#include <video/fbcon.h>
-#include <video/macmodes.h>
+#include "macmodes.h"
/*
* MacOS video mode definitions
diff --git a/include/video/macmodes.h b/drivers/video/macmodes.h
index 232f5a09a499..232f5a09a499 100644
--- a/include/video/macmodes.h
+++ b/drivers/video/macmodes.h
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index 63d70448e783..f984722caa89 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -120,7 +120,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
b->mask.data = data;
b->mask.clock = clock;
b->adapter = matrox_i2c_adapter_template;
- sprintf(b->adapter.name, name, GET_FB_IDX(minfo->fbcon.node));
+ sprintf(b->adapter.name, name, minor(minfo->fbcon.node));
b->adapter.data = b;
b->adapter.algo_data = &b->bac;
b->bac = matrox_i2c_algo_template;
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 477039b3fb8b..3a988123e654 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1872,12 +1872,12 @@ static int initMatrox2(WPMINFO struct display* d, struct board* b){
goto failVideoIO;
}
printk("fb%d: %s frame buffer device\n",
- GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
+ minor(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
if (ACCESS_FBINFO(fbcon.currcon) < 0) {
/* there is no console on this fb... but we have to initialize hardware
* until someone tells me what is proper thing to do */
printk(KERN_INFO "fb%d: initializing hardware\n",
- GET_FB_IDX(ACCESS_FBINFO(fbcon.node)));
+ minor(ACCESS_FBINFO(fbcon.node)));
matroxfb_set_var(&vesafb_defined, -1, &ACCESS_FBINFO(fbcon));
}
return 0;
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 56c7c7a02583..70a63cb5f097 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -816,7 +816,7 @@ static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) {
return -1;
}
printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n",
- GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), GET_FB_IDX(m2info->fbcon.node));
+ minor(ACCESS_FBINFO(fbcon.node)), minor(m2info->fbcon.node));
m2info->fbcon_registered = 1;
return 0;
#undef minfo
@@ -839,7 +839,7 @@ static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) {
printk(KERN_ERR "matroxfb_crtc2: Expect kernel crash after module unload.\n");
return;
}
- id = GET_FB_IDX(m2info->fbcon.node);
+ id = minor(m2info->fbcon.node);
unregister_framebuffer(&m2info->fbcon);
kfree(m2info->fbcon.disp);
/* return memory back to primary head */
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
index 6e1fd2f76347..efe82be7f367 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/maxinefb.c
@@ -34,7 +34,6 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
-#include <video/fbcon.h>
#include "maxinefb.h"
/* bootinfo.h defines the machine type values, needed when checking */
@@ -42,27 +41,29 @@
#include <asm/bootinfo.h>
static struct fb_info fb_info;
-static struct display disp;
static struct fb_var_screeninfo maxinefb_defined = {
- .xres = 1024,
- .yres = 768,
- .xres_virtual = 1024,
- .yres_virtual = 768,
- .bits_per_pixel =8,
- .activate = FB_ACTIVATE_NOW,
- .height = -1,
- .width = -1,
- .vmode = FB_VMODE_NONINTERLACED,
+ .xres = 1024,
+ .yres = 768,
+ .xres_virtual = 1024,
+ .yres_virtual = 768,
+ .bits_per_pixel = 8,
+ .red.length = 8,
+ .green.length = 8,
+ .blue.length = 8,
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .vmode = FB_VMODE_NONINTERLACED,
};
static struct fb_fix_screeninfo maxinefb_fix = {
- .id = "Maxine onboard graphics 1024x768x8",
- .smem_len = (1024*768),
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .line_length = 1024,
-}
+ .id = "Maxine onboard graphics 1024x768x8",
+ .smem_len = (1024*768),
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .line_length = 1024,
+};
/* Reference to machine type set in arch/mips/dec/prom/identify.c, KM */
extern unsigned long mips_machtype;
@@ -112,13 +113,11 @@ static int maxinefb_setcolreg(unsigned regno, unsigned red, unsigned green,
static struct fb_ops maxinefb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = maxinefb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
int __init maxinefb_init(void)
@@ -156,23 +155,14 @@ int __init maxinefb_init(void)
*/
}
- /* Let there be consoles... */
-
- strcpy(fb_info.modename, "Maxine onboard graphics 1024x768x8");
- fb_info.changevar = NULL;
fb_info.node = NODEV;
fb_info.fbops = &maxinefb_ops;
fb_info.screen_base = (char *) maxinefb_fix.smem_start;
fb_info.var = maxinefb_defined;
fb_info.fix = maxinefb_fix;
- fb_info.disp = &disp;
- fb_info.currcon = -1;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&fb_info.cmap, 256, 0);
- gen_set_disp(-1, &fb_info);
if (register_framebuffer(&fb_info) < 0)
return 1;
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 16d0aeb9184d..5dd60c82914f 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -16,8 +16,6 @@
#include <linux/fb.h>
#include <linux/sched.h>
-#include <video/fbcon.h>
-
#undef DEBUG
#define name_matches(v, s, l) \
@@ -277,7 +275,7 @@ static int __init my_atoi(const char *name)
int __fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
const struct fb_videomode *mode, unsigned int bpp)
{
- int err;
+ int err = 1;
DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname",
mode->xres, mode->yres, bpp, mode->refresh);
@@ -298,7 +296,8 @@ int __fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
var->vsync_len = mode->vsync_len;
var->sync = mode->sync;
var->vmode = mode->vmode;
- err = info->fbops->fb_set_var(var, PROC_CONSOLE(info), info);
+ if (info->fbops->fb_check_var)
+ err = info->fbops->fb_check_var(var, info);
var->activate &= ~FB_ACTIVATE_TEST;
return !err;
}
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 08174b35099a..1b50a75f5f1e 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/video/neofb.c -- NeoMagic Framebuffer Driver
*
- * Copyright (c) 2001 Denis Oliver Kropp <dok@convergence.de>
+ * Copyright (c) 2001-2002 Denis Oliver Kropp <dok@directfb.org>
*
*
* Card specific code is based on XFree86's neomagic driver.
@@ -11,6 +11,16 @@
* Public License. See the file COPYING in the main directory of this
* archive for more details.
*
+ *
+ * 0.4.1
+ * - Cosmetic changes (dok)
+ *
+ * 0.4
+ * - Toshiba Libretto support, allow modes larger than LCD size if
+ * LCD is disabled, keep BIOS settings if internal/external display
+ * haven't been enabled explicitly
+ * (Thomas J. Moore <dark@mama.indstate.edu>)
+ *
* 0.3.3
* - Porting over to new fbdev api. (jsimmons)
*
@@ -56,6 +66,10 @@
#include <linux/fb.h>
#include <linux/pci.h>
#include <linux/init.h>
+#ifdef CONFIG_TOSHIBA
+#include <linux/toshiba.h>
+extern int tosh_smm(SMMRegisters *regs);
+#endif
#include <asm/io.h>
#include <asm/irq.h>
@@ -67,20 +81,18 @@
#include <asm/mtrr.h>
#endif
-#include <video/fbcon.h>
#include <video/neomagic.h>
-#define NEOFB_VERSION "0.3.3"
-
-struct neofb_par default_par;
+#define NEOFB_VERSION "0.4.1"
/* --------------------------------------------------------------------- */
-static int disabled = 0;
-static int internal = 0;
-static int external = 0;
-static int nostretch = 0;
-static int nopciburst = 0;
+static int disabled;
+static int internal;
+static int external;
+static int libretto;
+static int nostretch;
+static int nopciburst;
#ifdef MODULE
@@ -94,6 +106,8 @@ MODULE_PARM(internal, "i");
MODULE_PARM_DESC(internal, "Enable output on internal LCD Display.");
MODULE_PARM(external, "i");
MODULE_PARM_DESC(external, "Enable output on external CRT.");
+MODULE_PARM(libretto, "i");
+MODULE_PARM_DESC(libretto, "Force Libretto 100/110 800x480 LCD.");
MODULE_PARM(nostretch, "i");
MODULE_PARM_DESC(nostretch,
"Disable stretching of modes smaller than LCD.");
@@ -450,15 +464,17 @@ static void vgaHWRestore(const struct fb_info *info,
/*
* Hardware Acceleration for Neo2200+
*/
-static inline void neo2200_wait_idle(struct neofb_par *par)
+static inline int neo2200_sync(struct fb_info *info)
{
+ struct neofb_par *par = (struct neofb_par *) info->par;
int waitcycles;
while (par->neo2200->bltStat & 1)
waitcycles++;
+ return 0;
}
-static inline void neo2200_wait_fifo(struct neofb_par *par,
+static inline void neo2200_wait_fifo(struct fb_info *info,
int requested_fifo_space)
{
// ndev->neo.waitfifo_calls++;
@@ -484,17 +500,17 @@ static inline void neo2200_wait_fifo(struct neofb_par *par,
neo_fifo_space -= requested_fifo_space;
*/
- neo2200_wait_idle(par);
+ neo2200_sync(info);
}
-static inline void neo2200_accel_init(struct fb_info *fb,
+static inline void neo2200_accel_init(struct fb_info *info,
struct fb_var_screeninfo *var)
{
- struct neofb_par *par = (struct neofb_par *) fb->par;
+ struct neofb_par *par = (struct neofb_par *) info->par;
Neo2200 *neo2200 = par->neo2200;
u32 bltMod, pitch;
- neo2200_wait_idle(par);
+ neo2200_sync(info);
switch (var->bits_per_pixel) {
case 8:
@@ -551,8 +567,9 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
timings.sync = var->sync;
/* Is the mode larger than the LCD panel? */
- if ((var->xres > par->NeoPanelWidth) ||
- (var->yres > par->NeoPanelHeight)) {
+ if (par->internal_display &&
+ ((var->xres > par->NeoPanelWidth) ||
+ (var->yres > par->NeoPanelHeight))) {
printk(KERN_INFO
"Mode (%dx%d) larger than the LCD panel (%dx%d)\n",
var->xres, var->yres, par->NeoPanelWidth,
@@ -561,23 +578,27 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
/* Is the mode one of the acceptable sizes? */
- switch (var->xres) {
- case 1280:
- if (var->yres == 1024)
- mode_ok = 1;
- break;
- case 1024:
- if (var->yres == 768)
- mode_ok = 1;
- break;
- case 800:
- if (var->yres == 600)
- mode_ok = 1;
- break;
- case 640:
- if (var->yres == 480)
- mode_ok = 1;
- break;
+ if (!par->internal_display)
+ mode_ok = 1;
+ else {
+ switch (var->xres) {
+ case 1280:
+ if (var->yres == 1024)
+ mode_ok = 1;
+ break;
+ case 1024:
+ if (var->yres == 768)
+ mode_ok = 1;
+ break;
+ case 800:
+ if (var->yres == (par->libretto ? 480 : 600))
+ mode_ok = 1;
+ break;
+ case 640:
+ if (var->yres == 480)
+ mode_ok = 1;
+ break;
+ }
}
if (!mode_ok) {
@@ -674,6 +695,10 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if (var->yoffset + var->yres > var->yres_virtual)
var->yoffset = var->yres_virtual - var->yres;
+ var->nonstd = 0;
+ var->height = -1;
+ var->width = -1;
+
if (var->bits_per_pixel >= 24 || !par->neo2200)
var->accel_flags &= ~FB_ACCELF_TEXT;
return 0;
@@ -1165,10 +1190,9 @@ static void neofb_update_start(struct fb_info *info,
/*
* Pan or Wrap the Display
*/
-static int neofb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb)
+static int neofb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
- struct fb_info *info = (struct fb_info *) fb;
u_int y_bottom;
y_bottom = var->yoffset;
@@ -1178,19 +1202,18 @@ static int neofb_pan_display(struct fb_var_screeninfo *var, int con,
if (var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
- if (y_bottom > fb->var.yres_virtual)
+ if (y_bottom > info->var.yres_virtual)
return -EINVAL;
neofb_update_start(info, var);
- fb->var.xoffset = var->xoffset;
- fb->var.yoffset = var->yoffset;
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
if (var->vmode & FB_VMODE_YWRAP)
- fb->var.vmode |= FB_VMODE_YWRAP;
+ info->var.vmode |= FB_VMODE_YWRAP;
else
- fb->var.vmode &= ~FB_VMODE_YWRAP;
-
+ info->var.vmode &= ~FB_VMODE_YWRAP;
return 0;
}
@@ -1239,10 +1262,8 @@ static int neofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/*
* (Un)Blank the display.
*/
-static int neofb_blank(int blank, struct fb_info *fb)
+static int neofb_blank(int blank, struct fb_info *info)
{
- // struct fb_info *info = (struct fb_info *)fb;
-
/*
* Blank the screen if blank_mode != 0, else unblank. If
* blank == NULL then the caller blanks by setting the CLUT
@@ -1261,6 +1282,17 @@ static int neofb_blank(int blank, struct fb_info *fb)
switch (blank) {
case 4: /* powerdown - both sync lines down */
+#ifdef CONFIG_TOSHIBA
+ /* attempt to turn off backlight on toshiba; also turns off external */
+ {
+ SMMRegisters regs;
+
+ regs.eax = 0xff00; /* HCI_SET */
+ regs.ebx = 0x0002; /* HCI_BACKLIGHT */
+ regs.ecx = 0x0000; /* HCI_DISABLE */
+ tosh_smm(&regs);
+ }
+#endif
break;
case 3: /* hsync off */
break;
@@ -1269,13 +1301,24 @@ static int neofb_blank(int blank, struct fb_info *fb)
case 1: /* just software blanking of screen */
break;
default: /* case 0, or anything else: unblank */
+#ifdef CONFIG_TOSHIBA
+ /* attempt to re-enable backlight/external on toshiba */
+ {
+ SMMRegisters regs;
+
+ regs.eax = 0xff00; /* HCI_SET */
+ regs.ebx = 0x0002; /* HCI_BACKLIGHT */
+ regs.ecx = 0x0001; /* HCI_ENABLE */
+ tosh_smm(&regs);
+ }
+#endif
break;
}
return 0;
}
static void
-neo2200fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+neo2200_fillrect(struct fb_info *info, struct fb_fillrect *rect)
{
struct neofb_par *par = (struct neofb_par *) info->par;
u_long dst, rop;
@@ -1283,7 +1326,7 @@ neo2200fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
dst = rect->dx + rect->dy * info->var.xres_virtual;
rop = rect->rop ? 0x060000 : 0x0c0000;
- neo2200_wait_fifo(par, 4);
+ neo2200_wait_fifo(info, 4);
/* set blt control */
par->neo2200->bltCntl = NEO_BC3_FIFO_EN |
@@ -1309,7 +1352,7 @@ neo2200fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
}
static void
-neo2200fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+neo2200_copyarea(struct fb_info *info, struct fb_copyarea *area)
{
struct neofb_par *par = (struct neofb_par *) info->par;
u_long src, dst, bltCntl;
@@ -1337,7 +1380,7 @@ neo2200fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
area->dx * (info->var.bits_per_pixel >> 3) +
area->dy * info->fix.line_length;
- neo2200_wait_fifo(par, 4);
+ neo2200_wait_fifo(info, 4);
/* set blt control */
par->neo2200->bltCntl = bltCntl;
@@ -1349,11 +1392,11 @@ neo2200fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
}
static void
-neo2200fb_imageblit(struct fb_info *info, struct fb_image *image)
+neo2200_imageblit(struct fb_info *info, struct fb_image *image)
{
struct neofb_par *par = (struct neofb_par *) info->par;
- neo2200_wait_idle(par);
+ neo2200_sync(info);
switch (info->var.bits_per_pixel) {
case 8:
@@ -1385,98 +1428,140 @@ neo2200fb_imageblit(struct fb_info *info, struct fb_image *image)
(image->width * image->height) >> 3);
}
+static void
+neofb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+ if (info->var.accel_flags == FB_ACCELF_TEXT)
+ neo2200_fillrect(info, rect);
+ else
+ cfb_fillrect(info, rect);
+}
+
+static void
+neofb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+ if (info->var.accel_flags == FB_ACCELF_TEXT)
+ neo2200_copyarea(info, area);
+ else
+ cfb_copyarea(info, area);
+}
+
+static void
+neofb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+ if (info->var.accel_flags == FB_ACCELF_TEXT)
+ neo2200_imageblit(info, image);
+ else
+ cfb_imageblit(info, image);
+}
+
static struct fb_ops neofb_ops = {
.owner = THIS_MODULE,
.fb_check_var = neofb_check_var,
.fb_set_par = neofb_set_par,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = neofb_setcolreg,
.fb_pan_display = neofb_pan_display,
.fb_blank = neofb_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_sync = neo2200_sync,
+ .fb_fillrect = neofb_fillrect,
+ .fb_copyarea = neofb_copyarea,
+ .fb_imageblit = neofb_imageblit,
+ .fb_cursor = soft_cursor,
};
/* --------------------------------------------------------------------- */
static struct fb_var_screeninfo __devinitdata neofb_var640x480x8 = {
- accel_flags: FB_ACCELF_TEXT,
- xres: 640,
- yres: 480,
- xres_virtual: 640,
- yres_virtual: 30000,
- bits_per_pixel: 8,
- pixclock: 39722,
- left_margin: 48,
- right_margin: 16,
- upper_margin: 33,
- lower_margin: 10,
- hsync_len: 96,
- vsync_len: 2,
- vmode: FB_VMODE_NONINTERLACED
+ .accel_flags = FB_ACCELF_TEXT,
+ .xres = 640,
+ .yres = 480,
+ .xres_virtual = 640,
+ .yres_virtual = 30000,
+ .bits_per_pixel = 8,
+ .pixclock = 39722,
+ .left_margin = 48,
+ .right_margin = 16,
+ .upper_margin = 33,
+ .lower_margin = 10,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .vmode = FB_VMODE_NONINTERLACED
};
static struct fb_var_screeninfo __devinitdata neofb_var800x600x8 = {
- accel_flags: FB_ACCELF_TEXT,
- xres: 800,
- yres: 600,
- xres_virtual: 800,
- yres_virtual: 30000,
- bits_per_pixel: 8,
- pixclock: 25000,
- left_margin: 88,
- right_margin: 40,
- upper_margin: 23,
- lower_margin: 1,
- hsync_len: 128,
- vsync_len: 4,
- sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- vmode: FB_VMODE_NONINTERLACED
+ .accel_flags = FB_ACCELF_TEXT,
+ .xres = 800,
+ .yres = 600,
+ .xres_virtual = 800,
+ .yres_virtual = 30000,
+ .bits_per_pixel = 8,
+ .pixclock = 25000,
+ .left_margin = 88,
+ .right_margin = 40,
+ .upper_margin = 23,
+ .lower_margin = 1,
+ .hsync_len = 128,
+ .vsync_len = 4,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
+};
+
+static struct fb_var_screeninfo __devinitdata neofb_var800x480x8 = {
+ .accel_flags = FB_ACCELF_TEXT,
+ .xres = 800,
+ .yres = 480,
+ .xres_virtual = 800,
+ .yres_virtual = 30000,
+ .bits_per_pixel = 8,
+ .pixclock = 25000,
+ .left_margin = 88,
+ .right_margin = 40,
+ .upper_margin = 23,
+ .lower_margin = 1,
+ .hsync_len = 128,
+ .vsync_len = 4,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
};
static struct fb_var_screeninfo __devinitdata neofb_var1024x768x8 = {
- accel_flags: FB_ACCELF_TEXT,
- xres: 1024,
- yres: 768,
- xres_virtual: 1024,
- yres_virtual: 30000,
- bits_per_pixel: 8,
- pixclock: 15385,
- left_margin: 160,
- right_margin: 24,
- upper_margin: 29,
- lower_margin: 3,
- hsync_len: 136,
- vsync_len: 6,
- sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- vmode: FB_VMODE_NONINTERLACED
+ .accel_flags = FB_ACCELF_TEXT,
+ .xres = 1024,
+ .yres = 768,
+ .xres_virtual = 1024,
+ .yres_virtual = 30000,
+ .bits_per_pixel = 8,
+ .pixclock = 15385,
+ .left_margin = 160,
+ .right_margin = 24,
+ .upper_margin = 29,
+ .lower_margin = 3,
+ .hsync_len = 136,
+ .vsync_len = 6,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
};
#ifdef NOT_DONE
static struct fb_var_screeninfo __devinitdata neofb_var1280x1024x8 = {
- accel_flags: FB_ACCELF_TEXT,
- xres: 1280,
- yres: 1024,
- xres_virtual: 1280,
- yres_virtual: 30000,
- bits_per_pixel: 8,
- pixclock: 9260,
- left_margin: 248,
- right_margin: 48,
- upper_margin: 38,
- lower_margin: 1,
- hsync_len: 112,
- vsync_len: 3,
- sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- vmode: FB_VMODE_NONINTERLACED
+ .accel_flags = FB_ACCELF_TEXT,
+ .xres = 1280,
+ .yres = 1024,
+ .xres_virtual = 1280,
+ .yres_virtual = 30000,
+ .bits_per_pixel = 8,
+ .pixclock = 9260,
+ .left_margin = 248,
+ .right_margin = 48,
+ .upper_margin = 38,
+ .lower_margin = 1,
+ .hsync_len = 112,
+ .vsync_len = 3,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
};
#endif
-static struct fb_var_screeninfo *neofb_var = NULL;
-
static int __devinit neo_map_mmio(struct fb_info *info,
struct pci_dev *dev)
{
@@ -1581,6 +1666,7 @@ static void __devinit neo_unmap_video(struct fb_info *info)
static int __devinit neo_init_hw(struct fb_info *info)
{
struct neofb_par *par = (struct neofb_par *) info->par;
+ unsigned char type, display;
int videoRam = 896;
int maxClock = 65000;
int CursorMem = 1024;
@@ -1588,7 +1674,6 @@ static int __devinit neo_init_hw(struct fb_info *info)
int linearSize = 1024;
int maxWidth = 1024;
int maxHeight = 1024;
- unsigned char type, display;
int w;
DBG("neo_init_hw");
@@ -1609,6 +1694,13 @@ static int __devinit neo_init_hw(struct fb_info *info)
VGAwGR(0x09, 0x26);
type = VGArGR(0x21);
display = VGArGR(0x20);
+ if (!par->internal_display && !par->external_display) {
+ par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
+ par->external_display = display & 1;
+ printk (KERN_INFO "Autodetected %s display\n",
+ par->internal_display && par->external_display ? "simultaneous" :
+ par->internal_display ? "internal" : "external");
+ }
/* Determine panel width -- used in NeoValidMode. */
w = VGArGR(0x20);
@@ -1617,34 +1709,34 @@ static int __devinit neo_init_hw(struct fb_info *info)
case 0x00:
par->NeoPanelWidth = 640;
par->NeoPanelHeight = 480;
- neofb_var = &neofb_var640x480x8;
+ info->var = neofb_var640x480x8;
break;
case 0x01:
par->NeoPanelWidth = 800;
- par->NeoPanelHeight = 600;
- neofb_var = &neofb_var800x600x8;
+ par->NeoPanelHeight = par->libretto ? 480 : 600;
+ info->var = par->libretto ? neofb_var800x480x8 : neofb_var800x600x8;
break;
case 0x02:
par->NeoPanelWidth = 1024;
par->NeoPanelHeight = 768;
- neofb_var = &neofb_var1024x768x8;
+ info->var = neofb_var1024x768x8;
break;
case 0x03:
/* 1280x1024 panel support needs to be added */
#ifdef NOT_DONE
par->NeoPanelWidth = 1280;
par->NeoPanelHeight = 1024;
- neofb_var = &neofb_var1280x1024x8;
+ info->var = neofb_var1280x1024x8;
break;
#else
printk(KERN_ERR
- "neofb: Only 640x480, 800x600 and 1024x768 panels are currently supported\n");
+ "neofb: Only 640x480, 800x600/480 and 1024x768 panels are currently supported\n");
return -1;
#endif
default:
par->NeoPanelWidth = 640;
par->NeoPanelHeight = 480;
- neofb_var = &neofb_var640x480x8;
+ info->var = neofb_var640x480x8;
break;
}
@@ -1750,30 +1842,24 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
struct fb_info *info;
struct neofb_par *par;
- info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
- sizeof(u32) * 16, GFP_KERNEL);
+ info = kmalloc(sizeof(struct fb_info) + sizeof(struct neofb_par) +
+ sizeof(u32) * 17, GFP_KERNEL);
if (!info)
return NULL;
- memset(info, 0, sizeof(struct fb_info) + sizeof(struct display));
+ memset(info, 0, sizeof(struct fb_info) + sizeof(struct neofb_par) + sizeof(u32) * 17);
- par = &default_par;
- memset(par, 0, sizeof(struct neofb_par));
+ par = (struct neofb_par *) (info + 1);
- info->currcon = -1;
info->fix.accel = id->driver_data;
par->pci_burst = !nopciburst;
par->lcd_stretch = !nostretch;
+ par->libretto = libretto;
- if (!internal && !external) {
- par->internal_display = 1;
- par->external_display = 0;
- } else {
- par->internal_display = internal;
- par->external_display = external;
- }
+ par->internal_display = internal;
+ par->external_display = external;
switch (info->fix.accel) {
case FB_ACCEL_NEOMAGIC_NM2070:
@@ -1812,22 +1898,10 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
info->fix.ywrapstep = 0;
info->fix.accel = id->driver_data;
- info->var.nonstd = 0;
- info->var.activate = FB_ACTIVATE_NOW;
- info->var.height = -1;
- info->var.width = -1;
- info->var.accel_flags = 0;
-
- strcpy(info->modename, info->fix.id);
-
info->fbops = &neofb_ops;
- info->changevar = NULL;
- info->switch_con = gen_switch;
- info->updatevar = gen_update_var;
info->flags = FBINFO_FLAG_DEFAULT;
info->par = par;
- info->disp = (struct display *) (info + 1);
- info->pseudo_palette = (void *) (info->disp + 1);
+ info->pseudo_palette = (void *) (par + 1);
fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
@@ -1881,8 +1955,6 @@ static int __devinit neofb_probe(struct pci_dev *dev,
if (err)
goto failed;
- gen_set_var(neofb_var, -1, info);
-
/*
* Calculate the hsync and vsync frequencies. Note that
* we split the 1e12 constant up so that we can preserve
@@ -1908,7 +1980,7 @@ static int __devinit neofb_probe(struct pci_dev *dev,
goto failed;
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(info->node), info->modename);
+ minor(info->node), info->fix.id);
/*
* Our driver data
@@ -2008,7 +2080,6 @@ static void __exit neo_done(void)
pci_unregister_driver(&neofb_driver);
}
-
#ifndef MODULE
/* ************************* init in-kernel code ************************** */
@@ -2036,6 +2107,8 @@ int __init neofb_setup(char *options)
nostretch = 1;
if (!strncmp(this_opt, "nopciburst", 10))
nopciburst = 1;
+ if (!strncmp(this_opt, "libretto", 8))
+ libretto = 1;
}
return 0;
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 4186b17c0d67..f772815444b3 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -24,7 +24,6 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
-#include <linux/selection.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/io.h>
@@ -33,8 +32,7 @@
#include <asm/bootx.h>
#endif
-#include <video/fbcon.h>
-#include <video/macmodes.h>
+#include "macmodes.h"
/* Supported palette hacks */
enum {
@@ -83,14 +81,12 @@ static void offb_init_fb(const char *name, const char *full_name,
static struct fb_ops offb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = offb_setcolreg,
.fb_blank = offb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
/*
@@ -411,7 +407,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
return;
}
- size = sizeof(struct fb_info) + sizeof(struct display) + sizeof(u32) * 17;
+ size = sizeof(struct fb_info) + sizeof(u32) * 17;
info = kmalloc(size, GFP_ATOMIC);
@@ -528,24 +524,15 @@ static void __init offb_init_fb(const char *name, const char *full_name,
strcpy(fix->id, "OFfb ");
strncat(fix->id, full_name, sizeof(fix->id));
- strcpy(info->modename, fix->id);
info->node = NODEV;
info->fbops = &offb_ops;
info->screen_base = ioremap(address, fix->smem_len);
info->par = par;
- info->disp = (struct display *) (info + 1);
- info->pseudo_palette = (void *) (info->disp + 1);
- info->currcon = -1;
- info->fontname[0] = '\0';
- info->changevar = NULL;
- info->switch_con = gen_switch;
- info->updatevar = gen_update_var;
+ info->pseudo_palette = (void *) (info + 1);
info->flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&info->cmap, 256, 0);
- gen_set_disp(-1, info);
-
if (register_framebuffer(info) < 0) {
kfree(info);
release_mem_region(res_start, res_size);
@@ -553,7 +540,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
}
printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
- GET_FB_IDX(info->node), full_name);
+ minor(info->node), full_name);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 3aea0686edee..1cdf67cfb4a2 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -58,14 +58,14 @@ struct fb_par_platinum {
};
struct fb_info_platinum {
- struct fb_info fb_info;
- struct display disp;
- struct fb_par_platinum default_par;
- struct fb_par_platinum current_par;
+ struct fb_info info;
+ struct display display; /* Will disappear */
+ struct fb_par_platinum par;
struct {
__u8 red, green, blue;
} palette[256];
+ u32 pseudo_palette[17];
volatile struct cmap_regs *cmap_regs;
unsigned long cmap_regs_phys;
@@ -80,42 +80,17 @@ struct fb_info_platinum {
unsigned long total_vram;
int clktype;
int dactype;
-
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
-#endif
- } fbcon_cmap;
};
/*
* Frame buffer device API
*/
-static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *fb);
-static int platinum_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb);
-static int platinum_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb);
-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_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *fb);
-static int platinum_blank(int blank, struct fb_info *fb);
-
-
-/*
- * Interface to the low level console driver
- */
-
-static int platinum_switch(int con, struct fb_info *fb);
-static int platinum_updatevar(int con, struct fb_info *fb);
+static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+static int platinumfb_blank(int blank_mode, struct fb_info *info);
+static int platinumfb_set_par (struct fb_info *info);
+static int platinumfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info);
/*
* internal functions
@@ -125,21 +100,14 @@ static void platinum_of_init(struct device_node *dp);
static inline int platinum_vram_reqd(int video_mode, int color_mode);
static int read_platinum_sense(struct fb_info_platinum *info);
static void set_platinum_clock(struct fb_info_platinum *info);
-static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_platinum *info);
+static void platinum_set_hardware(struct fb_info_platinum *info,
+ const struct fb_par_platinum *par);
static int platinum_par_to_var(struct fb_var_screeninfo *var,
const struct fb_par_platinum *par,
const struct fb_info_platinum *info);
static int platinum_var_to_par(const struct fb_var_screeninfo *var,
struct fb_par_platinum *par,
const struct fb_info_platinum *info);
-static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
- const struct fb_par_platinum *par,
- const struct fb_info_platinum *info);
-static void platinum_set_dispsw(struct display *disp,
- struct fb_info_platinum *info, int cmode,
- int accel);
-static int platinum_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *fb);
/*
* Interface used by the world
@@ -150,202 +118,65 @@ int platinum_setup(char*);
static struct fb_ops platinumfb_ops = {
.owner = THIS_MODULE,
- .fb_get_fix = platinum_get_fix,
- .fb_get_var = platinum_get_var,
- .fb_set_var = platinum_set_var,
- .fb_get_cmap = platinum_get_cmap,
- .fb_set_cmap = platinum_set_cmap,
- .fb_setcolreg = platinum_setcolreg,
- .fb_blank = platinum_blank,
+ .fb_set_var = gen_set_var,
+ .fb_check_var = platinumfb_check_var,
+ .fb_set_par = platinumfb_set_par,
+ .fb_get_cmap = gen_get_cmap,
+ .fb_set_cmap = gen_set_cmap,
+ .fb_setcolreg = platinumfb_setcolreg,
+ .fb_blank = platinumfb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
};
-static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *fb)
+/*
+ * Checks a var structure
+ */
+static int platinumfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
{
- const struct fb_info_platinum *info = (struct fb_info_platinum *)fb;
+ struct fb_info_platinum *p = (struct fb_info_platinum *) info;
struct fb_par_platinum par;
-
- if (con == -1)
- par = info->default_par;
- else
- platinum_var_to_par(&fb_display[con].var, &par, info);
-
- platinum_encode_fix(fix, &par, info);
- return 0;
-}
-
-static int platinum_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb)
-{
- const struct fb_info_platinum *info = (struct fb_info_platinum *)fb;
-
- if (con == -1)
- platinum_par_to_var(var, &info->default_par, info);
- else
- *var = fb_display[con].var;
+ int err;
+
+ err = platinum_var_to_par(var, &par, p);
+ if (err)
+ return err;
+ platinum_par_to_var(var, &par, p);
return 0;
}
-static void platinum_set_dispsw(struct display *disp,
- struct fb_info_platinum *info, int cmode,
- int accel)
-{
- switch(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;
- disp->dispsw_data = info->fbcon_cmap.cfb16;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case CMODE_32:
- disp->dispsw = &fbcon_cfb32;
- disp->dispsw_data = info->fbcon_cmap.cfb32;
- break;
-#endif
- default:
- disp->dispsw = &fbcon_dummy;
- break;
- }
-}
-
-static int platinum_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb)
+/*
+ * Applies current var to display
+ */
+static int platinumfb_set_par (struct fb_info *info)
{
- struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
- struct fb_par_platinum par;
- struct display *display;
- int oldxres, oldyres, oldvxres, oldvyres, oldbpp, err;
- int activate = var->activate;
+ struct fb_info_platinum *p = (struct fb_info_platinum *) info;
struct platinum_regvals *init;
+ struct fb_par_platinum par;
+ int err;
- display = (con >= 0) ? &fb_display[con] : fb->disp;
-
- if((err = platinum_var_to_par(var, &par, info))) {
- printk(KERN_ERR "platinum_set_var: error calling platinum_var_to_par: %d.\n", err);
+ if((err = platinum_var_to_par(&info->var, &par, p))) {
+ printk (KERN_ERR "platinumfb_set_par: error calling"
+ " platinum_var_to_par: %d.\n", err);
return err;
}
-
- platinum_par_to_var(var, &par, info);
-
- if ((activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
- printk(KERN_INFO "platinum_set_var: Not activating.\n");
- return 0;
- }
-
- init = platinum_reg_init[par.vmode-1];
-
- oldxres = display->var.xres;
- oldyres = display->var.yres;
- oldvxres = display->var.xres_virtual;
- oldvyres = display->var.yres_virtual;
- oldbpp = display->var.bits_per_pixel;
- display->var = *var;
-
- if (oldxres != var->xres || oldyres != var->yres ||
- oldvxres != var->xres_virtual || oldyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel) {
- struct fb_fix_screeninfo fix;
-
- platinum_encode_fix(&fix, &par, info);
- info->fb_info.screen_base = (char *) info->frame_buffer + init->fb_offset + 0x20;
- 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 = 1;
- display->inverse = 0;
- platinum_set_dispsw(display, info, par.cmode, 0);
- display->scrollmode = SCROLL_YREDRAW;
- if (info->fb_info.changevar)
- (*info->fb_info.changevar)(con);
- }
-
- if (!info->fb_info.display_fg ||
- info->fb_info.display_fg->vc_num == con)
- platinum_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->fb_info);
- }
-
- return 0;
-}
-
-static int platinum_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- if (!info->display_fg ||
- info->display_fg->vc_num == con) /* current console? */
- return fb_get_cmap(cmap, 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)
-{
- int err;
- struct display *disp;
-
- if (con >= 0)
- disp = &fb_display[con];
- else
- disp = info->disp;
- if (!disp->cmap.len) { /* no colormap allocated? */
- int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
- if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
- return err;
- }
-
- if (!info->display_fg ||
- info->display_fg->vc_num == con) /* current console? */
- return fb_set_cmap(cmap, kspc, info);
- else
- fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
- return 0;
-}
-static int platinum_switch(int con, struct fb_info *fb)
-{
- struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
- struct fb_par_platinum par;
-
- if (fb_display[fb->currcon].cmap.len)
- fb_get_cmap(&fb_display[fb->currcon].cmap, 1, platinum_getcolreg,
- fb);
- fb->currcon = con;
+ platinum_set_hardware(p, &par);
- platinum_var_to_par(&fb_display[con].var, &par, info);
- platinum_set_par(&par, info);
- platinum_set_dispsw(&fb_display[con], info, par.cmode, 0);
- do_install_cmap(con, fb);
-
- return 1;
-}
+ init = platinum_reg_init[p->par.vmode-1];
+
+ info->screen_base = (char *) p->frame_buffer + init->fb_offset + 0x20;
+ info->fix.smem_start = (p->frame_buffer_phys) + init->fb_offset + 0x20;
+ info->fix.visual = (p->par.cmode == CMODE_8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+ info->fix.line_length = vmode_attrs[p->par.vmode-1].hres * (1<<p->par.cmode) + 0x20;
-static int platinum_updatevar(int con, struct fb_info *fb)
-{
- printk(KERN_ERR "platinum_updatevar is doing nothing yet.\n");
return 0;
}
-static int platinum_blank(int blank, struct fb_info *fb)
+static int platinumfb_blank(int blank, struct fb_info *fb)
{
/*
* Blank the screen if blank_mode != 0, else unblank. If blank == NULL
@@ -375,26 +206,11 @@ static int platinum_blank(int blank, struct fb_info *fb)
return 0;
}
-static int platinum_getcolreg(u_int regno, u_int *red, u_int *green,
- u_int *blue, u_int *transp, struct fb_info *fb)
-{
- struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
-
- if (regno > 255)
- return 1;
-
- *red = (info->palette[regno].red<<8) | info->palette[regno].red;
- *green = (info->palette[regno].green<<8) | info->palette[regno].green;
- *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
- *transp = 0;
- return 0;
-}
-
-static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *fb)
+static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
{
- struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
- volatile struct cmap_regs *cmap_regs = info->cmap_regs;
+ struct fb_info_platinum *p = (struct fb_info_platinum *) info;
+ volatile struct cmap_regs *cmap_regs = p->cmap_regs;
if (regno > 255)
return 1;
@@ -403,23 +219,30 @@ static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
green >>= 8;
blue >>= 8;
- info->palette[regno].red = red;
- info->palette[regno].green = green;
- info->palette[regno].blue = blue;
+ p->palette[regno].red = red;
+ p->palette[regno].green = green;
+ p->palette[regno].blue = blue;
out_8(&cmap_regs->addr, regno); /* tell clut what addr to fill */
out_8(&cmap_regs->lut, red); /* send one color channel at */
out_8(&cmap_regs->lut, green); /* a time... */
out_8(&cmap_regs->lut, blue);
- if(regno < 16) {
-#ifdef FBCON_HAS_CFB16
- info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | (regno << 0);
-#endif
-#ifdef FBCON_HAS_CFB32
- info->fbcon_cmap.cfb32[regno] = (regno << 24) | (regno << 16) | (regno << 8) | regno;
-#endif
+ if (regno < 16) {
+ int i;
+ switch (p->par.cmode) {
+ case CMODE_16:
+ ((u16 *) (info->pseudo_palette))[regno] =
+ (regno << 10) | (regno << 5) | regno;
+ break;
+ case CMODE_32:
+ i = (regno << 8) | regno;
+ ((u32 *) (info->pseudo_palette))[regno] =
+ (i << 16) | i;
+ break;
+ }
}
+
return 0;
}
@@ -439,7 +262,7 @@ static void set_platinum_clock(struct fb_info_platinum *info)
volatile struct cmap_regs *cmap_regs = info->cmap_regs;
struct platinum_regvals *init;
- init = platinum_reg_init[info->current_par.vmode-1];
+ init = platinum_reg_init[info->par.vmode-1];
STORE_D2(6, 0xc6);
out_8(&cmap_regs->addr,3+32);
@@ -461,7 +284,7 @@ static void set_platinum_clock(struct fb_info_platinum *info)
/* 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_par(const struct fb_par_platinum *par, struct fb_info_platinum *info)
+static void platinum_set_hardware(struct fb_info_platinum *info, const struct fb_par_platinum *par)
{
volatile struct platinum_regs *platinum_regs = info->platinum_regs;
volatile struct cmap_regs *cmap_regs = info->cmap_regs;
@@ -469,7 +292,7 @@ static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_p
int i;
int vmode, cmode;
- info->current_par = *par;
+ info->par = *par;
vmode = par->vmode;
cmode = par->cmode;
@@ -509,15 +332,52 @@ static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_p
out_be32(&platinum_regs->reg[24].r, 0); /* turn display on */
}
+/*
+ * Set misc info vars for this driver
+ */
+static void __init platinum_init_info(struct fb_info *info, struct fb_info_platinum *p)
+{
+ /* Fill fb_info */
+ strcpy(info->modename, "platinum");
+ info->currcon = -1;
+ info->par = &p->par;
+ info->node = NODEV;
+ info->fbops = &platinumfb_ops;
+ info->disp = &p->display;
+ info->pseudo_palette = p->pseudo_palette;
+ info->flags = FBINFO_FLAG_DEFAULT;
+ strncpy (info->fontname, fontname, sizeof (info->fontname));
+ info->fontname[sizeof (info->fontname) - 1] = 0;
+ info->changevar = NULL;
+ info->display_fg = NULL;
+ info->screen_base = (char *) p->frame_buffer + 0x20;
+ info->changevar = NULL;
+ info->switch_con = gen_switch;
+ info->updatevar = gen_update_var;
+
+ fb_alloc_cmap(&info->cmap, 256, 0);
+
+ /* Fill fix common fields */
+ strcpy(info->fix.id, "platinum");
+ info->fix.mmio_start = p->platinum_regs_phys;
+ info->fix.mmio_len = 0x1000;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.smem_start = p->frame_buffer_phys + 0x20; /* will be updated later */
+ info->fix.smem_len = p->total_vram - 0x20;
+ info->fix.ywrapstep = 0;
+ info->fix.xpanstep = 0;
+ info->fix.ypanstep = 0;
+ info->fix.type_aux = 0;
+ info->fix.accel = FB_ACCEL_NONE;
+}
+
-static int __init init_platinum(struct fb_info_platinum *info)
+static int __init init_platinum(struct fb_info_platinum *p)
{
struct fb_var_screeninfo var;
- struct display *disp;
- int sense;
- int j,k;
+ int sense, rc;
- sense = read_platinum_sense(info);
+ sense = read_platinum_sense(p);
printk(KERN_INFO "Monitor sense value = 0x%x, ", sense);
if (default_vmode == VMODE_NVRAM) {
@@ -538,44 +398,40 @@ static int __init init_platinum(struct fb_info_platinum *info)
/*
* Reduce the pixel size if we don't have enough VRAM.
*/
- while(default_cmode > CMODE_8 && platinum_vram_reqd(default_vmode, default_cmode) > info->total_vram)
+ while(default_cmode > CMODE_8 && platinum_vram_reqd(default_vmode, default_cmode) > p->total_vram)
default_cmode--;
printk("using video mode %d and color mode %d.\n", default_vmode, default_cmode);
- mac_vmode_to_var(default_vmode, default_cmode, &var);
-
- if (platinum_var_to_par(&var, &info->default_par, info)) {
- printk(KERN_ERR "platinumfb: can't set default video mode\n");
- return 0;
+ /* Setup default var */
+ if (mac_vmode_to_var(default_vmode, default_cmode, &var) < 0) {
+ /* This shouldn't happen! */
+ printk("mac_vmode_to_var(%d, %d,) failed\n", default_vmode, default_cmode);
+try_again:
+ default_vmode = VMODE_640_480_60;
+ default_cmode = CMODE_8;
+ if (mac_vmode_to_var(default_vmode, default_cmode, &var) < 0) {
+ printk(KERN_ERR "platinumfb: mac_vmode_to_var() failed\n");
+ return -ENXIO;
+ }
}
- disp = &info->disp;
-
- strcpy(info->fb_info.modename, "platinum");
- info->fb_info.node = NODEV;
- info->fb_info.fbops = &platinumfb_ops;
- info->fb_info.disp = disp;
- info->fb_info.currcon = -1;
- strcpy(info->fb_info.fontname, fontname);
- info->fb_info.changevar = NULL;
- info->fb_info.switch_con = &platinum_switch;
- info->fb_info.updatevar = &platinum_updatevar;
- info->fb_info.flags = FBINFO_FLAG_DEFAULT;
-
- 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];
- }
- platinum_set_var(&var, -1, &info->fb_info);
+ /* Initialize info structure */
+ platinum_init_info(&p->info, p);
- if (register_framebuffer(&info->fb_info) < 0)
+ /* Apply default var */
+ p->info.var = var;
+ var.activate = FB_ACTIVATE_NOW;
+ rc = gen_set_var(&var, -1, &p->info);
+ if (rc && (default_vmode != VMODE_640_480_60 || default_cmode != CMODE_8))
+ goto try_again;
+
+ /* Register with fbdev layer */
+ if (register_framebuffer(&p->info) < 0)
return 0;
printk(KERN_INFO "fb%d: platinum frame buffer device\n",
- GET_FB_IDX(info->fb_info.node));
+ GET_FB_IDX(p->info.node));
return 1;
}
@@ -761,33 +617,6 @@ static int platinum_par_to_var(struct fb_var_screeninfo *var,
return mac_vmode_to_var(par->vmode, par->cmode, var);
}
-static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
- const struct fb_par_platinum *par,
- const struct fb_info_platinum *info)
-{
- struct platinum_regvals *init;
-
- init = platinum_reg_init[par->vmode-1];
-
- memset(fix, 0, sizeof(*fix));
- strcpy(fix->id, "platinum");
- fix->smem_start = (info->frame_buffer_phys) + init->fb_offset + 0x20;
- fix->smem_len = (u32) info->total_vram;
- fix->mmio_start = (info->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->visual = (par->cmode == CMODE_8) ?
- FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
- fix->line_length = vmode_attrs[par->vmode-1].hres * (1<<par->cmode) + 0x20;
-
- return 0;
-}
-
-
/*
* Parse user speficied options (`video=platinumfb:')
*/
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 168f4ec92505..2141b8d8a65a 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -2289,7 +2289,7 @@ int __init pm2fb_init(void) {
return -EINVAL;
}
printk(KERN_INFO "fb%d: %s (%s), using %uK of video memory.\n",
- GET_FB_IDX(fb_info.gen.info.node),
+ minor(fb_info.gen.info.node),
board_table[fb_info.board].name,
permedia2_name,
(u32 )(fb_info.regions.fb_size>>10));
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 0653a9650718..7bdc0abe61df 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -1647,7 +1647,7 @@ static void pm3fb_common_init(struct pm3fb_info *l_fb_info)
pm3fb_write_mode(l_fb_info);
printk("fb%d: %s, using %uK of video memory (%s)\n",
- GET_FB_IDX(l_fb_info->gen.info.node),
+ minor(l_fb_info->gen.info.node),
permedia3_name, (u32) (l_fb_info->fb_size >> 10),
cardbase[l_fb_info->board_type].cardname);
}
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index aba95ee840c4..18b756278fec 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -36,8 +36,6 @@
#include <asm/dec/tc.h>
#include "pmag-ba-fb.h"
-#include <video/fbcon.h>
-
struct pmag_ba_ramdac_regs {
unsigned char addr_low;
unsigned char pad0[3];
@@ -52,28 +50,30 @@ struct pmag_ba_ramdac_regs {
* Max 3 TURBOchannel slots -> max 3 PMAG-BA :)
*/
static struct fb_info pmagba_fb_info[3];
-static struct display pmagba_disp[3];
static struct fb_var_screeninfo pmagbafb_defined = {
- .xres = 1024,
- .yres = 864,
- .xres_virtual = 1024,
- .yres_virtual = 864,
- .bits_per_pixel =8,
- .activate = FB_ACTIVATE_NOW,
- .height = 274,
- .width = 195,
- .accel = FB_ACCEL_NONE,
- .vmode = FB_VMODE_NONINTERLACED,
-}
+ .xres = 1024,
+ .yres = 864,
+ .xres_virtual = 1024,
+ .yres_virtual = 864,
+ .bits_per_pixel = 8,
+ .red.length = 8,
+ .green.length = 8,
+ .blue.length = 8,
+ .activate = FB_ACTIVATE_NOW,
+ .height = 274,
+ .width = 195,
+ .accel = FB_ACCEL_NONE,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
static struct fb_fix_screeninfo pmagbafb_fix = {
- .id = "PMAG-BA",
- .smem_len = (1024 * 864),
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .line_length = 1024,
-}
+ .id = "PMAG-BA",
+ .smem_len = (1024 * 864),
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .line_length = 1024,
+};
/*
* Turn hardware cursor off
@@ -111,20 +111,17 @@ static int pmagbafb_setcolreg(unsigned regno, unsigned red, unsigned green,
static struct fb_ops pmagbafb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = pmagbafb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
-}
+ .fb_cursor = soft_cursor,
+};
int __init pmagbafb_init_one(int slot)
{
unsigned long base_addr = get_tc_base_addr(slot);
struct fb_info *info = &pmagba_fb_info[slot];
- struct display *disp = &pmagba_disp[slot];
printk("PMAG-BA framebuffer in slot %d\n", slot);
/*
@@ -141,21 +138,14 @@ int __init pmagbafb_init_one(int slot)
/*
* Let there be consoles..
*/
- strcpy(info->modename, pmagbafb_fix.id);
- info->changevar = NULL;
info->node = NODEV;
info->fbops = &pmagbafb_ops;
info->var = pmagbafb_defined;
info->fix = pmagbafb_fix;
info->screen_base = pmagbafb_fix.smem_start;
- info->disp = &disp;
- info->currcon = -1;
- info->switch_con = gen_switch;
- info->updatevar = gen_update_var;
info->flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&fb_info.cmap, 256, 0);
- gen_set_disp(-1, info);
if (register_framebuffer(info) < 0)
return 1;
@@ -183,9 +173,4 @@ int __init pmagbafb_init(void)
}
}
-int __init pmagbafb_setup(char *options)
-{
- return 0;
-}
-
MODULE_LICENSE("GPL");
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 9d95f157ce46..5c2108d8a7fb 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -39,8 +39,6 @@
#include <asm/dec/tc.h>
#include "pmagb-b-fb.h"
-#include <video/fbcon.h>
-
struct pmagb_b_ramdac_regs {
unsigned char addr_low;
unsigned char pad0[3];
@@ -55,27 +53,29 @@ struct pmagb_b_ramdac_regs {
* Max 3 TURBOchannel slots -> max 3 PMAGB-B :)
*/
static struct fb_info pmagbb_fb_info[3];
-static struct display pmagbb_disp[3];
static struct fb_var_screeninfo pmagbbfb_defined = {
- .xres = 1280,
- .yres = 1024,
- .xres_virtual = 1280,
- .yres_virtual = 1024,
- .bits_per_pixel =8,
- .activate = FB_ACTIVATE_NOW,
- .height = 274,
- .width = 195,
- .accel_flags = FB_ACCEL_NONE,
- .vmode = FB_VMODE_NONINTERLACED,
+ .xres = 1280,
+ .yres = 1024,
+ .xres_virtual = 1280,
+ .yres_virtual = 1024,
+ .bits_per_pixel = 8,
+ .red.length = 8,
+ .green.length = 8,
+ .blue.length = 8,
+ .activate = FB_ACTIVATE_NOW,
+ .height = 274,
+ .width = 195,
+ .accel_flags = FB_ACCEL_NONE,
+ .vmode = FB_VMODE_NONINTERLACED,
};
static struct fb_fix_screeninfo pmagbafb_fix = {
- .id = "PMAGB-BA",
- .smem_len = (1280 * 1024),
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .line_length = 1280,
+ .id = "PMAGB-BA",
+ .smem_len = (1280 * 1024),
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .line_length = 1280,
}
/*
@@ -114,20 +114,17 @@ static int pmagbbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
static struct fb_ops pmagbbfb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = pmagbbfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
int __init pmagbbfb_init_one(int slot)
{
unsigned long base_addr = get_tc_base_addr(slot);
struct fb_info *info = &pmagbb_fb_info[slot];
- struct display *disp = &pmagbb_disp[slot];
printk("PMAGB-BA framebuffer in slot %d\n", slot);
/*
@@ -144,21 +141,14 @@ int __init pmagbbfb_init_one(int slot)
/*
* Let there be consoles..
*/
- strcpy(info->modename, pmagbbfb_fix.id);
- info->changevar = NULL;
info->node = NODEV;
info->fbops = &pmagbbfb_ops;
info->var = pmagbbfb_defined;
info->fix = pmagbbfb_fix;
info->screen_base = pmagbbfb_fix.smem_start;
- info->disp = &disp;
- info->currcon = -1;
- info->switch_con = gen_switch;
- info->updatevar = gen_update_var;
info->flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&fb_info.cmap, 256, 0);
- gen_set_disp(-1, info);
if (register_framebuffer(info) < 0)
return 1;
@@ -186,9 +176,4 @@ int __init pmagbbfb_init(void)
}
}
-int __init pmagbbfb_setup(char *options)
-{
- return 0;
-}
-
MODULE_LICENSE("GPL");
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 1b0725a11cbc..0790fbf9db7d 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -1059,10 +1059,10 @@ int __init pvr2fb_init(void)
modememused = get_line_length(var.xres_virtual, var.bits_per_pixel);
modememused *= var.yres_virtual;
printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n",
- GET_FB_IDX(fb_info.node), fb_info.modename, modememused>>10,
+ minor(fb_info.node), fb_info.modename, modememused>>10,
videomemorysize>>10);
printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n",
- GET_FB_IDX(fb_info.node), var.xres, var.yres, var.bits_per_pixel,
+ minor(fb_info.node), var.xres, var.yres, var.bits_per_pixel,
get_line_length(var.xres, var.bits_per_pixel),
(char *)pvr2_get_param(cables, NULL, cable_type, 3),
(char *)pvr2_get_param(outputs, NULL, video_output, 3));
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index 97b036f6cce0..7093cd15b7a6 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -28,13 +28,10 @@
#include <linux/module.h>
#include <asm/pgtable.h>
-#include <video/fbcon.h>
-
#define Q40_PHYS_SCREEN_ADDR 0xFE800000
static u32 pseudo_palette[17];
static struct fb_info fb_info;
-static struct display display;
static struct fb_fix_screeninfo q40fb_fix __initdata = {
.id = "Q40",
@@ -69,13 +66,11 @@ static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
static struct fb_ops q40fb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = q40fb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -117,15 +112,8 @@ int q40fb_init(void)
fb_info.screen_base = (char *) q40fb_fix.smem_start;
/* The below feilds will go away !!!! */
- fb_info.currcon = -1;
- strcpy(fb_info.modename, fb_info.fix.id);
- fb_info.disp = &display;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_alloc_cmap(&fb_info.cmap, 16, 0);
- gen_set_disp(-1, &fb_info);
-
master_outb(3, DISPLAY_CONTROL_REG);
if (register_framebuffer(&fb_info) < 0) {
@@ -134,7 +122,7 @@ int q40fb_init(void)
}
printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n",
- GET_FB_IDX(fb_info.node));
+ minor(fb_info.node));
return 0;
}
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index b55a6b503e7c..ea8466a9bd7a 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -2,7 +2,7 @@
* drivers/video/radeonfb.c
* framebuffer driver for ATI Radeon chipset video boards
*
- * Copyright 2000 Ani Joshi <ajoshi@unixbox.com>
+ * Copyright 2000 Ani Joshi <ajoshi@kernel.crashing.org>
*
*
* ChangeLog:
@@ -15,13 +15,21 @@
* blanking, pan_display, and cmap fixes, 0.1.0
* 2001-10-10 Radeon 7500 and 8500 support, and experimental
* flat panel support, 0.1.1
+ * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2
+ * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3
+ * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt
+ * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4
+ * 2002-06-02 console switching, mode set fixes, accel fixes
+ * 2002-06-03 MTRR support, Peter Horton, 0.1.5
+ * 2002-09-21 rv250, r300, m9 initial support,
+ * added mirror option, 0.1.6
*
* Special thanks to ATI DevRel team for their hardware donations.
*
*/
-#define RADEON_VERSION "0.1.1"
+#define RADEON_VERSION "0.1.6"
#include <linux/config.h>
@@ -34,27 +42,45 @@
#include <linux/slab.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 <linux/pci.h>
+#include <linux/vmalloc.h>
#include <asm/io.h>
+#include <asm/uaccess.h>
#if defined(__powerpc__)
#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include "macmodes.h"
+
+#ifdef CONFIG_NVRAM
+#include <linux/nvram.h>
#endif
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
-#include "radeon.h"
+#ifdef CONFIG_BOOTX_TEXT
+#include <asm/btext.h>
+#endif
+#ifdef CONFIG_ADB_PMU
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#endif
-#define DEBUG 0
+#endif /* __powerpc__ */
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <video/radeon.h>
+#include <linux/radeonfb.h>
+
+#define DEBUG 1
#if DEBUG
#define RTRACE printk
@@ -62,6 +88,8 @@
#define RTRACE if(0) printk
#endif
+// XXX
+#undef CONFIG_PMAC_PBOOK
enum radeon_chips {
@@ -71,11 +99,76 @@ enum radeon_chips {
RADEON_QG,
RADEON_QY,
RADEON_QZ,
- RADEON_QL,
- RADEON_QW,
RADEON_LW,
+ RADEON_LX,
RADEON_LY,
- RADEON_LZ
+ RADEON_LZ,
+ RADEON_QL,
+ RADEON_QN,
+ RADEON_QO,
+ RADEON_Ql,
+ RADEON_BB,
+ RADEON_QW,
+ RADEON_QX,
+ RADEON_Id,
+ RADEON_Ie,
+ RADEON_If,
+ RADEON_Ig,
+ RADEON_Ld,
+ RADEON_Le,
+ RADEON_Lf,
+ RADEON_Lg,
+ RADEON_ND,
+ RADEON_NE,
+ RADEON_NF,
+ RADEON_NG
+};
+
+enum radeon_arch {
+ RADEON_R100,
+ RADEON_RV100,
+ RADEON_R200,
+ RADEON_RV200,
+ RADEON_RV250,
+ RADEON_R300,
+ RADEON_M6,
+ RADEON_M7,
+ RADEON_M9
+};
+
+static struct radeon_chip_info {
+ const char *name;
+ unsigned char arch;
+} radeon_chip_info[] __devinitdata = {
+ { "QD", RADEON_R100 },
+ { "QE", RADEON_R100 },
+ { "QF", RADEON_R100 },
+ { "QG", RADEON_R100 },
+ { "VE QY", RADEON_RV100 },
+ { "VE QZ", RADEON_RV100 },
+ { "M7 LW", RADEON_M7 },
+ { "M7 LX", RADEON_M7 },
+ { "M6 LY", RADEON_M6 },
+ { "M6 LZ", RADEON_M6 },
+ { "8500 QL", RADEON_R200 },
+ { "8500 QN", RADEON_R200 },
+ { "8500 QO", RADEON_R200 },
+ { "8500 Ql", RADEON_R200 },
+ { "8500 BB", RADEON_R200 },
+ { "7500 QW", RADEON_RV200 },
+ { "7500 QX", RADEON_RV200 },
+ { "9000 Id", RADEON_RV250 },
+ { "9000 Ie", RADEON_RV250 },
+ { "9000 If", RADEON_RV250 },
+ { "9000 Ig", RADEON_RV250 },
+ { "M9 Ld", RADEON_M9 },
+ { "M9 Le", RADEON_M9 },
+ { "M9 Lf", RADEON_M9 },
+ { "M9 Lg", RADEON_M9 },
+ { "9700 ND", RADEON_R300 },
+ { "9700 NE", RADEON_R300 },
+ { "9700 NF", RADEON_R300 },
+ { "9700 NG", RADEON_R300 }
};
@@ -91,17 +184,35 @@ enum radeon_montype
static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG},
{ 0, }
};
MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
@@ -128,7 +239,15 @@ reg_val common_regs[] = {
{ CAP0_TRIG_CNTL, 0 },
};
-#define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
+reg_val common_regs_m6[] = {
+ { OVR_CLR, 0 },
+ { OVR_WID_LEFT_RIGHT, 0 },
+ { OVR_WID_TOP_BOTTOM, 0 },
+ { OV0_SCALE_CNTL, 0 },
+ { SUBPIC_CNTL, 0 },
+ { GEN_INT_CNTL, 0 },
+ { CAP0_TRIG_CNTL, 0 }
+};
typedef struct {
u8 clock_chip_type;
@@ -192,7 +311,6 @@ struct radeon_regs {
u32 flags;
u32 pix_clock;
int xres, yres;
- int bpp;
/* DDA regs */
u32 dda_config;
@@ -201,7 +319,8 @@ struct radeon_regs {
/* PLL regs */
u32 ppll_div_3;
u32 ppll_ref_div;
-
+ u32 vclk_ecp_cntl;
+
/* Flat panel regs */
u32 fp_crtc_h_total_disp;
u32 fp_crtc_v_total_disp;
@@ -214,6 +333,7 @@ struct radeon_regs {
u32 lvds_gen_cntl;
u32 lvds_pll_cntl;
u32 tmds_crc;
+ u32 tmds_transmitter_cntl;
#if defined(__BIG_ENDIAN)
u32 surface_cntl;
@@ -227,35 +347,47 @@ struct radeonfb_info {
struct radeon_regs state;
struct radeon_regs init_state;
- char name[17];
+ char name[32];
char ram_type[12];
- u32 mmio_base_phys;
- u32 fb_base_phys;
+ unsigned long mmio_base_phys;
+ unsigned long fb_base_phys;
- u32 mmio_base;
- u32 fb_base;
+ unsigned long mmio_base;
+ unsigned long fb_base;
struct pci_dev *pdev;
- struct display disp;
- struct display *currcon_display;
+ unsigned char *EDID;
+ unsigned char *bios_seg;
+
+ struct display disp; /* Will disappear */
+ u32 pseudo_palette[17];
struct { u8 red, green, blue, pad; } palette[256];
int chipset;
+ unsigned char arch;
int video_ram;
u8 rev;
int pitch, bpp, depth;
int xres, yres, pixclock;
+ int xres_virtual, yres_virtual;
+ u32 accel_flags;
+
+ int use_default_var;
+ int got_dfpinfo;
int hasCRTC2;
int crtDisp_type;
int dviDisp_type;
int panel_xres, panel_yres;
+ int clock;
int hOver_plus, hSync_width, hblank;
int vOver_plus, vSync_width, vblank;
+ int hAct_high, vAct_high, interlaced;
+ int synct, misc;
u32 dp_gui_master_cntl;
@@ -264,22 +396,16 @@ struct radeonfb_info {
struct ram_info ram;
- u32 hack_crtc_ext_cntl;
- u32 hack_crtc_v_sync_strt_wid;
+ int mtrr_hdl;
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
- union {
-#if defined(FBCON_HAS_CFB16)
- u_int16_t cfb16[16];
-#endif
-#if defined(FBCON_HAS_CFB24)
- u_int32_t cfb24[16];
-#endif
-#if defined(FBCON_HAS_CFB32)
- u_int32_t cfb32[16];
-#endif
- } con_cmap;
-#endif
+#ifdef CONFIG_PMAC_PBOOK
+ int pm_reg;
+ u32 save_regs[64];
+ u32 mdll, mdll2;
+#endif /* CONFIG_PMAC_PBOOK */
+ int asleep;
+
+ struct radeonfb_info *next;
};
@@ -290,7 +416,6 @@ static struct fb_var_screeninfo radeonfb_default_var = {
0, FB_VMODE_NONINTERLACED
};
-
/*
* IO macros
*/
@@ -300,8 +425,12 @@ static struct fb_var_screeninfo radeonfb_default_var = {
#define INREG(addr) readl((rinfo->mmio_base)+addr)
#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
-#define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
- OUTREG(CLOCK_CNTL_DATA, val)
+#define OUTPLL(addr,val) \
+ do { \
+ OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
+ OUTREG(CLOCK_CNTL_DATA, val); \
+ } while(0)
+
#define OUTPLLP(addr,val,mask) \
do { \
unsigned int _tmp = INPLL(addr); \
@@ -321,7 +450,7 @@ static struct fb_var_screeninfo radeonfb_default_var = {
static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
{
- OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
+ OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
return (INREG(CLOCK_CNTL_DATA));
}
@@ -432,6 +561,14 @@ static __inline__ u32 radeon_get_dstbpp(u16 depth)
}
+static inline int var_to_depth(const struct fb_var_screeninfo *var)
+{
+ if (var->bits_per_pixel != 16)
+ return var->bits_per_pixel;
+ return (var->green.length == 6) ? 16 : 15;
+}
+
+
static void _radeon_engine_reset(struct radeonfb_info *rinfo)
{
u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
@@ -457,8 +594,7 @@ static void _radeon_engine_reset(struct radeonfb_info *rinfo)
SOFT_RESET_RE |
SOFT_RESET_PP |
SOFT_RESET_E2 |
- SOFT_RESET_RB |
- SOFT_RESET_HDP);
+ SOFT_RESET_RB);
INREG(RBBM_SOFT_RESET);
OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
~(SOFT_RESET_CP |
@@ -467,8 +603,7 @@ static void _radeon_engine_reset(struct radeonfb_info *rinfo)
SOFT_RESET_RE |
SOFT_RESET_PP |
SOFT_RESET_E2 |
- SOFT_RESET_RB |
- SOFT_RESET_HDP));
+ SOFT_RESET_RB));
INREG(RBBM_SOFT_RESET);
OUTPLL(MCLK_CNTL, mclk_cntl);
@@ -542,416 +677,57 @@ static __inline__ int _max(int val1, int val2)
* globals
*/
-static char fontname[40] __initdata;
static char *mode_option __initdata;
-static char noaccel __initdata = 0;
-static char panel_yres __initdata = 0;
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_radeon8;
-#endif
-
+static char noaccel = 1;
+static char mirror = 0;
+static int panel_yres __initdata = 0;
+static char force_dfp __initdata = 0;
+static struct radeonfb_info *board_list = NULL;
+static char nomtrr __initdata = 0;
/*
* prototypes
*/
-static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp, struct fb_info *info);
-static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int radeonfb_blank (int blank, struct fb_info *info);
-static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, int con, struct fb_info *info);
-static int radeonfb_switch (int con, struct fb_info *info);
-static int radeonfb_updatevar (int con, struct fb_info *info);
-static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
-static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info);
-static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);
static void radeon_save_state (struct radeonfb_info *rinfo,
struct radeon_regs *save);
static void radeon_engine_init (struct radeonfb_info *rinfo);
-static void radeon_load_video_mode (struct radeonfb_info *rinfo,
- struct fb_var_screeninfo *mode);
static void radeon_write_mode (struct radeonfb_info *rinfo,
struct radeon_regs *mode);
static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
-static int radeon_init_disp_var (struct radeonfb_info *rinfo);
-static int radeonfb_pci_register (struct pci_dev *pdev,
- const struct pci_device_id *ent);
-static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
+static int radeon_init_disp_var (struct radeonfb_info *rinfo, struct fb_var_screeninfo *var);
static char *radeon_find_rom(struct radeonfb_info *rinfo);
static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);
static void radeon_get_moninfo (struct radeonfb_info *rinfo);
static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);
-static int radeon_read_OF (struct radeonfb_info *rinfo);
+static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);
+static void radeon_get_EDID(struct radeonfb_info *rinfo);
+static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
+static void radeon_update_default_var(struct radeonfb_info *rinfo);
-#if defined(__powerpc__)
+#ifdef CONFIG_ALL_PPC
+
+static int radeon_read_OF (struct radeonfb_info *rinfo);
+static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
-#endif
-static struct fb_ops radeon_fb_ops = {
- .fb_get_fix = radeonfb_get_fix,
- .fb_get_var = radeonfb_get_var,
- .fb_set_var = radeonfb_set_var,
- .fb_get_cmap = radeonfb_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = radeonfb_setcolreg,
- .fb_pan_display = radeonfb_pan_display,
- .fb_blank = radeonfb_blank,
- .fb_ioctl = radeonfb_ioctl,
+#ifdef CONFIG_PMAC_PBOOK
+int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier radeon_sleep_notifier = {
+ radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
};
-
-
-static struct pci_driver radeonfb_driver = {
- .name = "radeonfb",
- .id_table = radeonfb_pci_table,
- .probe = radeonfb_pci_register,
- .remove = __devexit_p(radeonfb_pci_unregister),
+#endif /* CONFIG_PMAC_PBOOK */
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int radeon_set_backlight_enable(int on, int level, void *data);
+static int radeon_set_backlight_level(int level, void *data);
+static struct backlight_controller radeon_backlight_controller = {
+ radeon_set_backlight_enable,
+ radeon_set_backlight_level
};
+#endif /* CONFIG_PMAC_BACKLIGHT */
-
-int __init radeonfb_init (void)
-{
- return pci_module_init (&radeonfb_driver);
-}
-
-
-void __exit radeonfb_exit (void)
-{
- pci_unregister_driver (&radeonfb_driver);
-}
-
-
-int __init radeonfb_setup (char *options)
-{
- char *this_opt;
-
- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep (&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- 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);
- } else if (!strncmp(this_opt, "noaccel", 7)) {
- noaccel = 1;
- } else if (!strncmp(this_opt, "panel_yres:", 11)) {
- panel_yres = simple_strtoul((this_opt+11), NULL, 0);
- } else
- mode_option = this_opt;
- }
-
- return 0;
-}
-
-#ifdef MODULE
-module_init(radeonfb_init);
-module_exit(radeonfb_exit);
-#endif
-
-
-MODULE_AUTHOR("Ani Joshi");
-MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
-MODULE_LICENSE("GPL");
-
-static int radeonfb_pci_register (struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct radeonfb_info *rinfo;
- u32 tmp;
- int i, j;
- char *bios_seg = NULL;
-
- RTRACE("radeonfb_pci_register BEGIN\n");
-
- rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
- if (!rinfo) {
- printk ("radeonfb: could not allocate memory\n");
- return -ENODEV;
- }
-
- memset (rinfo, 0, sizeof (struct radeonfb_info));
-
- rinfo->pdev = pdev;
-
- /* enable device */
- {
- int err;
-
- if ((err = pci_enable_device(pdev))) {
- printk("radeonfb: cannot enable device\n");
- kfree (rinfo);
- return -ENODEV;
- }
- }
-
- /* set base addrs */
- rinfo->fb_base_phys = pci_resource_start (pdev, 0);
- rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
-
- /* request the mem regions */
- if (!request_mem_region (rinfo->fb_base_phys,
- pci_resource_len(pdev, 0), "radeonfb")) {
- printk ("radeonfb: cannot reserve FB region\n");
- kfree (rinfo);
- return -ENODEV;
- }
-
- if (!request_mem_region (rinfo->mmio_base_phys,
- pci_resource_len(pdev, 2), "radeonfb")) {
- printk ("radeonfb: cannot reserve MMIO region\n");
- release_mem_region (rinfo->fb_base_phys,
- pci_resource_len(pdev, 0));
- kfree (rinfo);
- return -ENODEV;
- }
-
- /* map the regions */
- rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys,
- RADEON_REGSIZE);
- if (!rinfo->mmio_base) {
- printk ("radeonfb: cannot map MMIO\n");
- release_mem_region (rinfo->mmio_base_phys,
- pci_resource_len(pdev, 2));
- release_mem_region (rinfo->fb_base_phys,
- pci_resource_len(pdev, 0));
- kfree (rinfo);
- return -ENODEV;
- }
-
- rinfo->chipset = pdev->device;
-
- /* chipset */
- switch (pdev->device) {
- case PCI_DEVICE_ID_RADEON_QD:
- strcpy(rinfo->name, "Radeon QD ");
- break;
- case PCI_DEVICE_ID_RADEON_QE:
- strcpy(rinfo->name, "Radeon QE ");
- break;
- case PCI_DEVICE_ID_RADEON_QF:
- strcpy(rinfo->name, "Radeon QF ");
- break;
- case PCI_DEVICE_ID_RADEON_QG:
- strcpy(rinfo->name, "Radeon QG ");
- break;
- case PCI_DEVICE_ID_RADEON_QY:
- strcpy(rinfo->name, "Radeon QY VE ");
- rinfo->hasCRTC2 = 1;
- break;
- case PCI_DEVICE_ID_RADEON_QZ:
- strcpy(rinfo->name, "Radeon QZ VE ");
- rinfo->hasCRTC2 = 1;
- break;
- case PCI_DEVICE_ID_RADEON_QW:
- strcpy(rinfo->name, "Radeon 7500 QW ");
- rinfo->hasCRTC2 = 1;
- break;
- case PCI_DEVICE_ID_RADEON_QL:
- strcpy(rinfo->name, "Radeon 8500 QL ");
- rinfo->hasCRTC2 = 1;
- break;
- case PCI_DEVICE_ID_RADEON_LW:
- strcpy(rinfo->name, "Radeon M7 LW ");
- rinfo->hasCRTC2 = 1;
- break;
- case PCI_DEVICE_ID_RADEON_LY:
- strcpy(rinfo->name, "Radeon M6 LY ");
- rinfo->hasCRTC2 = 1;
- break;
- case PCI_DEVICE_ID_RADEON_LZ:
- strcpy(rinfo->name, "Radeon M6 LZ ");
- rinfo->hasCRTC2 = 1;
- break;
- default:
- return -ENODEV;
- }
-
- /* framebuffer size */
- tmp = INREG(CONFIG_MEMSIZE);
-
- /* mem size is bits [28:0], mask off the rest */
- rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
-
- /* ram type */
- tmp = INREG(MEM_SDRAM_MODE_REG);
- switch ((MEM_CFG_TYPE & tmp) >> 30) {
- case 0:
- /* SDR SGRAM (2:1) */
- strcpy(rinfo->ram_type, "SDR SGRAM");
- rinfo->ram.ml = 4;
- rinfo->ram.mb = 4;
- rinfo->ram.trcd = 1;
- rinfo->ram.trp = 2;
- rinfo->ram.twr = 1;
- rinfo->ram.cl = 2;
- rinfo->ram.loop_latency = 16;
- rinfo->ram.rloop = 16;
-
- break;
- case 1:
- /* DDR SGRAM */
- strcpy(rinfo->ram_type, "DDR SGRAM");
- rinfo->ram.ml = 4;
- rinfo->ram.mb = 4;
- rinfo->ram.trcd = 3;
- rinfo->ram.trp = 3;
- rinfo->ram.twr = 2;
- rinfo->ram.cl = 3;
- rinfo->ram.tr2w = 1;
- rinfo->ram.loop_latency = 16;
- rinfo->ram.rloop = 16;
-
- break;
- default:
- /* 64-bit SDR SGRAM */
- strcpy(rinfo->ram_type, "SDR SGRAM 64");
- rinfo->ram.ml = 4;
- rinfo->ram.mb = 8;
- rinfo->ram.trcd = 3;
- rinfo->ram.trp = 3;
- rinfo->ram.twr = 1;
- rinfo->ram.cl = 3;
- rinfo->ram.tr2w = 1;
- rinfo->ram.loop_latency = 17;
- rinfo->ram.rloop = 17;
-
- break;
- }
-
- bios_seg = radeon_find_rom(rinfo);
- radeon_get_pllinfo(rinfo, bios_seg);
-
- RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
-
- radeon_get_moninfo(rinfo);
- if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
- (rinfo->crtDisp_type == MT_DFP)) {
- if (!radeon_get_dfpinfo(rinfo)) {
- iounmap ((void*)rinfo->mmio_base);
- release_mem_region (rinfo->mmio_base_phys,
- pci_resource_len(pdev, 2));
- release_mem_region (rinfo->fb_base_phys,
- pci_resource_len(pdev, 0));
- kfree (rinfo);
- return -ENODEV;
- }
- }
-
- rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
- rinfo->video_ram);
- if (!rinfo->fb_base) {
- printk ("radeonfb: cannot map FB\n");
- iounmap ((void*)rinfo->mmio_base);
- release_mem_region (rinfo->mmio_base_phys,
- pci_resource_len(pdev, 2));
- release_mem_region (rinfo->fb_base_phys,
- pci_resource_len(pdev, 0));
- kfree (rinfo);
- return -ENODEV;
- }
-
- /* XXX turn off accel for now, blts aren't working right */
- noaccel = 1;
-
- /* set all the vital stuff */
- radeon_set_fbinfo (rinfo);
-
- /* save current mode regs before we switch into the new one
- * so we can restore this upon __exit
- */
- radeon_save_state (rinfo, &rinfo->init_state);
-
- /* init palette */
- for (i=0; i<16; i++) {
- j = color_table[i];
- rinfo->palette[i].red = default_red[j];
- rinfo->palette[i].green = default_grn[j];
- rinfo->palette[i].blue = default_blu[j];
- }
-
- pci_set_drvdata(pdev, rinfo);
-
- if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
- printk ("radeonfb: could not register framebuffer\n");
- iounmap ((void*)rinfo->fb_base);
- iounmap ((void*)rinfo->mmio_base);
- release_mem_region (rinfo->mmio_base_phys,
- pci_resource_len(pdev, 2));
- release_mem_region (rinfo->fb_base_phys,
- pci_resource_len(pdev, 0));
- kfree (rinfo);
- return -ENODEV;
- }
-
- if (!noaccel) {
- /* initialize the engine */
- radeon_engine_init (rinfo);
- }
-
- printk ("radeonfb: ATI %s %s %d MB\n", rinfo->name, rinfo->ram_type,
- (rinfo->video_ram/(1024*1024)));
-
- if (rinfo->hasCRTC2) {
- printk("radeonfb: DVI port %s monitor connected\n",
- GET_MON_NAME(rinfo->dviDisp_type));
- printk("radeonfb: CRT port %s monitor connected\n",
- GET_MON_NAME(rinfo->crtDisp_type));
- } else {
- printk("radeonfb: CRT port %s monitor connected\n",
- GET_MON_NAME(rinfo->crtDisp_type));
- }
-
- RTRACE("radeonfb_pci_register END\n");
-
- return 0;
-}
-
-
-
-static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
-{
- struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
-
- if (!rinfo)
- return;
-
- /* restore original state */
- radeon_write_mode (rinfo, &rinfo->init_state);
-
- unregister_framebuffer ((struct fb_info *) rinfo);
-
- iounmap ((void*)rinfo->mmio_base);
- iounmap ((void*)rinfo->fb_base);
-
- release_mem_region (rinfo->mmio_base_phys,
- pci_resource_len(pdev, 2));
- release_mem_region (rinfo->fb_base_phys,
- pci_resource_len(pdev, 0));
-
- kfree (rinfo);
-}
-
+#endif /* CONFIG_ALL_PPC */
static char *radeon_find_rom(struct radeonfb_info *rinfo)
@@ -1053,7 +829,7 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
} else {
-#if defined(__powerpc__)
+#ifdef CONFIG_ALL_PPC
if (radeon_read_OF(rinfo)) {
unsigned int tmp, Nx, M, ref_div, xclk;
@@ -1078,24 +854,39 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
#endif
/* no BIOS or BIOS not found, use defaults */
switch (rinfo->chipset) {
- case PCI_DEVICE_ID_RADEON_QW:
+ case PCI_DEVICE_ID_ATI_RADEON_QW:
+ case PCI_DEVICE_ID_ATI_RADEON_QX:
rinfo->pll.ppll_max = 35000;
rinfo->pll.ppll_min = 12000;
rinfo->pll.xclk = 23000;
rinfo->pll.ref_div = 12;
rinfo->pll.ref_clk = 2700;
break;
- case PCI_DEVICE_ID_RADEON_QL:
+ case PCI_DEVICE_ID_ATI_RADEON_QL:
+ case PCI_DEVICE_ID_ATI_RADEON_QN:
+ case PCI_DEVICE_ID_ATI_RADEON_QO:
+ case PCI_DEVICE_ID_ATI_RADEON_Ql:
+ case PCI_DEVICE_ID_ATI_RADEON_BB:
rinfo->pll.ppll_max = 35000;
rinfo->pll.ppll_min = 12000;
rinfo->pll.xclk = 27500;
rinfo->pll.ref_div = 12;
rinfo->pll.ref_clk = 2700;
break;
- case PCI_DEVICE_ID_RADEON_QD:
- case PCI_DEVICE_ID_RADEON_QE:
- case PCI_DEVICE_ID_RADEON_QF:
- case PCI_DEVICE_ID_RADEON_QG:
+ case PCI_DEVICE_ID_ATI_RADEON_Id:
+ case PCI_DEVICE_ID_ATI_RADEON_Ie:
+ case PCI_DEVICE_ID_ATI_RADEON_If:
+ case PCI_DEVICE_ID_ATI_RADEON_Ig:
+ rinfo->pll.ppll_max = 35000;
+ rinfo->pll.ppll_min = 12000;
+ rinfo->pll.xclk = 25000;
+ rinfo->pll.ref_div = 12;
+ rinfo->pll.ref_clk = 2700;
+ break;
+ case PCI_DEVICE_ID_ATI_RADEON_QD:
+ case PCI_DEVICE_ID_ATI_RADEON_QE:
+ case PCI_DEVICE_ID_ATI_RADEON_QF:
+ case PCI_DEVICE_ID_ATI_RADEON_QG:
default:
rinfo->pll.ppll_max = 35000;
rinfo->pll.ppll_min = 12000;
@@ -1115,8 +906,14 @@ static void radeon_get_moninfo (struct radeonfb_info *rinfo)
{
unsigned int tmp;
- tmp = INREG(RADEON_BIOS_4_SCRATCH);
+ if (force_dfp) {
+ rinfo->dviDisp_type = MT_DFP;
+ return;
+ }
+ tmp = INREG(RADEON_BIOS_4_SCRATCH);
+ printk(KERN_DEBUG "radeon_get_moninfo: bios 4 scratch = %x\n", tmp);
+
if (rinfo->hasCRTC2) {
/* primary DVI port */
if (tmp & 0x08)
@@ -1154,74 +951,254 @@ static void radeon_get_moninfo (struct radeonfb_info *rinfo)
}
-static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
+
+static void radeon_get_EDID(struct radeonfb_info *rinfo)
{
- unsigned int tmp;
- unsigned short a, b;
+#ifdef CONFIG_ALL_PPC
+ if (!radeon_get_EDID_OF(rinfo))
+ RTRACE("radeonfb: could not retrieve EDID from OF\n");
+#else
+ /* XXX use other methods later */
+#endif
+}
- if (panel_yres) {
- rinfo->panel_yres = panel_yres;
- } else {
- tmp = INREG(FP_VERT_STRETCH);
- tmp &= 0x00fff000;
- rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
- }
- switch (rinfo->panel_yres) {
- case 480:
- rinfo->panel_xres = 640;
- break;
- case 600:
- rinfo->panel_xres = 800;
- break;
- case 786:
- rinfo->panel_xres = 1024;
- break;
- case 1024:
- rinfo->panel_xres = 1280;
- break;
- case 1050:
- rinfo->panel_xres = 1400;
- break;
- case 1200:
- rinfo->panel_xres = 1600;
- break;
- default:
- printk("radeonfb: Failed to detect DFP panel size\n");
- return 0;
+#ifdef CONFIG_ALL_PPC
+static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
+{
+ struct device_node *dp;
+ unsigned char *pedid = NULL;
+ static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };
+ int i;
+
+ dp = pci_device_to_OF_node(rinfo->pdev);
+ while (dp != NULL) {
+ for (i = 0; propnames[i] != NULL; ++i) {
+ pedid = (unsigned char *)
+ get_property(dp, propnames[i], NULL);
+ if (pedid != NULL) {
+ rinfo->EDID = pedid;
+ return 1;
+ }
+ }
+ dp = dp->child;
+ }
+ return 0;
+}
+#endif /* CONFIG_ALL_PPC */
+
+
+static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
+{
+ unsigned char *block = rinfo->EDID;
+
+ if (!block)
+ return 0;
+
+ /* jump to the detailed timing block section */
+ block += 54;
+
+ rinfo->clock = (block[0] + (block[1] << 8));
+ rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
+ rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
+ rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
+ rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
+ rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
+ rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
+ rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
+ rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
+ rinfo->interlaced = ((block[17] & 0x80) >> 7);
+ rinfo->synct = ((block[17] & 0x18) >> 3);
+ rinfo->misc = ((block[17] & 0x06) >> 1);
+ rinfo->hAct_high = rinfo->vAct_high = 0;
+ if (rinfo->synct == 3) {
+ if (rinfo->misc & 2)
+ rinfo->hAct_high = 1;
+ if (rinfo->misc & 1)
+ rinfo->vAct_high = 1;
}
- printk("radeonfb: detected DFP panel size: %dx%d\n",
+ printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
rinfo->panel_xres, rinfo->panel_yres);
- tmp = INREG(FP_CRTC_H_TOTAL_DISP);
- a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
- b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
- rinfo->hblank = (a - b + 1) * 8;
-
- tmp = INREG(FP_H_SYNC_STRT_WID);
- rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
- FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
- rinfo->hOver_plus *= 8;
- rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
- FP_H_SYNC_WID_SHIFT);
- rinfo->hSync_width *= 8;
- tmp = INREG(FP_CRTC_V_TOTAL_DISP);
- a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
- b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
- rinfo->vblank = a - b /* + 24 */ ;
-
- tmp = INREG(FP_V_SYNC_STRT_WID);
- rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
- - b + 1;
- rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
- FP_V_SYNC_WID_SHIFT);
+ rinfo->got_dfpinfo = 1;
return 1;
}
+static void radeon_update_default_var(struct radeonfb_info *rinfo)
+{
+ struct fb_var_screeninfo *var = &radeonfb_default_var;
+
+ var->xres = rinfo->panel_xres;
+ var->yres = rinfo->panel_yres;
+ var->xres_virtual = rinfo->panel_xres;
+ var->yres_virtual = rinfo->panel_yres;
+ var->xoffset = var->yoffset = 0;
+ var->bits_per_pixel = 8;
+ var->pixclock = 100000000 / rinfo->clock;
+ var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
+ var->right_margin = rinfo->hOver_plus;
+ var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
+ var->lower_margin = rinfo->vOver_plus;
+ var->hsync_len = rinfo->hSync_width;
+ var->vsync_len = rinfo->vSync_width;
+ var->sync = 0;
+ if (rinfo->synct == 3) {
+ if (rinfo->hAct_high)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (rinfo->vAct_high)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ }
+
+ var->vmode = 0;
+ if (rinfo->interlaced)
+ var->vmode |= FB_VMODE_INTERLACED;
+
+ rinfo->use_default_var = 1;
+}
+
+
+static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo)
+{
+ char *fpbiosstart, *tmp, *tmp0;
+ char stmp[30];
+ int i;
+
+ if (!rinfo->bios_seg)
+ return 0;
+
+ if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
+ printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
+ return 0;
+ }
+
+ if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {
+ printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
+ return 0;
+ }
+
+ for(i=0; i<24; i++)
+ stmp[i] = readb(tmp+i+1);
+ stmp[24] = 0;
+ printk("radeonfb: panel ID string: %s\n", stmp);
+ rinfo->panel_xres = readw(tmp + 25);
+ rinfo->panel_yres = readw(tmp + 27);
+ printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
+ rinfo->panel_xres, rinfo->panel_yres);
+
+ for(i=0; i<20; i++) {
+ tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
+ if (tmp0 == 0)
+ break;
+ if ((readw(tmp0) == rinfo->panel_xres) &&
+ (readw(tmp0+2) == rinfo->panel_yres)) {
+ rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
+ rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
+ rinfo->hSync_width = readb(tmp0+23) * 8;
+ rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
+ rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
+ rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
+ rinfo->clock = readw(tmp0+9);
+
+ rinfo->got_dfpinfo = 1;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+
+static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
+{
+ unsigned int tmp;
+ unsigned short a, b;
+
+ if (radeon_get_dfpinfo_BIOS(rinfo))
+ radeon_update_default_var(rinfo);
+
+ if (radeon_dfp_parse_EDID(rinfo))
+ radeon_update_default_var(rinfo);
+
+ if (!rinfo->got_dfpinfo) {
+ /*
+ * it seems all else has failed now and we
+ * resort to probing registers for our DFP info
+ */
+ if (panel_yres) {
+ rinfo->panel_yres = panel_yres;
+ } else {
+ tmp = INREG(FP_VERT_STRETCH);
+ tmp &= 0x00fff000;
+ rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
+ }
+
+ switch (rinfo->panel_yres) {
+ case 480:
+ rinfo->panel_xres = 640;
+ break;
+ case 600:
+ rinfo->panel_xres = 800;
+ break;
+ case 768:
#if defined(__powerpc__)
+ if (rinfo->dviDisp_type == MT_LCD)
+ rinfo->panel_xres = 1152;
+ else
+#endif
+ rinfo->panel_xres = 1024;
+ break;
+ case 1024:
+ rinfo->panel_xres = 1280;
+ break;
+ case 1050:
+ rinfo->panel_xres = 1400;
+ break;
+ case 1200:
+ rinfo->panel_xres = 1600;
+ break;
+ default:
+ printk("radeonfb: Failed to detect DFP panel size\n");
+ return 0;
+ }
+
+ printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
+ rinfo->panel_xres, rinfo->panel_yres);
+
+ tmp = INREG(FP_CRTC_H_TOTAL_DISP);
+ a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
+ b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
+ rinfo->hblank = (a - b + 1) * 8;
+
+ tmp = INREG(FP_H_SYNC_STRT_WID);
+ rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
+ FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
+ rinfo->hOver_plus *= 8;
+ rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
+ FP_H_SYNC_WID_SHIFT);
+ rinfo->hSync_width *= 8;
+ tmp = INREG(FP_CRTC_V_TOTAL_DISP);
+ a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
+ b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
+ rinfo->vblank = a - b /* + 24 */ ;
+
+ tmp = INREG(FP_V_SYNC_STRT_WID);
+ rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
+ - b + 1;
+ rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
+ FP_V_SYNC_WID_SHIFT);
+
+ return 1;
+ }
+
+ return 1;
+}
+
+
+#ifdef CONFIG_ALL_PPC
static int radeon_read_OF (struct radeonfb_info *rinfo)
{
struct device_node *dp;
@@ -1251,10 +1228,10 @@ static void radeon_engine_init (struct radeonfb_info *rinfo)
radeon_engine_reset ();
radeon_fifo_wait (1);
- OUTREG(DSTCACHE_MODE, 0);
+ OUTREG(RB2D_DSTCACHE_MODE, 0);
/* XXX */
- rinfo->pitch = ((rinfo->xres * (rinfo->depth / 8) + 0x3f)) >> 6;
+ rinfo->pitch = ((rinfo->xres_virtual * (rinfo->bpp / 8) + 0x3f)) >> 6;
radeon_fifo_wait (1);
temp = INREG(DEFAULT_PITCH_OFFSET);
@@ -1296,141 +1273,54 @@ static void radeon_engine_init (struct radeonfb_info *rinfo)
}
-
-static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
-{
- struct fb_info *info;
-
- info = &rinfo->info;
-
- strcpy (info->modename, rinfo->name);
- info->node = NODEV;
- info->flags = FBINFO_FLAG_DEFAULT;
- info->fbops = &radeon_fb_ops;
- info->screen_base = (char*)rinfo->fb_base;
- info->display_fg = NULL;
- info->currcon = -1;
- strncpy (info->fontname, fontname, sizeof (info->fontname));
- info->fontname[sizeof (info->fontname) - 1] = 0;
- info->changevar = NULL;
- info->switch_con = radeonfb_switch;
- info->updatevar = radeonfb_updatevar;
-
- if (radeon_init_disp (rinfo) < 0)
- return -1;
-
- return 0;
-}
-
-
-
static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
{
- struct fb_info *info;
- struct display *disp;
+ struct fb_info *info = &rinfo->info;
+ struct fb_var_screeninfo var;
- info = &rinfo->info;
- disp = &rinfo->disp;
-
- disp->var = radeonfb_default_var;
- info->disp = disp;
-
- radeon_set_dispsw (rinfo, disp);
+ var = radeonfb_default_var;
+ if ((radeon_init_disp_var(rinfo, &var)) < 0)
+ return -1;
- if (noaccel)
- disp->scrollmode = SCROLL_YREDRAW;
- else
- disp->scrollmode = 0;
+ rinfo->depth = var_to_depth(&var);
+ rinfo->bpp = var.bits_per_pixel;
- rinfo->currcon_display = disp;
+ info->var = var;
+ fb_alloc_cmap(&info->cmap, 256, 0);
- if ((radeon_init_disp_var (rinfo)) < 0)
- return -1;
-
+ var.activate = FB_ACTIVATE_NOW;
+ gen_set_var(&var, -1, info);
return 0;
}
-
-static int radeon_init_disp_var (struct radeonfb_info *rinfo)
+static int radeon_init_disp_var (struct radeonfb_info *rinfo,
+ struct fb_var_screeninfo *var)
{
#ifndef MODULE
if (mode_option)
- fb_find_mode (&rinfo->disp.var, &rinfo->info, mode_option,
+ fb_find_mode (var, &rinfo->info, mode_option,
NULL, 0, NULL, 8);
else
#endif
- fb_find_mode (&rinfo->disp.var, &rinfo->info, "640x480-8@60",
+ if (rinfo->use_default_var)
+ /* We will use the modified default far */
+ *var = radeonfb_default_var;
+ else
+
+ fb_find_mode (var, &rinfo->info, "640x480-8@60",
NULL, 0, NULL, 0);
if (noaccel)
- rinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;
+ var->accel_flags &= ~FB_ACCELF_TEXT;
else
- rinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;
+ var->accel_flags |= FB_ACCELF_TEXT;
return 0;
}
-
-static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp)
-
-{
- int accel;
-
- accel = disp->var.accel_flags & FB_ACCELF_TEXT;
-
- disp->dispsw_data = NULL;
-
- disp->type = FB_TYPE_PACKED_PIXELS;
- disp->type_aux = 0;
- disp->ypanstep = 1;
- disp->ywrapstep = 0;
- disp->can_soft_blank = 1;
- disp->inverse = 0;
-
- rinfo->depth = disp->var.bits_per_pixel;
- switch (disp->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- disp->dispsw = &fbcon_cfb8;
- disp->visual = FB_VISUAL_PSEUDOCOLOR;
- disp->line_length = disp->var.xres_virtual;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = &rinfo->con_cmap.cfb16;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
- disp->line_length = disp->var.xres_virtual * 2;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 24:
- disp->dispsw = &fbcon_cfb24;
- disp->dispsw_data = &rinfo->con_cmap.cfb24;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
- disp->line_length = disp->var.xres_virtual * 4;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- disp->dispsw = &fbcon_cfb32;
- disp->dispsw_data = &rinfo->con_cmap.cfb32;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
- disp->line_length = disp->var.xres_virtual * 4;
- break;
-#endif
- default:
- printk ("radeonfb: setting fbcon_dummy renderer\n");
- disp->dispsw = &fbcon_dummy;
- }
-
- return;
-}
-
-static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
+static int radeon_do_maximize(struct radeonfb_info *rinfo,
struct fb_var_screeninfo *var,
struct fb_var_screeninfo *v,
int nom, int den)
@@ -1446,7 +1336,7 @@ static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
{-1, -1}
};
int i;
-
+
/* use highest possible virtual resolution */
if (v->xres_virtual == -1 && v->yres_virtual == -1) {
printk("radeonfb: using max available virtual resolution\n");
@@ -1490,105 +1380,55 @@ static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
return 0;
}
-
-/*
- * fb ops
- */
-
-static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
+static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
{
- struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
- struct display *disp;
-
- disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-
- memset (fix, 0, sizeof (struct fb_fix_screeninfo));
- strcpy (fix->id, rinfo->name);
-
- fix->smem_start = rinfo->fb_base_phys;
- fix->smem_len = rinfo->video_ram;
-
- fix->type = disp->type;
- fix->type_aux = disp->type_aux;
- fix->visual = disp->visual;
-
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
-
- fix->line_length = disp->line_length;
-
- fix->mmio_start = rinfo->mmio_base_phys;
- fix->mmio_len = RADEON_REGSIZE;
- if (noaccel)
- fix->accel = FB_ACCEL_NONE;
- else
- fix->accel = 40; /* XXX */
-
- return 0;
-}
-
-
-
-static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-
- *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
-
- return 0;
-}
-
-
-
-static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
- struct display *disp;
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info->par;
struct fb_var_screeninfo v;
- int nom, den, accel;
- unsigned chgvar = 0;
-
- disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-
- accel = var->accel_flags & FB_ACCELF_TEXT;
-
- if (con >= 0) {
- chgvar = ((disp->var.xres != var->xres) ||
- (disp->var.yres != var->yres) ||
- (disp->var.xres_virtual != var->xres_virtual) ||
- (disp->var.yres_virtual != var->yres_virtual) ||
- (disp->var.bits_per_pixel != var->bits_per_pixel) ||
- memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
- memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
- memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)));
- }
+ int nom, den;
memcpy (&v, var, sizeof (v));
switch (v.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
+ case 0 ... 8:
+ v.bits_per_pixel = 8;
+ break;
+ case 9 ... 16:
+ v.bits_per_pixel = 16;
+ break;
+ case 17 ... 24:
+#if 0 /* Doesn't seem to work */
+ v.bits_per_pixel = 24;
+ break;
+#endif
+ return -EINVAL;
+ case 25 ... 32:
+ v.bits_per_pixel = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (var_to_depth(&v)) {
case 8:
nom = den = 1;
- disp->line_length = v.xres_virtual;
- disp->visual = FB_VISUAL_PSEUDOCOLOR;
v.red.offset = v.green.offset = v.blue.offset = 0;
v.red.length = v.green.length = v.blue.length = 8;
v.transp.offset = v.transp.length = 0;
break;
-#endif
-
-#ifdef FBCON_HAS_CFB16
+ case 15:
+ nom = 2;
+ den = 1;
+ v.red.offset = 10;
+ v.green.offset = 5;
+ v.red.offset = 0;
+ v.red.length = v.green.length = v.blue.length = 5;
+ v.transp.offset = v.transp.length = 0;
+ break;
case 16:
nom = 2;
den = 1;
- disp->line_length = v.xres_virtual * 2;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
v.red.offset = 11;
v.green.offset = 5;
v.blue.offset = 0;
@@ -1596,28 +1436,19 @@ static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
v.green.length = 6;
v.blue.length = 5;
v.transp.offset = v.transp.length = 0;
- break;
-#endif
-
-#ifdef FBCON_HAS_CFB24
+ break;
case 24:
nom = 4;
den = 1;
- disp->line_length = v.xres_virtual * 3;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
v.red.offset = 16;
v.green.offset = 8;
v.blue.offset = 0;
v.red.length = v.blue.length = v.green.length = 8;
v.transp.offset = v.transp.length = 0;
break;
-#endif
-#ifdef FBCON_HAS_CFB32
case 32:
nom = 4;
den = 1;
- disp->line_length = v.xres_virtual * 4;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
v.red.offset = 16;
v.green.offset = 8;
v.blue.offset = 0;
@@ -1625,14 +1456,13 @@ static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
v.transp.offset = 24;
v.transp.length = 8;
break;
-#endif
default:
printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
var->xres, var->yres, var->bits_per_pixel);
return -EINVAL;
}
- if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
+ if (radeon_do_maximize(rinfo, var, &v, nom, den) < 0)
return -EINVAL;
if (v.xoffset < 0)
@@ -1649,179 +1479,144 @@ static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
v.red.msb_right = v.green.msb_right = v.blue.msb_right =
v.transp.offset = v.transp.length =
v.transp.msb_right = 0;
-
- switch (v.activate & FB_ACTIVATE_MASK) {
- case FB_ACTIVATE_TEST:
- return 0;
- case FB_ACTIVATE_NXTOPEN:
- case FB_ACTIVATE_NOW:
- break;
- default:
- return -EINVAL;
- }
-
- memcpy (&disp->var, &v, sizeof (v));
-
- if (chgvar) {
- radeon_set_dispsw(rinfo, disp);
- if (noaccel)
- disp->scrollmode = SCROLL_YREDRAW;
- else
- disp->scrollmode = 0;
-
- if (info && info->changevar)
- info->changevar(con);
- }
-
- radeon_load_video_mode (rinfo, &v);
-
- do_install_cmap(con, info);
-
+ if (noaccel)
+ v.accel_flags = 0;
+
+ memcpy(var, &v, sizeof(v));
+
return 0;
}
-
-static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
+static int radeonfb_pan_display (struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
- struct display *disp;
+
+ if ((var->xoffset + var->xres > var->xres_virtual)
+ || (var->yoffset + var->yres > var->yres_virtual))
+ return -EINVAL;
- disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-
- if (con == info->currcon) {
- int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
- return rc;
- } else if (disp->cmap.len)
- fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
- cmap, kspc ? 0 : 2);
-
+ if (rinfo->asleep)
+ return 0;
+
+ OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
+ * var->bits_per_pixel / 8) & ~7);
return 0;
}
-
-static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
+static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg, int con, struct fb_info *info)
{
struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
- struct display *disp;
- unsigned int cmap_len;
-
- disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-
- cmap_len = radeon_get_cmap_len (&disp->var);
- if (disp->cmap.len != cmap_len) {
- int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
- if (err)
- return err;
- }
-
- if (con == info->currcon) {
- int rc = fb_set_cmap (cmap, kspc, info);
- return rc;
- } else
- fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
-
- return 0;
-}
+ unsigned int tmp;
+ u32 value = 0;
+ int rc;
+
+ switch (cmd) {
+ /*
+ * TODO: set mirror accordingly for non-Mobility chipsets with 2 CRTC's
+ */
+ case FBIO_RADEON_SET_MIRROR:
+ switch (rinfo->arch) {
+ case RADEON_R100:
+ case RADEON_RV100:
+ case RADEON_R200:
+ case RADEON_RV200:
+ case RADEON_RV250:
+ case RADEON_R300:
+ return -EINVAL;
+ default:
+ /* RADEON M6, RADEON_M7, RADEON_M9 */
+ break;
+ }
+ rc = get_user(value, (__u32*)arg);
+ if (rc)
+ return rc;
-static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
- u32 offset, xoffset, yoffset;
-
- xoffset = (var->xoffset + 7) & ~7;
- yoffset = var->yoffset;
-
- if ((xoffset + var->xres > var->xres_virtual) || (yoffset+var->yres >
- var->yres_virtual))
- return -EINVAL;
-
- offset = ((yoffset * var->xres + xoffset) * var->bits_per_pixel) >> 6;
-
- OUTREG(CRTC_OFFSET, offset);
-
- return 0;
-}
+ if (value & 0x01) {
+ tmp = INREG(LVDS_GEN_CNTL);
+ tmp |= (LVDS_ON | LVDS_BLON);
+ } else {
+ tmp = INREG(LVDS_GEN_CNTL);
-static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, int con, struct fb_info *info)
-{
- return -EINVAL;
-}
+ tmp &= ~(LVDS_ON | LVDS_BLON);
+ }
+ OUTREG(LVDS_GEN_CNTL, tmp);
-static int radeonfb_switch (int con, struct fb_info *info)
-{
- struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
- struct display *disp;
- struct fb_cmap *cmap;
- int switchcon = 0;
-
- disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-
- if (info->currcon >= 0) {
- cmap = &(rinfo->currcon_display->cmap);
- if (cmap->len)
- fb_get_cmap (cmap, 1, radeon_getcolreg, info);
- }
-
- if ((disp->var.xres != rinfo->xres) ||
- (disp->var.yres != rinfo->yres) ||
- (disp->var.pixclock != rinfo->pixclock) ||
- (disp->var.bits_per_pixel != rinfo->depth))
- switchcon = 1;
-
- if (switchcon) {
- info->currcon = con;
- rinfo->currcon_display = disp;
- disp->var.activate = FB_ACTIVATE_NOW;
-
- radeonfb_set_var (&disp->var, con, info);
- radeon_set_dispsw (rinfo, disp);
- do_install_cmap(con, info);
- }
+ if (value & 0x02) {
+ tmp = INREG(CRTC_EXT_CNTL);
+ tmp |= CRTC_CRT_ON;
- /* XXX absurd hack for X to restore console */
- {
- OUTREGP(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl,
- CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
- OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid);
- }
+ mirror = 1;
+ } else {
+ tmp = INREG(CRTC_EXT_CNTL);
+ tmp &= ~CRTC_CRT_ON;
- return 0;
-}
+ mirror = 0;
+ }
+ OUTREG(CRTC_EXT_CNTL, tmp);
+ break;
+ case FBIO_RADEON_GET_MIRROR:
+ switch (rinfo->arch) {
+ case RADEON_R100:
+ case RADEON_RV100:
+ case RADEON_R200:
+ case RADEON_RV200:
+ case RADEON_RV250:
+ case RADEON_R300:
+ return -EINVAL;
+ default:
+ /* RADEON M6, RADEON_M7, RADEON_M9 */
+ break;
+ }
-static int radeonfb_updatevar (int con, struct fb_info *info)
-{
- int rc;
-
- rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
- con, info);
-
- return rc;
+ tmp = INREG(LVDS_GEN_CNTL);
+ if ((LVDS_ON | LVDS_BLON) & tmp)
+ value |= 0x01;
+
+ tmp = INREG(CRTC_EXT_CNTL);
+ if (CRTC_CRT_ON & tmp)
+ value |= 0x02;
+
+ return put_user(value, (__u32*)arg);
+ default:
+ return -EINVAL;
+ }
+
+ return -EINVAL;
}
+
static int radeonfb_blank (int blank, struct fb_info *info)
{
struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
u32 val = INREG(CRTC_EXT_CNTL);
+ u32 val2 = INREG(LVDS_GEN_CNTL);
+
+ if (rinfo->asleep)
+ return 0;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
+ set_backlight_enable(!blank);
+ return 0;
+ }
+#endif
/* reset it */
val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
CRTC_VSYNC_DIS);
-
+ val2 &= ~(LVDS_DISPLAY_DIS);
+
switch (blank) {
case VESA_NO_BLANKING:
break;
@@ -1834,56 +1629,31 @@ static int radeonfb_blank (int blank, struct fb_info *info)
case VESA_POWERDOWN:
val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
CRTC_HSYNC_DIS);
+ val2 |= (LVDS_DISPLAY_DIS);
break;
}
-
- OUTREG(CRTC_EXT_CNTL, val);
- return 0;
-}
-static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
-{
- int rc = 16; /* reasonable default */
-
- switch (var->bits_per_pixel) {
- case 8:
- rc = 256;
- break;
- default:
- rc = 32;
- break;
- }
-
- return rc;
-}
-
-
-
-static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info)
-{
- struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-
- if (regno > 255)
- return 1;
-
- *red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red;
- *green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
- *blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
- *transp = 0;
+ switch (rinfo->dviDisp_type) {
+ case MT_LCD:
+ OUTREG(LVDS_GEN_CNTL, val2);
+ break;
+ case MT_CRT:
+ default:
+ OUTREG(CRTC_EXT_CNTL, val);
+ break;
+ }
return 0;
-}
-
+}
static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp, struct fb_info *info)
+ unsigned blue, unsigned transp, struct fb_info *info)
{
struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
- u32 pindex;
-
+ u32 pindex, vclk_cntl;
+ unsigned int i;
+
if (regno > 255)
return 1;
@@ -1894,62 +1664,58 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
rinfo->palette[regno].green = green;
rinfo->palette[regno].blue = blue;
- /* init gamma for hicolor */
- if ((rinfo->depth > 8) && (regno == 0)) {
- int i;
-
- for (i=0; i<255; i++) {
- OUTREG(PALETTE_INDEX, i);
- OUTREG(PALETTE_DATA, (i << 16) | (i << 8) | i);
- }
- }
-
/* default */
pindex = regno;
-
- /* XXX actually bpp, fixme */
- if (rinfo->depth == 16)
- pindex = regno * 8;
-
- if (rinfo->depth == 16) {
- OUTREG(PALETTE_INDEX, pindex/2);
- OUTREG(PALETTE_DATA, (rinfo->palette[regno/2].red << 16) |
- (green << 8) | (rinfo->palette[regno/2].blue));
- green = rinfo->palette[regno/2].green;
- }
-
- if ((rinfo->depth == 8) || (regno < 32)) {
- OUTREG(PALETTE_INDEX, pindex);
- OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
- }
+ if (!rinfo->asleep) {
+ vclk_cntl = INPLL(VCLK_ECP_CNTL);
+ OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
+
+ if (rinfo->bpp == 16) {
+ pindex = regno * 8;
+
+ if (rinfo->depth == 16 && regno > 63)
+ return 1;
+ if (rinfo->depth == 15 && regno > 31)
+ return 1;
+
+ /* For 565, the green component is mixed one order below */
+ if (rinfo->depth == 16) {
+ OUTREG(PALETTE_INDEX, pindex>>1);
+ OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
+ (green << 8) | (rinfo->palette[regno>>1].blue));
+ green = rinfo->palette[regno<<1].green;
+ }
+ }
+
+ if (rinfo->depth != 16 || regno < 32) {
+ OUTREG(PALETTE_INDEX, pindex);
+ OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
+ }
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
- if (regno < 32) {
+ OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
+ }
+ if (regno < 16) {
switch (rinfo->depth) {
-#ifdef FBCON_HAS_CFB16
- case 16:
- rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) |
- regno;
- break;
-#endif
-#ifdef FBCON_HAS_CFB24
- case 24:
- rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32: {
- u32 i;
-
- i = (regno << 8) | regno;
- rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
- break;
- }
-#endif
+ case 15:
+ ((u16 *) (info->pseudo_palette))[regno] =
+ (regno << 10) | (regno << 5) | regno;
+ break;
+ case 16:
+ ((u16 *) (info->pseudo_palette))[regno] =
+ (regno << 11) | (regno << 6) | regno;
+ break;
+ case 24:
+ ((u32 *) (info->pseudo_palette))[regno] =
+ (regno << 16) | (regno << 8) | regno;
+ break;
+ case 32:
+ i = (regno << 8) | regno;
+ ((u32 *) (info->pseudo_palette))[regno] =
+ (i << 16) | i;
+ break;
}
}
-#endif
return 0;
}
@@ -1982,13 +1748,16 @@ static void radeon_save_state (struct radeonfb_info *rinfo,
save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
save->tmds_crc = INREG(TMDS_CRC);
+ save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
+ save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
}
-static void radeon_load_video_mode (struct radeonfb_info *rinfo,
- struct fb_var_screeninfo *mode)
+static int radeonfb_set_par (struct fb_info *info)
{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *)info->par;
+ struct fb_var_screeninfo *mode = &info->var;
struct radeon_regs newmode;
int hTotal, vTotal, hSyncStart, hSyncEnd,
hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
@@ -2002,9 +1771,12 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
int min_bits, format = 0;
int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
int primary_mon = PRIMARY_MONITOR(rinfo);
+ int depth = var_to_depth(mode);
rinfo->xres = mode->xres;
rinfo->yres = mode->yres;
+ rinfo->xres_virtual = mode->xres_virtual;
+ rinfo->yres_virtual = mode->yres_virtual;
rinfo->pixclock = mode->pixclock;
hSyncStart = mode->xres + mode->right_margin;
@@ -2021,13 +1793,13 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
if (rinfo->panel_yres < mode->yres)
rinfo->yres = mode->yres = rinfo->panel_yres;
- hTotal = mode->xres + rinfo->hblank + mode->left_margin;
- hSyncStart = mode->xres + rinfo->hOver_plus + mode->right_margin;
- hSyncEnd = hSyncStart + rinfo->hOver_plus + mode->hsync_len;
+ hTotal = mode->xres + rinfo->hblank;
+ hSyncStart = mode->xres + rinfo->hOver_plus;
+ hSyncEnd = hSyncStart + rinfo->hSync_width;
- vTotal = mode->yres + rinfo->vblank + mode->upper_margin;
- vSyncStart = mode->yres + rinfo->vOver_plus + mode->lower_margin;
- vSyncEnd = vSyncStart + rinfo->vSync_width + mode->vsync_len;
+ vTotal = mode->yres + rinfo->vblank;
+ vSyncStart = mode->yres + rinfo->vOver_plus;
+ vSyncEnd = vSyncStart + rinfo->vSync_width;
}
sync = mode->sync;
@@ -2045,7 +1817,7 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
hsync_wid = 1;
else if (hsync_wid > 0x3f) /* max */
hsync_wid = 0x3f;
- vsync_wid = mode->vsync_len;
+
if (vsync_wid == 0)
vsync_wid = 1;
else if (vsync_wid > 0x1f) /* max */
@@ -2056,24 +1828,8 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
- switch (mode->bits_per_pixel) {
- case 8:
- format = DST_8BPP;
- bytpp = 1;
- break;
- case 16:
- format = DST_16BPP;
- bytpp = 2;
- break;
- case 24:
- format = DST_24BPP;
- bytpp = 3;
- break;
- case 32:
- format = DST_32BPP;
- bytpp = 4;
- break;
- }
+ format = radeon_get_dstbpp(depth);
+ bytpp = mode->bits_per_pixel >> 3;
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
hsync_fudge = hsync_fudge_fp[format-1];
@@ -2087,6 +1843,9 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
+ if (mirror)
+ newmode.crtc_ext_cntl |= CRTC_CRT_ON;
+
newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
CRTC_INTERLACE_EN);
} else {
@@ -2097,7 +1856,7 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
DAC_8BIT_EN;
- newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0xffff) |
+ newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
(((mode->xres / 8) - 1) << 16));
newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
@@ -2109,7 +1868,7 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
(vsync_wid << 16) | (v_sync_pol << 23));
- newmode.crtc_pitch = (mode->xres >> 3);
+ newmode.crtc_pitch = (mode->xres_virtual >> 3);
newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
#if defined(__BIG_ENDIAN)
@@ -2125,8 +1884,8 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
}
#endif
- rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
- & ~(0x3f)) / 64;
+ rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
+ & ~(0x3f)) / 64;
RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n",
newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
@@ -2137,9 +1896,7 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
newmode.yres = mode->yres;
rinfo->bpp = mode->bits_per_pixel;
-
- rinfo->hack_crtc_ext_cntl = newmode.crtc_ext_cntl;
- rinfo->hack_crtc_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
+ rinfo->depth = depth;
if (freq > rinfo->pll.ppll_max)
freq = rinfo->pll.ppll_max;
@@ -2176,6 +1933,8 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
newmode.ppll_ref_div = rinfo->pll.ref_div;
newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
}
+ newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
+
RTRACE("post div = 0x%x\n", rinfo->post_div);
RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
@@ -2204,7 +1963,7 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
if ((ron + rinfo->ram.rloop) >= roff) {
printk("radeonfb: error ron out of range\n");
- return;
+ return -EINVAL;
}
newmode.dda_config = (xclk_per_trans_precise |
@@ -2213,48 +1972,43 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
newmode.dda_on_off = (ron << 16) | roff;
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
- int hRatio, vRatio;
-
- if ((rinfo->panel_xres == 0) || (rinfo->panel_yres == 0)) {
- hRatio = vRatio = 1;
- } else {
- if (mode->xres > rinfo->panel_xres)
- mode->xres = rinfo->panel_xres;
- if (mode->yres > rinfo->panel_yres)
- mode->yres = rinfo->panel_yres;
-
- hRatio = mode->xres / rinfo->panel_xres;
- vRatio = mode->yres / rinfo->panel_yres;
- }
-
- if (hRatio == 1) {
- newmode.fp_horz_stretch =
- rinfo->init_state.fp_horz_stretch;
- newmode.fp_horz_stretch &= ~(HORZ_STRETCH_BLEND |
- HORZ_STRETCH_ENABLE);
- } else {
- newmode.fp_horz_stretch =
- ((((unsigned long)(hRatio * HORZ_STRETCH_RATIO_MAX +
- (int)0.5)) & HORZ_STRETCH_RATIO_MASK)) |
- (rinfo->init_state.fp_horz_stretch &
- (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
- HORZ_AUTO_RATIO_INC));
+ unsigned int hRatio, vRatio;
+
+ /* We force the pixel clock to be always enabled. Allowing it
+ * to be power managed during blanking would save power, but has
+ * nasty interactions with the 2D engine & sleep code that haven't
+ * been solved yet. --BenH
+ */
+ newmode.vclk_ecp_cntl &= ~PIXCLK_DAC_ALWAYS_ONb;
+
+ if (mode->xres > rinfo->panel_xres)
+ mode->xres = rinfo->panel_xres;
+ if (mode->yres > rinfo->panel_yres)
+ mode->yres = rinfo->panel_yres;
+
+ newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
+ << HORZ_PANEL_SHIFT);
+ newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
+ << VERT_PANEL_SHIFT);
+
+ if (mode->xres != rinfo->panel_xres) {
+ hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
+ rinfo->panel_xres);
+ newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
+ (newmode.fp_horz_stretch &
+ (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
+ HORZ_AUTO_RATIO_INC)));
newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
HORZ_STRETCH_ENABLE);
}
newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
- if (vRatio == 1) {
- newmode.fp_vert_stretch =
- rinfo->init_state.fp_vert_stretch;
- newmode.fp_vert_stretch &= ~(VERT_STRETCH_BLEND |
- VERT_STRETCH_ENABLE);
- } else {
- newmode.fp_vert_stretch =
- ((((unsigned long)(vRatio * VERT_STRETCH_RATIO_MAX +
- (int)0.5)) & VERT_STRETCH_RATIO_MASK)) |
- (rinfo->init_state.fp_vert_stretch &
- (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED));
+ if (mode->yres != rinfo->panel_yres) {
+ vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
+ rinfo->panel_yres);
+ newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
+ (newmode.fp_vert_stretch &
+ (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
VERT_STRETCH_ENABLE);
}
@@ -2269,14 +2023,14 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
FP_USE_SHADOW_EN |
FP_CRTC_USE_SHADOW_VEND |
FP_CRT_SYNC_ALT));
+
newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
FP_CRTC_DONT_SHADOW_HEND);
newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
newmode.tmds_crc = rinfo->init_state.tmds_crc;
-
- newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
+ newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
if (primary_mon == MT_LCD) {
newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
@@ -2284,22 +2038,41 @@ static void radeon_load_video_mode (struct radeonfb_info *rinfo,
} else {
/* DFP */
newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
+ newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST |
+ ICHCSEL | TMDS_PLL_EN) &
+ ~(TMDS_PLLRST);
+ newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
}
- newmode.fp_crtc_h_total_disp =
- rinfo->init_state.fp_crtc_h_total_disp;
- newmode.fp_crtc_v_total_disp =
- rinfo->init_state.fp_crtc_v_total_disp;
- newmode.fp_h_sync_strt_wid =
- rinfo->init_state.fp_h_sync_strt_wid;
- newmode.fp_v_sync_strt_wid =
- rinfo->init_state.fp_v_sync_strt_wid;
+ newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |
+ (((mode->xres / 8) - 1) << 16));
+ newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |
+ ((mode->yres - 1) << 16);
+ newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |
+ (hsync_wid << 16) | (h_sync_pol << 23));
+ newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |
+ (vsync_wid << 16) | (v_sync_pol << 23));
}
/* do it! */
- radeon_write_mode (rinfo, &newmode);
+ if (!rinfo->asleep) {
+ radeon_write_mode (rinfo, &newmode);
+ /* (re)initialize the engine */
+ if (!noaccel)
+ radeon_engine_init (rinfo);
+
+ }
+ /* Update fix */
+ info->fix.line_length = rinfo->pitch*64;
+ info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+
+#ifdef CONFIG_BOOTX_TEXT
+ /* Update debug text engine */
+ btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
+ rinfo->depth, rinfo->pitch*64);
+#endif
- return;
+ return 0;
}
@@ -2309,11 +2082,16 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
int i;
int primary_mon = PRIMARY_MONITOR(rinfo);
- /* blank screen */
- OUTREG8(CRTC_EXT_CNTL + 1, 4);
+ radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);
- for (i=0; i<9; i++)
- OUTREG(common_regs[i].reg, common_regs[i].val);
+
+ if (rinfo->arch == RADEON_M6) {
+ for (i=0; i<8; i++)
+ OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
+ } else {
+ for (i=0; i<9; i++)
+ OUTREG(common_regs[i].reg, common_regs[i].val);
+ }
OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
@@ -2326,16 +2104,6 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
OUTREG(CRTC_OFFSET, 0);
OUTREG(CRTC_OFFSET_CNTL, 0);
OUTREG(CRTC_PITCH, mode->crtc_pitch);
-#if 1
- printk("CRTC_H_TOTAL_DISP = 0x%x, H_SYNC = 0x%x\n",
- mode->crtc_h_total_disp, mode->crtc_h_sync_strt_wid);
- printk("CRTC_V_TOTAL_DISP = 0x%x, V_SYNC = 0x%x\n",
- mode->crtc_v_total_disp, mode->crtc_v_sync_strt_wid);
- printk("PPLL_DIV_3 = 0x%x, PPLL_REF_DIV = 0x%x\n",
- mode->ppll_div_3, mode->ppll_ref_div);
- printk("DDA_CONFIG = 0x%x, DDA_ON_OFF = 0x%x\n",
- mode->dda_config, mode->dda_on_off);
-#endif
#if defined(__BIG_ENDIAN)
OUTREG(SURFACE_CNTL, mode->surface_cntl);
@@ -2367,131 +2135,1017 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
- OUTREG(DDA_CONFIG, mode->dda_config);
- OUTREG(DDA_ON_OFF, mode->dda_on_off);
+// OUTREG(DDA_CONFIG, mode->dda_config);
+// OUTREG(DDA_ON_OFF, mode->dda_on_off);
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
- OUTREG(TMDS_CRC, mode->tmds_crc);
OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
+ OUTREG(TMDS_CRC, mode->tmds_crc);
+ OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
if (primary_mon == MT_LCD) {
unsigned int tmp = INREG(LVDS_GEN_CNTL);
+ mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
+ mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
+
if ((tmp & (LVDS_ON | LVDS_BLON)) ==
- (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)))
- OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
- } else {
- /* DVI */
- if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
- udelay(1000);
+ (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
} else {
- OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
- LVDS_BLON);
- udelay(1000);
- OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+ if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
+ udelay(1000);
+ OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+ } else {
+ OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
+ LVDS_BLON);
+ udelay(1000);
+ OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+ }
}
}
}
- /* unblank screen */
- OUTREG8(CRTC_EXT_CNTL + 1, 0);
+ radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);
+ OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
+
return;
}
+static struct fb_ops radeonfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = radeonfb_check_var,
+ .fb_set_par = radeonfb_set_par,
+ .fb_setcolreg = radeonfb_setcolreg,
+ .fb_pan_display = radeonfb_pan_display,
+ .fb_blank = radeonfb_blank,
+ .fb_ioctl = radeonfb_ioctl,
+#if 0
+ .fb_fillrect = radeonfb_fillrect,
+ .fb_copyarea = radeonfb_copyarea,
+ .fb_imageblit = radeonfb_imageblit,
+ .fb_rasterimg = radeonfb_rasterimg,
+#else
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+#endif
+};
+
+
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
+{
+ struct fb_info *info;
+
+ info = &rinfo->info;
+
+ // XXX ???
+ strncpy (info->modename, rinfo->name, sizeof(info->modename));
+
+ info->currcon = -1;
+ info->par = rinfo;
+ info->disp = &rinfo->disp;
+ info->pseudo_palette = rinfo->pseudo_palette;
+ info->node = NODEV;
+ info->flags = FBINFO_FLAG_DEFAULT;
+ info->fbops = &radeonfb_ops;
+ info->display_fg = NULL;
+ info->screen_base = (char *)rinfo->fb_base;
+
+ /* Fill fix common fields */
+ strncpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
+ info->fix.id[sizeof(info->fix.id) - 1] = '\0';
+ info->fix.smem_start = rinfo->fb_base_phys;
+ info->fix.smem_len = rinfo->video_ram;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ info->fix.xpanstep = 8;
+ info->fix.ypanstep = 1;
+ info->fix.ywrapstep = 0;
+ info->fix.type_aux = 0;
+ info->fix.mmio_start = rinfo->mmio_base_phys;
+ info->fix.mmio_len = RADEON_REGSIZE;
+ if (noaccel)
+ info->fix.accel = FB_ACCEL_NONE;
+ else
+ info->fix.accel = FB_ACCEL_ATI_RADEON;
+
+ if (radeon_init_disp (rinfo) < 0)
+ return -1;
+
+ return 0;
+}
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+
+/* TODO: Dbl check these tables, we don't go up to full ON backlight
+ * in these, possibly because we noticed MacOS doesn't, but I'd prefer
+ * having some more official numbers from ATI
+ */
+static int backlight_conv_m6[] = {
+ 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
+ 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
+};
+static int backlight_conv_m7[] = {
+ 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
+ 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
+};
+
+#define BACKLIGHT_LVDS_OFF
+#undef BACKLIGHT_DAC_OFF
+
+/* We turn off the LCD completely instead of just dimming the backlight.
+ * This provides some greater power saving and the display is useless
+ * without backlight anyway.
+ */
+
+static int radeon_set_backlight_enable(int on, int level, void *data)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
+ unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
+ int* conv_table;
+
+ if (rinfo->arch == RADEON_M7)
+ conv_table = backlight_conv_m7;
+ else
+ conv_table = backlight_conv_m6;
+
+ lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
+ if (on && (level > BACKLIGHT_OFF)) {
+ lvds_gen_cntl |= LVDS_DIGON;
+ if (!lvds_gen_cntl & LVDS_ON) {
+ lvds_gen_cntl &= ~LVDS_BLON;
+ OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+ (void)INREG(LVDS_GEN_CNTL);
+ mdelay(10);
+ lvds_gen_cntl |= LVDS_BLON;
+ OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+ }
+ lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+ lvds_gen_cntl |= (conv_table[level] <<
+ LVDS_BL_MOD_LEVEL_SHIFT);
+ lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
+ lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
+ } else {
+ lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+ lvds_gen_cntl |= (conv_table[0] <<
+ LVDS_BL_MOD_LEVEL_SHIFT);
+ lvds_gen_cntl |= LVDS_DISPLAY_DIS;
+ OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+ udelay(10);
+ lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
+ }
+
+ OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+ rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
+ rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
+
+ return 0;
+}
+
+static int radeon_set_backlight_level(int level, void *data)
+{
+ return radeon_set_backlight_enable(1, level, data);
+}
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
+
+#ifdef CONFIG_PMAC_PBOOK
+
+static u32 dbg_clk;
/*
- * text console acceleration
+ * Radeon M6 Power Management code. This code currently only supports
+ * the mobile chips, it's based from some informations provided by ATI
+ * along with hours of tracing of MacOS drivers
*/
+
+static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
+{
+ rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
+ rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
+ rinfo->save_regs[2] = INPLL(MCLK_CNTL);
+ rinfo->save_regs[3] = INPLL(SCLK_CNTL);
+ rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
+ rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
+ rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
+ rinfo->save_regs[7] = INPLL(MCLK_MISC);
+ rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
+
+ rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
+ rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
+ rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
+ rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
+ rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
+ rinfo->save_regs[14] = INREG(BUS_CNTL1);
+ rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
+ rinfo->save_regs[16] = INREG(AGP_CNTL);
+ rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+ rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+ rinfo->save_regs[19] = INREG(GPIOPAD_A);
+ rinfo->save_regs[20] = INREG(GPIOPAD_EN);
+ rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
+ rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
+ rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
+ rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
+ rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
+ rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
+ rinfo->save_regs[27] = INREG(GPIO_MONID);
+ rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
+
+ rinfo->save_regs[29] = INREG(SURFACE_CNTL);
+ rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
+ rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
+ rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
+ rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
+}
+static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
+{
+ OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
+
+ OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
+ OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
+ OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
+ OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
+ OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
+ OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
+ OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
+ OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
+
+ OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+ OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
+ OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
+ OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
+ OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
+ OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
+ OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
+ OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+ OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
+ OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
+
+ // wait VBL before that one ?
+ OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
+
+ OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
+ OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
+ OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
+ OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
+ OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
+ OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
+ OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
+ OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
+ OUTREG(GPIO_MONID, rinfo->save_regs[27]);
+ OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
+}
-static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
- int dsty, int dstx, int height, int width)
+static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
+{
+ OUTREG(GPIOPAD_MASK, 0x0001ffff);
+ OUTREG(GPIOPAD_EN, 0x00000400);
+ OUTREG(GPIOPAD_A, 0x00000000);
+ OUTREG(ZV_LCDPAD_MASK, 0x00000000);
+ OUTREG(ZV_LCDPAD_EN, 0x00000000);
+ OUTREG(ZV_LCDPAD_A, 0x00000000);
+ OUTREG(GPIO_VGA_DDC, 0x00030000);
+ OUTREG(GPIO_DVI_DDC, 0x00000000);
+ OUTREG(GPIO_MONID, 0x00030000);
+ OUTREG(GPIO_CRT2_DDC, 0x00000000);
+}
+
+static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
{
- struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
- u32 dp_cntl = DST_LAST_PEL;
-
- srcx *= fontwidth(p);
- srcy *= fontheight(p);
- dstx *= fontwidth(p);
- dsty *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
-
- if (srcy < dsty) {
- srcy += height - 1;
- dsty += height - 1;
- } else
- dp_cntl |= DST_Y_TOP_TO_BOTTOM;
-
- if (srcx < dstx) {
- srcx += width - 1;
- dstx += width - 1;
- } else
- dp_cntl |= DST_X_LEFT_TO_RIGHT;
-
- radeon_fifo_wait(6);
- OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
- GMC_BRUSH_NONE |
- GMC_SRC_DATATYPE_COLOR |
- ROP3_S |
- DP_SRC_SOURCE_MEMORY));
- OUTREG(DP_WRITE_MSK, 0xffffffff);
- OUTREG(DP_CNTL, dp_cntl);
- OUTREG(SRC_Y_X, (srcy << 16) | srcx);
- OUTREG(DST_Y_X, (dsty << 16) | dstx);
- OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
+//
+// u32 reg;
+//
+// OUTPLL(P2PLL_REF_DIV, 0x0c);
+//
+// .../... figure out what macos does here
}
+static void radeon_pm_low_current(struct radeonfb_info *rinfo)
+{
+ u32 reg;
+ reg = INREG(BUS_CNTL1);
+ reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
+ reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
+ OUTREG(BUS_CNTL1, reg);
+
+ reg = INPLL(PLL_PWRMGT_CNTL);
+ reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
+ PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
+ reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
+ reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
+ OUTPLL(PLL_PWRMGT_CNTL, reg);
+
+// reg = INPLL(TV_PLL_CNTL1);
+// reg |= TV_PLL_CNTL1__TVPLL_RESET | TV_PLL_CNTL1__TVPLL_SLEEP;
+// OUTPLL(TV_PLL_CNTL1, reg);
+
+ reg = INREG(TV_DAC_CNTL);
+ reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
+ reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
+ TV_DAC_CNTL_BDACPD |
+ (8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
+ OUTREG(TV_DAC_CNTL, reg);
+
+ reg = INREG(TMDS_TRANSMITTER_CNTL);
+ reg &= ~(TMDS_PLL_EN |TMDS_PLLRST);
+ OUTREG(TMDS_TRANSMITTER_CNTL, reg);
+
+// lvds_pll_cntl = regr32(g, LVDS_PLL_CNTL);
+// lvds_pll_cntl &= ~LVDS_PLL_CNTL__LVDS_PLL_EN;
+// lvds_pll_cntl |= LVDS_PLL_CNTL__LVDS_PLL_RESET;
+// regw32(g, LVDS_PLL_CNTL, lvds_pll_cntl);
+
+ reg = INREG(DAC_CNTL);
+ reg &= ~DAC_CMP_EN;
+ OUTREG(DAC_CNTL, reg);
+
+ reg = INREG(DAC_CNTL2);
+ reg &= ~DAC2_CMP_EN;
+ OUTREG(DAC_CNTL2, reg);
+
+ reg = INREG(TV_DAC_CNTL);
+ reg &= ~TV_DAC_CNTL_DETECT;
+ OUTREG(TV_DAC_CNTL, reg);
+}
-static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
- int srcy, int srcx, int height, int width)
+static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
{
- struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
- u32 clr;
+ /* This code is disabled. It does what is in the pm_init
+ * function of the MacOS driver code ATI sent me. However,
+ * it doesn't fix my sleep problem, and is causing other issues
+ * on wakeup (bascially the machine dying when switching consoles
+ * I haven't had time to investigate this yet
+ */
+#if 0
+ u32 disp_misc_cntl;
+ u32 disp_pwr_man;
+ u32 temp;
- clr = attr_bgcol_ec(p, conp);
- clr |= (clr << 8);
- clr |= (clr << 16);
+ // set SPLL, MPLL, PPLL, P2PLL, TVPLL, SCLK, MCLK, PCLK, P2CLK,
+ // TCLK and TEST_MODE to 0
+ temp = INPLL(CLK_PWRMGT_CNTL);
+ OUTPLL(CLK_PWRMGT_CNTL , temp & ~0xc00002ff);
- srcx *= fontwidth(p);
- srcy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
+ // Turn on Power Management
+ temp = INPLL(CLK_PWRMGT_CNTL);
+ OUTPLL(CLK_PWRMGT_CNTL , temp | 0x00000400);
- radeon_fifo_wait(6);
- OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
- GMC_BRUSH_SOLID_COLOR |
- GMC_SRC_DATATYPE_COLOR |
- ROP3_P));
- OUTREG(DP_BRUSH_FRGD_CLR, clr);
- OUTREG(DP_WRITE_MSK, 0xffffffff);
- OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
- OUTREG(DST_Y_X, (srcy << 16) | srcx);
- OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
+ // Turn off display clock if using mobile chips
+ temp = INPLL(CLK_PWRMGT_CNTL);
+ OUTREG(CLK_PWRMGT_CNTL , temp | 0x00100000);
+
+ // Force PIXCLK_ALWAYS_ON and PIXCLK_DAC_ALWAYS_ON
+ temp = INPLL(VCLK_ECP_CNTL);
+ OUTPLL(VCLK_ECP_CNTL, temp & ~0x000000c0);
+
+ // Force ECP_FORCE_ON to 1
+ temp = INPLL(VCLK_ECP_CNTL);
+ OUTPLL(VCLK_ECP_CNTL, temp | 0x00040000);
+
+ // Force PIXCLK_BLEND_ALWAYS_ON and PIXCLK_GV_ALWAYS_ON
+ temp = INPLL(PIXCLKS_CNTL);
+ OUTPLL(PIXCLKS_CNTL, temp & ~0x00001800);
+
+ // Forcing SCLK_CNTL to ON
+ OUTPLL(SCLK_CNTL, (INPLL(SCLK_CNTL)& 0x00000007) | 0xffff8000 );
+
+ // Set PM control over XTALIN pad
+ temp = INPLL(CLK_PIN_CNTL);
+ OUTPLL(CLK_PIN_CNTL, temp | 0x00080000);
+
+ // Force MCLK and YCLK and MC as dynamic
+ temp = INPLL(MCLK_CNTL);
+ OUTPLL(MCLK_CNTL, temp & 0xffeaffff);
+
+ // PLL_TURNOFF
+ temp = INPLL(PLL_PWRMGT_CNTL);
+ OUTPLL(PLL_PWRMGT_CNTL, temp | 0x0000001f);
+
+ // set MOBILE_SU to 1 if M6 or DDR64 is detected
+ temp = INPLL(PLL_PWRMGT_CNTL);
+ OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00010000);
+
+ // select PM access mode (PM_MODE_SEL) (use ACPI mode)
+// temp = INPLL(PLL_PWRMGT_CNTL);
+// OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00002000);
+ temp = INPLL(PLL_PWRMGT_CNTL);
+ OUTPLL(PLL_PWRMGT_CNTL, temp & ~0x00002000);
+
+ // set DISP_MISC_CNTL register
+ disp_misc_cntl = INREG(DISP_MISC_CNTL);
+ disp_misc_cntl &= ~( DISP_MISC_CNTL_SOFT_RESET_GRPH_PP |
+ DISP_MISC_CNTL_SOFT_RESET_SUBPIC_PP |
+ DISP_MISC_CNTL_SOFT_RESET_OV0_PP |
+ DISP_MISC_CNTL_SOFT_RESET_GRPH_SCLK |
+ DISP_MISC_CNTL_SOFT_RESET_SUBPIC_SCLK |
+ DISP_MISC_CNTL_SOFT_RESET_OV0_SCLK |
+ DISP_MISC_CNTL_SOFT_RESET_GRPH2_PP |
+ DISP_MISC_CNTL_SOFT_RESET_GRPH2_SCLK |
+ DISP_MISC_CNTL_SOFT_RESET_LVDS |
+ DISP_MISC_CNTL_SOFT_RESET_TMDS |
+ DISP_MISC_CNTL_SOFT_RESET_DIG_TMDS |
+ DISP_MISC_CNTL_SOFT_RESET_TV);
+ OUTREG(DISP_MISC_CNTL, disp_misc_cntl);
+
+ // set DISP_PWR_MAN register
+ disp_pwr_man = INREG(DISP_PWR_MAN);
+ // clau - 9.29.2000 - changes made to bit23:18 to set to 1 as requested by George
+ disp_pwr_man |= (DISP_PWR_MAN_DIG_TMDS_ENABLE_RST |
+ DISP_PWR_MAN_TV_ENABLE_RST |
+ // DISP_PWR_MAN_AUTO_PWRUP_EN |
+ DISP_PWR_MAN_DISP_D3_GRPH_RST |
+ DISP_PWR_MAN_DISP_D3_SUBPIC_RST |
+ DISP_PWR_MAN_DISP_D3_OV0_RST |
+ DISP_PWR_MAN_DISP_D1D2_GRPH_RST |
+ DISP_PWR_MAN_DISP_D1D2_SUBPIC_RST |
+ DISP_PWR_MAN_DISP_D1D2_OV0_RST);
+ disp_pwr_man &= ~(DISP_PWR_MAN_DISP_PWR_MAN_D3_CRTC_EN |
+ DISP_PWR_MAN_DISP2_PWR_MAN_D3_CRTC2_EN|
+ DISP_PWR_MAN_DISP_D3_RST |
+ DISP_PWR_MAN_DISP_D3_REG_RST);
+ OUTREG(DISP_PWR_MAN, disp_pwr_man);
+
+ // clau - 10.24.2000
+ // - add in setting for BUS_CNTL1 b27:26 = 0x01 and b31 = 0x1
+ // - add in setting for AGP_CNTL b7:0 = 0x20
+ // - add in setting for DVI_DDC_DATA_OUT_EN b17:16 = 0x0
+
+ // the following settings (two lines) are applied at a later part of this function, only on mobile platform
+ // requres -mobile flag
+ OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & 0xf3ffffff) | 0x04000000);
+ OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | 0x80000000);
+ OUTREG(AGP_CNTL, (INREG(AGP_CNTL) & 0xffffff00) | 0x20);
+ OUTREG(GPIO_DVI_DDC, INREG(GPIO_DVI_DDC) & 0xfffcffff);
+
+ // yulee - 12.12.2000
+ // A12 only
+ // EN_MCLK_TRISTATE_IN_SUSPEND@MCLK_MISC = 1
+ // ACCESS_REGS_IN_SUSPEND@CLK_PIN_CNTL = 0
+ // only on mobile platform
+ OUTPLL(MCLK_MISC, INPLL(MCLK_MISC) | 0x00040000 );
+
+ // yulee -12.12.2000
+ // AGPCLK_VALID@BUS_CNTL1 = 1
+ // MOBILE_PLATFORM_SEL@BUS_CNTL1 = 01
+ // CRTC_STEREO_SYNC_OUT_EN@CRTC_OFFSET_CNTL = 0
+ // CG_CLK_TO_OUTPIN@CLK_PIN_CNTL = 0
+ // only on mobile platform
+ OUTPLL(CLK_PIN_CNTL, INPLL(CLK_PIN_CNTL ) & 0xFFFFF7FF );
+ OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1 ) & 0xF3FFFFFF) | 0x84000000 );
+ OUTREG(CRTC_OFFSET_CNTL, INREG(CRTC_OFFSET_CNTL ) & 0xFFEFFFFF );
+
+ mdelay(100);
+#endif
+
+ /* Disable CRTCs */
+ OUTREG(CRTC_GEN_CNTL, (INREG(CRTC_GEN_CNTL) & ~CRTC_EN) | CRTC_DISP_REQ_EN_B);
+ OUTREG(CRTC2_GEN_CNTL, (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
+ (void)INREG(CRTC2_GEN_CNTL);
+ mdelay(17);
+}
+
+static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
+{
+ u16 pwr_cmd;
+
+ if (!rinfo->pm_reg)
+ return;
+
+ /* Set the chip into appropriate suspend mode (we use D2,
+ * D3 would require a compete re-initialization of the chip,
+ * including PCI config registers, clocks, AGP conf, ...)
+ */
+ if (suspend) {
+ /* According to ATI, we should program V2CLK here, I have
+ * to verify what's up exactly
+ */
+ /* Save some registers */
+ radeon_pm_save_regs(rinfo);
+
+ /* Check that on M7 too, might work might not. M7 may also
+ * need explicit enabling of PM
+ */
+ if (rinfo->arch == RADEON_M6) {
+ /* Program V2CLK */
+ radeon_pm_program_v2clk(rinfo);
+
+ /* Disable IO PADs */
+ radeon_pm_disable_iopad(rinfo);
+
+ /* Set low current */
+ radeon_pm_low_current(rinfo);
+
+ /* Prepare chip for power management */
+ radeon_pm_setup_for_suspend(rinfo);
+
+ /* Reset the MDLL */
+ OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) | MCKOA_RESET);
+ (void)INPLL(MDLL_RDCKA);
+ OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
+ (void)INPLL(MDLL_RDCKA);
+ }
+
+ /* Switch PCI power managment to D2. */
+ for (;;) {
+ pci_read_config_word(
+ rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+ &pwr_cmd);
+ if (pwr_cmd & 2)
+ break;
+ pci_write_config_word(
+ rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+ (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
+ mdelay(500);
+ }
+ } else {
+ /* Switch back PCI powermanagment to D0 */
+ mdelay(200);
+ pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
+ mdelay(500);
+
+ dbg_clk = INPLL(1);
+
+ /* Do we need that on M7 ? */
+ if (rinfo->arch == RADEON_M6) {
+ /* Restore the MDLL */
+ OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
+ (void)INPLL(MDLL_CKO);
+ }
+
+ /* Restore some registers */
+ radeon_pm_restore_regs(rinfo);
+ }
+}
+
+/*
+ * Save the contents of the framebuffer when we go to sleep,
+ * and restore it when we wake up again.
+ */
+
+int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+ struct radeonfb_info *rinfo;
+
+ for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
+ struct fb_fix_screeninfo fix;
+ int nb;
+ struct display *disp;
+
+ disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon];
+
+ switch (rinfo->arch) {
+ case RADEON_M6:
+ case RADEON_M7:
+ case RADEON_M9:
+ break;
+ default:
+ return PBOOK_SLEEP_REFUSE;
+ }
+
+ radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
+ nb = fb_display[fg_console].var.yres * fix.line_length;
+
+ switch (when) {
+ case PBOOK_SLEEP_NOW:
+ acquire_console_sem();
+ disp->dispsw = &fbcon_dummy;
+
+ if (!noaccel) {
+ /* Make sure engine is reset */
+ radeon_engine_reset();
+ radeon_engine_idle();
+ }
+
+ /* Blank display and LCD */
+ radeonfb_blank(VESA_POWERDOWN+1,
+ (struct fb_info *)rinfo);
+
+ /* Sleep */
+ rinfo->asleep = 1;
+ radeon_set_suspend(rinfo, 1);
+ release_console_sem();
+
+ break;
+ case PBOOK_WAKE:
+ acquire_console_sem();
+ /* Wakeup */
+ radeon_set_suspend(rinfo, 0);
+
+ if (!noaccel)
+ radeon_engine_init(rinfo);
+ rinfo->asleep = 0;
+ radeon_set_dispsw(rinfo, disp);
+ radeon_load_video_mode(rinfo, &disp->var);
+ do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon,
+ (struct fb_info *)rinfo);
+
+ radeonfb_blank(0, (struct fb_info *)rinfo);
+ release_console_sem();
+ printk("CLK_PIN_CNTL on wakeup was: %08x\n", dbg_clk);
+ break;
+ }
+ }
+
+ return PBOOK_SLEEP_OK;
}
+#endif /* CONFIG_PMAC_PBOOK */
+static int radeonfb_pci_register (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct radeonfb_info *rinfo;
+ struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
+ u32 tmp;
+
+ RTRACE("radeonfb_pci_register BEGIN\n");
+ /* Enable device in PCI config */
+ if (pci_enable_device(pdev) != 0) {
+ printk(KERN_ERR "radeonfb: Cannot enable PCI device\n");
+ return -ENODEV;
+ }
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_radeon8 = {
- .setup = fbcon_cfb8_setup,
- .bmove = fbcon_radeon_bmove,
- .clear = fbcon_radeon_clear,
- .putc = fbcon_cfb8_putc,
- .putcs = fbcon_cfb8_putcs,
- .revc = fbcon_cfb8_revc,
- .clear_margins = fbcon_cfb8_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
+ if (!rinfo) {
+ printk ("radeonfb: could not allocate memory\n");
+ return -ENODEV;
+ }
+
+ memset (rinfo, 0, sizeof (struct radeonfb_info));
+ //info = &rinfo->info;
+ rinfo->pdev = pdev;
+ strcpy(rinfo->name, rci->name);
+ rinfo->arch = rci->arch;
+
+ /* Set base addrs */
+ rinfo->fb_base_phys = pci_resource_start (pdev, 0);
+ rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+
+ /* request the mem regions */
+ if (!request_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0), "radeonfb")) {
+ printk ("radeonfb: cannot reserve FB region\n");
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ if (!request_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2), "radeonfb")) {
+ printk ("radeonfb: cannot reserve MMIO region\n");
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ /* map the regions */
+ rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys,
+ RADEON_REGSIZE);
+ if (!rinfo->mmio_base) {
+ printk ("radeonfb: cannot map MMIO\n");
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ rinfo->chipset = pdev->device;
+
+ switch (rinfo->arch) {
+ case RADEON_R100:
+ rinfo->hasCRTC2 = 0;
+ break;
+ default:
+ /* all the rest have it */
+ rinfo->hasCRTC2 = 1;
+ break;
+ }
+#if 0
+ if (rinfo->arch == RADEON_M7) {
+ /*
+ * Noticed some errors in accel with M7, will have to work these out...
+ */
+ noaccel = 1;
+ }
+#endif
+ if (mirror)
+ printk("radeonfb: mirroring display to CRT\n");
+
+ /* framebuffer size */
+ tmp = INREG(CONFIG_MEMSIZE);
+
+ /* mem size is bits [28:0], mask off the rest */
+ rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+ /* ram type */
+ tmp = INREG(MEM_SDRAM_MODE_REG);
+ switch ((MEM_CFG_TYPE & tmp) >> 30) {
+ case 0:
+ /* SDR SGRAM (2:1) */
+ strcpy(rinfo->ram_type, "SDR SGRAM");
+ rinfo->ram.ml = 4;
+ rinfo->ram.mb = 4;
+ rinfo->ram.trcd = 1;
+ rinfo->ram.trp = 2;
+ rinfo->ram.twr = 1;
+ rinfo->ram.cl = 2;
+ rinfo->ram.loop_latency = 16;
+ rinfo->ram.rloop = 16;
+
+ break;
+ case 1:
+ /* DDR SGRAM */
+ strcpy(rinfo->ram_type, "DDR SGRAM");
+ rinfo->ram.ml = 4;
+ rinfo->ram.mb = 4;
+ rinfo->ram.trcd = 3;
+ rinfo->ram.trp = 3;
+ rinfo->ram.twr = 2;
+ rinfo->ram.cl = 3;
+ rinfo->ram.tr2w = 1;
+ rinfo->ram.loop_latency = 16;
+ rinfo->ram.rloop = 16;
+
+ break;
+ default:
+ /* 64-bit SDR SGRAM */
+ strcpy(rinfo->ram_type, "SDR SGRAM 64");
+ rinfo->ram.ml = 4;
+ rinfo->ram.mb = 8;
+ rinfo->ram.trcd = 3;
+ rinfo->ram.trp = 3;
+ rinfo->ram.twr = 1;
+ rinfo->ram.cl = 3;
+ rinfo->ram.tr2w = 1;
+ rinfo->ram.loop_latency = 17;
+ rinfo->ram.rloop = 17;
+
+ break;
+ }
+
+ rinfo->bios_seg = radeon_find_rom(rinfo);
+ radeon_get_pllinfo(rinfo, rinfo->bios_seg);
+
+ /*
+ * Hack to get around some busted production M6's
+ * reporting no ram
+ */
+ if (rinfo->video_ram == 0) {
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_ATI_RADEON_LY:
+ case PCI_DEVICE_ID_ATI_RADEON_LZ:
+ rinfo->video_ram = 8192;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+
+#if !defined(__powerpc__)
+ radeon_get_moninfo(rinfo);
+#else
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_ATI_RADEON_LW:
+ case PCI_DEVICE_ID_ATI_RADEON_LX:
+ case PCI_DEVICE_ID_ATI_RADEON_LY:
+ case PCI_DEVICE_ID_ATI_RADEON_LZ:
+ rinfo->dviDisp_type = MT_LCD;
+ break;
+ default:
+ radeon_get_moninfo(rinfo);
+ break;
+ }
+#endif
+
+ radeon_get_EDID(rinfo);
+
+ if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
+ (rinfo->crtDisp_type == MT_DFP)) {
+ if (!radeon_get_dfpinfo(rinfo)) {
+ iounmap ((void*)rinfo->mmio_base);
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+ }
+
+ rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
+ rinfo->video_ram);
+ if (!rinfo->fb_base) {
+ printk ("radeonfb: cannot map FB\n");
+ iounmap ((void*)rinfo->mmio_base);
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ /* I SHOULD FIX THAT CRAP ! I should probably mimmic XFree DRI
+ * driver setup here.
+ *
+ * On PPC, OF based cards setup the internal memory
+ * mapping in strange ways. We change it so that the
+ * framebuffer is mapped at 0 and given half of the card's
+ * address space (2Gb). AGP is mapped high (0xe0000000) and
+ * can use up to 512Mb. Once DRI is fully implemented, we
+ * will have to setup the PCI remapper to remap the agp_special_page
+ * memory page somewhere between those regions so that the card
+ * use a normal PCI bus master cycle to access the ring read ptr.
+ * --BenH.
+ */
+#ifdef CONFIG_ALL_PPC
+ if (rinfo->hasCRTC2)
+ OUTREG(CRTC2_GEN_CNTL,
+ (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
+ OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) | CRTC_DISPLAY_DIS);
+ OUTREG(MC_FB_LOCATION, 0x7fff0000);
+ OUTREG(MC_AGP_LOCATION, 0xffffe000);
+ OUTREG(DISPLAY_BASE_ADDR, 0x00000000);
+ if (rinfo->hasCRTC2)
+ OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0x00000000);
+ OUTREG(SRC_OFFSET, 0x00000000);
+ OUTREG(DST_OFFSET, 0x00000000);
+ mdelay(10);
+ OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) & ~CRTC_DISPLAY_DIS);
+#endif /* CONFIG_ALL_PPC */
+
+ /* save current mode regs before we switch into the new one
+ * so we can restore this upon __exit
+ */
+ radeon_save_state (rinfo, &rinfo->init_state);
+
+ if (!noaccel) {
+ /* initialize the engine */
+ radeon_engine_init (rinfo);
+ }
+
+ /* set all the vital stuff */
+ radeon_set_fbinfo (rinfo);
+
+ pci_set_drvdata(pdev, rinfo);
+ rinfo->next = board_list;
+ board_list = rinfo;
+
+ if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
+ printk ("radeonfb: could not register framebuffer\n");
+ iounmap ((void*)rinfo->fb_base);
+ iounmap ((void*)rinfo->mmio_base);
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_MTRR
+ rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
+ rinfo->video_ram,
+ MTRR_TYPE_WRCOMB, 1);
+#endif
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if (rinfo->dviDisp_type == MT_LCD)
+ register_backlight_controller(&radeon_backlight_controller,
+ rinfo, "ati");
+#endif
+
+#ifdef CONFIG_PMAC_PBOOK
+ if (rinfo->dviDisp_type == MT_LCD) {
+ rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ pmu_register_sleep_notifier(&radeon_sleep_notifier);
+ }
+#endif
+
+ printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type,
+ (rinfo->video_ram/(1024*1024)));
+
+ if (rinfo->hasCRTC2) {
+ printk("radeonfb: DVI port %s monitor connected\n",
+ GET_MON_NAME(rinfo->dviDisp_type));
+ printk("radeonfb: CRT port %s monitor connected\n",
+ GET_MON_NAME(rinfo->crtDisp_type));
+ } else {
+ printk("radeonfb: CRT port %s monitor connected\n",
+ GET_MON_NAME(rinfo->crtDisp_type));
+ }
+
+ RTRACE("radeonfb_pci_register END\n");
+
+ return 0;
+}
+
+
+
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+{
+ struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+
+ if (!rinfo)
+ return;
+
+ /* restore original state
+ *
+ * Doesn't quite work yet, possibly because of the PPC hacking
+ * I do on startup, disable for now. --BenH
+ */
+ radeon_write_mode (rinfo, &rinfo->init_state);
+
+#ifdef CONFIG_MTRR
+ if (rinfo->mtrr_hdl >= 0)
+ mtrr_del(rinfo->mtrr_hdl, 0, 0);
+#endif
+
+ unregister_framebuffer ((struct fb_info *) rinfo);
+
+ iounmap ((void*)rinfo->mmio_base);
+ iounmap ((void*)rinfo->fb_base);
+
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+
+ kfree (rinfo);
+}
+
+
+static struct pci_driver radeonfb_driver = {
+ name: "radeonfb",
+ id_table: radeonfb_pci_table,
+ probe: radeonfb_pci_register,
+ remove: __devexit_p(radeonfb_pci_unregister),
};
+
+
+int __init radeonfb_init (void)
+{
+ return pci_module_init (&radeonfb_driver);
+}
+
+
+void __exit radeonfb_exit (void)
+{
+ pci_unregister_driver (&radeonfb_driver);
+}
+
+
+int __init radeonfb_setup (char *options)
+{
+ char *this_opt;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep (&options, ",")) != NULL) {
+ if (!*this_opt)
+ continue;
+ if (!strncmp(this_opt, "noaccel", 7)) {
+ noaccel = 1;
+ } else if (!strncmp(this_opt, "mirror", 6)) {
+ mirror = 1;
+ } else if (!strncmp(this_opt, "dfp", 3)) {
+ force_dfp = 1;
+ } else if (!strncmp(this_opt, "panel_yres:", 11)) {
+ panel_yres = simple_strtoul((this_opt+11), NULL, 0);
+ } else if (!strncmp(this_opt, "nomtrr", 6)) {
+ nomtrr = 1;
+ } else
+ mode_option = this_opt;
+ }
+
+ return 0;
+}
+
+#ifdef MODULE
+module_init(radeonfb_init);
+module_exit(radeonfb_exit);
#endif
+
+
+MODULE_AUTHOR("Ani Joshi");
+MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index 52ac100708bd..fb5e1020908c 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -1430,7 +1430,7 @@ int __init retz3fb_init(void)
return -EINVAL;
printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
- "video memory\n", GET_FB_IDX(fb_info->node),
+ "video memory\n", minor(fb_info->node),
fb_info->modename, zinfo->fbsize>>10);
/* FIXME: This driver cannot be unloaded yet */
diff --git a/drivers/video/riva/Makefile b/drivers/video/riva/Makefile
index 664fefd88eb4..d7656aacb5cc 100644
--- a/drivers/video/riva/Makefile
+++ b/drivers/video/riva/Makefile
@@ -4,6 +4,6 @@
obj-$(CONFIG_FB_RIVA) += rivafb.o
-rivafb-objs := fbdev.o riva_hw.o accel.o
+rivafb-objs := fbdev.o riva_hw.o
include $(TOPDIR)/Rules.make
diff --git a/drivers/video/riva/accel.c b/drivers/video/riva/accel.c
deleted file mode 100644
index bea186a5f46e..000000000000
--- a/drivers/video/riva/accel.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * linux/drivers/video/accel.c - nVidia RIVA 128/TNT/TNT2 fb driver
- *
- * Copyright 2000 Jindrich Makovicka, Ani Joshi
- *
- * 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 "rivafb.h"
-
-/* acceleration routines */
-
-inline void wait_for_idle(struct rivafb_info *rinfo)
-{
- while (rinfo->riva.Busy(&rinfo->riva));
-}
-
-/* set copy ROP, no mask */
-static void riva_setup_ROP(struct rivafb_info *rinfo)
-{
- RIVA_FIFO_FREE(rinfo->riva, Patt, 5);
- rinfo->riva.Patt->Shape = 0;
- rinfo->riva.Patt->Color0 = 0xffffffff;
- rinfo->riva.Patt->Color1 = 0xffffffff;
- rinfo->riva.Patt->Monochrome[0] = 0xffffffff;
- rinfo->riva.Patt->Monochrome[1] = 0xffffffff;
-
- RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
- rinfo->riva.Rop->Rop3 = 0xCC;
-}
-
-void riva_setup_accel(struct rivafb_info *rinfo)
-{
- RIVA_FIFO_FREE(rinfo->riva, Clip, 2);
- rinfo->riva.Clip->TopLeft = 0x0;
- rinfo->riva.Clip->WidthHeight = 0x80008000;
- riva_setup_ROP(rinfo);
- wait_for_idle(rinfo);
-}
-
-static void riva_rectfill(struct rivafb_info *rinfo, int sy,
- int sx, int height, int width, u_int color)
-{
- RIVA_FIFO_FREE(rinfo->riva, Bitmap, 1);
- rinfo->riva.Bitmap->Color1A = color;
-
- RIVA_FIFO_FREE(rinfo->riva, Bitmap, 2);
- rinfo->riva.Bitmap->UnclippedRectangle[0].TopLeft = (sx << 16) | sy;
- rinfo->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (width << 16) | height;
-}
-
-static void fbcon_riva_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
- sx *= fontwidth(p);
- sy *= fontheight(p);
- dx *= fontwidth(p);
- dy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
-
- RIVA_FIFO_FREE(rinfo->riva, Blt, 3);
- rinfo->riva.Blt->TopLeftSrc = (sy << 16) | sx;
- rinfo->riva.Blt->TopLeftDst = (dy << 16) | dx;
- rinfo->riva.Blt->WidthHeight = (height << 16) | width;
-}
-
-static void riva_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only, u32 bgx)
-{
- struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
- unsigned int right_start = conp->vc_cols*fontwidth(p);
- unsigned int bottom_start = conp->vc_rows*fontheight(p);
- unsigned int right_width, bottom_width;
-
- if (!bottom_only && (right_width = p->var.xres - right_start))
- riva_rectfill(rinfo, 0, right_start, p->var.yres_virtual,
- right_width, bgx);
- if ((bottom_width = p->var.yres - bottom_start))
- riva_rectfill(rinfo, p->var.yoffset + bottom_start, 0,
- bottom_width, right_start, bgx);
-}
-
-static u8 byte_rev[256] = {
- 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
- 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
- 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
- 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
- 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
- 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
- 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
- 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
- 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
- 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
- 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
- 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
- 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
- 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
- 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
- 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
-};
-
-static inline void fbcon_reverse_order(u32 *l)
-{
- u8 *a = (u8 *)l;
- *a++ = byte_rev[*a];
-/* *a++ = byte_rev[*a];
- *a++ = byte_rev[*a];*/
- *a = byte_rev[*a];
-}
-
-static void fbcon_riva_writechr(struct vc_data *conp, struct display *p,
- int c, int fgx, int bgx, int yy, int xx)
-{
- u8 *cdat;
- struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
- int w, h;
- volatile u32 *d;
- u32 cdat2;
- int i, j, cnt;
-
- w = fontwidth(p);
- h = fontheight(p);
-
- if (w <= 8)
- cdat = p->fontdata + (c & p->charmask) * h;
- else
- cdat = p->fontdata + ((c & p->charmask) * h << 1);
-
- RIVA_FIFO_FREE(rinfo->riva, Bitmap, 7);
- rinfo->riva.Bitmap->ClipE.TopLeft = (yy << 16) | (xx & 0xFFFF);
- rinfo->riva.Bitmap->ClipE.BottomRight = ((yy+h) << 16) | ((xx+w) & 0xffff);
- rinfo->riva.Bitmap->Color0E = bgx;
- rinfo->riva.Bitmap->Color1E = fgx;
- rinfo->riva.Bitmap->WidthHeightInE = (h << 16) | 32;
- rinfo->riva.Bitmap->WidthHeightOutE = (h << 16) | 32;
- rinfo->riva.Bitmap->PointE = (yy << 16) | (xx & 0xFFFF);
-
- d = &rinfo->riva.Bitmap->MonochromeData01E;
- for (i = h; i > 0; i-=16) {
- if (i >= 16)
- cnt = 16;
- else
- cnt = i;
- RIVA_FIFO_FREE(rinfo->riva, Bitmap, cnt);
- for (j = 0; j < cnt; j++) {
- if (w <= 8)
- cdat2 = *cdat++;
- else
- cdat2 = *((u16*)cdat)++;
- fbcon_reverse_order(&cdat2);
- d[j] = cdat2;
- }
- }
-}
-
-#ifdef FBCON_HAS_CFB8
-void fbcon_riva8_setup(struct display *p)
-{
- p->next_line = p->line_length ? p->line_length : p->var.xres_virtual;
- p->next_plane = 0;
-}
-
-static void fbcon_riva8_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- u32 bgx;
-
- struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
- bgx = attr_bgcol_ec(p, conp);
-
- sx *= fontwidth(p);
- sy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
-
- riva_rectfill(rinfo, sy, sx, height, width, bgx);
-}
-
-static void fbcon_riva8_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- u32 fgx,bgx;
-
- fgx = attr_fgcol(p,c);
- bgx = attr_bgcol(p,c);
-
- xx *= fontwidth(p);
- yy *= fontheight(p);
-
- fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-}
-
-static void fbcon_riva8_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy,
- int xx)
-{
- u16 c;
- u32 fgx,bgx;
-
- xx *= fontwidth(p);
- yy *= fontheight(p);
-
- c = scr_readw(s);
- fgx = attr_fgcol(p, c);
- bgx = attr_bgcol(p, c);
- while (count--) {
- c = scr_readw(s++);
- fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
- xx += fontwidth(p);
- }
-}
-
-static void fbcon_riva8_revc(struct display *p, int xx, int yy)
-{
- struct rivafb_info *rinfo = (struct rivafb_info *) (p->fb_info);
-
- xx *= fontwidth(p);
- yy *= fontheight(p);
-
- RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
- rinfo->riva.Rop->Rop3 = 0x66; // XOR
- riva_rectfill(rinfo, yy, xx, fontheight(p), fontwidth(p), 0x0f);
- RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
- rinfo->riva.Rop->Rop3 = 0xCC; // back to COPY
-}
-
-static void fbcon_riva8_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- riva_clear_margins(conp, p, bottom_only, attr_bgcol_ec(p, conp));
-}
-
-struct display_switch fbcon_riva8 = {
- .setup = fbcon_riva8_setup,
- .bmove = fbcon_riva_bmove,
- .clear = fbcon_riva8_clear,
- .putc = fbcon_riva8_putc,
- .putcs = fbcon_riva8_putcs,
- .revc = fbcon_riva8_revc,
- .clear_margins =fbcon_riva8_clear_margins,
- .fontwidthmask =FONTWIDTHRANGE(4, 16)
-};
-#endif
-
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
-static void fbcon_riva1632_revc(struct display *p, int xx, int yy)
-{
- struct rivafb_info *rinfo = (struct rivafb_info *) (p->fb_info);
-
- xx *= fontwidth(p);
- yy *= fontheight(p);
-
- RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
- rinfo->riva.Rop->Rop3 = 0x66; // XOR
- riva_rectfill(rinfo, yy, xx, fontheight(p), fontwidth(p), 0xffffffff);
- RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
- rinfo->riva.Rop->Rop3 = 0xCC; // back to COPY
-}
-#endif
-
-#ifdef FBCON_HAS_CFB16
-void fbcon_riva16_setup(struct display *p)
-{
- p->next_line = p->line_length ? p->line_length : p->var.xres_virtual<<1;
- p->next_plane = 0;
-}
-
-static void fbcon_riva16_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- u32 bgx;
-
- struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
- bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- sx *= fontwidth(p);
- sy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
-
- riva_rectfill(rinfo, sy, sx, height, width, bgx);
-}
-
-static inline void convert_bgcolor_16(u32 *col)
-{
- *col = ((*col & 0x00007C00) << 9)
- | ((*col & 0x000003E0) << 6)
- | ((*col & 0x0000001F) << 3)
- | 0xFF000000;
-}
-
-static void fbcon_riva16_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- u32 fgx,bgx;
-
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p,c)];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p,c)];
- if (p->var.green.length == 6)
- convert_bgcolor_16(&bgx);
- xx *= fontwidth(p);
- yy *= fontheight(p);
-
- fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-}
-
-static void fbcon_riva16_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy,
- int xx)
-{
- u16 c;
- u32 fgx,bgx;
-
- xx *= fontwidth(p);
- yy *= fontheight(p);
-
- c = scr_readw(s);
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
- if (p->var.green.length == 6)
- convert_bgcolor_16(&bgx);
- while (count--) {
- c = scr_readw(s++);
- fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
- xx += fontwidth(p);
- }
-}
-
-static void fbcon_riva16_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- riva_clear_margins(conp, p, bottom_only, ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]);
-}
-
-struct display_switch fbcon_riva16 = {
- .setup = fbcon_riva16_setup,
- .bmove = fbcon_riva_bmove,
- .clear = fbcon_riva16_clear,
- .putc = fbcon_riva16_putc,
- .putcs = fbcon_riva16_putcs,
- .revc = fbcon_riva1632_revc,
- .clear_margins =fbcon_riva16_clear_margins,
- .fontwidthmask =FONTWIDTHRANGE(4, 16)
-};
-#endif
-
-#ifdef FBCON_HAS_CFB32
-void fbcon_riva32_setup(struct display *p)
-{
- p->next_line = p->line_length ? p->line_length : p->var.xres_virtual<<2;
- p->next_plane = 0;
-}
-
-static void fbcon_riva32_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- u32 bgx;
-
- struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
- bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- sx *= fontwidth(p);
- sy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
-
- riva_rectfill(rinfo, sy, sx, height, width, bgx);
-}
-
-static void fbcon_riva32_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- u32 fgx,bgx;
-
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p,c)];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
- xx *= fontwidth(p);
- yy *= fontheight(p);
- fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-}
-
-static void fbcon_riva32_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy,
- int xx)
-{
- u16 c;
- u32 fgx,bgx;
-
- xx *= fontwidth(p);
- yy *= fontheight(p);
-
- c = scr_readw(s);
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
- while (count--) {
- c = scr_readw(s++);
- fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
- xx += fontwidth(p);
- }
-}
-
-static void fbcon_riva32_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- riva_clear_margins(conp, p, bottom_only, ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]);
-}
-
-struct display_switch fbcon_riva32 = {
- .setup = fbcon_riva32_setup,
- .bmove = fbcon_riva_bmove,
- .clear = fbcon_riva32_clear,
- .putc = fbcon_riva32_putc,
- .putcs = fbcon_riva32_putcs,
- .revc = fbcon_riva1632_revc,
- .clear_margins =fbcon_riva32_clear_margins,
- .fontwidthmask =FONTWIDTHRANGE(4, 16)
-};
-#endif
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index fa083a87938c..7321f818eacc 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -25,7 +25,6 @@
* Known bugs and issues:
* restoring text mode fails
* doublescan modes are broken
- * option 'noaccel' has no effect
*/
#include <linux/config.h>
@@ -34,17 +33,16 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/selection.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/console.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
+
#include "rivafb.h"
#include "nvreg.h"
@@ -55,7 +53,7 @@
/* version number of this driver */
-#define RIVAFB_VERSION "0.9.2a"
+#define RIVAFB_VERSION "0.9.3"
@@ -109,10 +107,7 @@
static int rivafb_blank(int blank, struct fb_info *info);
-extern void riva_setup_accel(struct rivafb_info *rinfo);
-extern inline void wait_for_idle(struct rivafb_info *rinfo);
-
-
+extern inline void wait_for_idle(struct riva_par *par);
/* ------------------------------------------------------------------------- *
*
@@ -136,6 +131,11 @@ enum riva_chips {
CH_GEFORCE2_GTS,
CH_GEFORCE2_ULTRA,
CH_QUADRO2_PRO,
+ CH_GEFORCE2_GO,
+ CH_GEFORCE3,
+ CH_GEFORCE3_1,
+ CH_GEFORCE3_2,
+ CH_QUADRO_DDC
};
/* directly indexed by riva_chips enum, above */
@@ -158,6 +158,11 @@ static struct riva_chip_info {
{ "GeForce2-GTS", NV_ARCH_10},
{ "GeForce2-ULTRA", NV_ARCH_10},
{ "Quadro2-PRO", NV_ARCH_10},
+ { "GeForce2-Go", NV_ARCH_10},
+ { "GeForce3", NV_ARCH_20},
+ { "GeForce3 Ti 200", NV_ARCH_20},
+ { "GeForce3 Ti 500", NV_ARCH_20},
+ { "Quadro DDC", NV_ARCH_20}
};
static struct pci_device_id rivafb_pci_tbl[] __devinitdata = {
@@ -195,6 +200,16 @@ static struct pci_device_id rivafb_pci_tbl[] __devinitdata = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_ULTRA },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_PRO },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GO },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_1 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_2 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO_DDC },
{ 0, } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
@@ -207,24 +222,9 @@ MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
*
* ------------------------------------------------------------------------- */
-#ifdef FBCON_HAS_CFB8
extern struct display_switch fbcon_riva8;
-#endif
-#ifdef FBCON_HAS_CFB16
extern struct display_switch fbcon_riva16;
-#endif
-#ifdef FBCON_HAS_CFB32
extern struct display_switch fbcon_riva32;
-#endif
-
-#if 0
-/* describes the state of a Riva board */
-struct rivafb_par {
- struct riva_regs state; /* state of hw board */
- __u32 visual; /* FB_VISUAL_xxx */
- unsigned depth; /* bpp of current mode */
-};
-#endif
struct riva_cursor {
int enable;
@@ -239,59 +239,56 @@ struct riva_cursor {
struct timer_list *timer;
};
-
-
/* ------------------------------------------------------------------------- *
*
* global variables
*
* ------------------------------------------------------------------------- */
-struct rivafb_info *riva_boards = NULL;
-
/* command line data, set in rivafb_setup() */
-static char fontname[40] __initdata = { 0 };
-static char noaccel __initdata = 0;
-static char nomove = 0;
-static char nohwcursor __initdata = 0;
-static char noblink = 0;
+static u32 pseudo_palette[17];
#ifdef CONFIG_MTRR
static char nomtrr __initdata = 0;
#endif
#ifndef MODULE
static char *mode_option __initdata = NULL;
-#else
-static char *font = NULL;
#endif
+static struct fb_fix_screeninfo rivafb_fix = {
+ id: "nVidia",
+ type: FB_TYPE_PACKED_PIXELS,
+ xpanstep: 1,
+ ypanstep: 1,
+};
+
static struct fb_var_screeninfo rivafb_default_var = {
- .xres = 640,
- .yres = 480,
- .xres_virtual = 640,
- .yres_virtual = 480,
- .xoffset = 0,
- .yoffset = 0,
- .bits_per_pixel =8,
- .grayscale = 0,
- .red = {0, 6, 0},
- .green = {0, 6, 0},
- .blue = {0, 6, 0},
- .transp = {0, 0, 0},
- .nonstd = 0,
- .activate = 0,
- .height = -1,
- .width = -1,
- .accel_flags = 0,
- .pixclock = 39721,
- .left_margin = 40,
- .right_margin = 24,
- .upper_margin = 32,
- .lower_margin = 11,
- .hsync_len = 96,
- .vsync_len = 2,
- .sync = 0,
- .vmode = FB_VMODE_NONINTERLACED
+ xres: 640,
+ yres: 480,
+ xres_virtual: 640,
+ yres_virtual: 480,
+ xoffset: 0,
+ yoffset: 0,
+ bits_per_pixel: 8,
+ grayscale: 0,
+ red: {0, 6, 0},
+ green: {0, 6, 0},
+ blue: {0, 6, 0},
+ transp: {0, 0, 0},
+ nonstd: 0,
+ activate: 0,
+ height: -1,
+ width: -1,
+ accel_flags: FB_ACCELF_TEXT,
+ pixclock: 39721,
+ left_margin: 40,
+ right_margin: 24,
+ upper_margin: 32,
+ lower_margin: 11,
+ hsync_len: 96,
+ vsync_len: 2,
+ sync: 0,
+ vmode: FB_VMODE_NONINTERLACED
};
/* from GGI */
@@ -323,70 +320,70 @@ static const struct riva_regs reg_template = {
*
* ------------------------------------------------------------------------- */
-static inline void CRTCout(struct rivafb_info *rinfo, unsigned char index,
+static inline void CRTCout(struct riva_par *par, unsigned char index,
unsigned char val)
{
- VGA_WR08(rinfo->riva.PCIO, 0x3d4, index);
- VGA_WR08(rinfo->riva.PCIO, 0x3d5, val);
+ VGA_WR08(par->riva.PCIO, 0x3d4, index);
+ VGA_WR08(par->riva.PCIO, 0x3d5, val);
}
-static inline unsigned char CRTCin(struct rivafb_info *rinfo,
+static inline unsigned char CRTCin(struct riva_par *par,
unsigned char index)
{
- VGA_WR08(rinfo->riva.PCIO, 0x3d4, index);
- return (VGA_RD08(rinfo->riva.PCIO, 0x3d5));
+ VGA_WR08(par->riva.PCIO, 0x3d4, index);
+ return (VGA_RD08(par->riva.PCIO, 0x3d5));
}
-static inline void GRAout(struct rivafb_info *rinfo, unsigned char index,
+static inline void GRAout(struct riva_par *par, unsigned char index,
unsigned char val)
{
- VGA_WR08(rinfo->riva.PVIO, 0x3ce, index);
- VGA_WR08(rinfo->riva.PVIO, 0x3cf, val);
+ VGA_WR08(par->riva.PVIO, 0x3ce, index);
+ VGA_WR08(par->riva.PVIO, 0x3cf, val);
}
-static inline unsigned char GRAin(struct rivafb_info *rinfo,
+static inline unsigned char GRAin(struct riva_par *par,
unsigned char index)
{
- VGA_WR08(rinfo->riva.PVIO, 0x3ce, index);
- return (VGA_RD08(rinfo->riva.PVIO, 0x3cf));
+ VGA_WR08(par->riva.PVIO, 0x3ce, index);
+ return (VGA_RD08(par->riva.PVIO, 0x3cf));
}
-static inline void SEQout(struct rivafb_info *rinfo, unsigned char index,
+static inline void SEQout(struct riva_par *par, unsigned char index,
unsigned char val)
{
- VGA_WR08(rinfo->riva.PVIO, 0x3c4, index);
- VGA_WR08(rinfo->riva.PVIO, 0x3c5, val);
+ VGA_WR08(par->riva.PVIO, 0x3c4, index);
+ VGA_WR08(par->riva.PVIO, 0x3c5, val);
}
-static inline unsigned char SEQin(struct rivafb_info *rinfo,
+static inline unsigned char SEQin(struct riva_par *par,
unsigned char index)
{
- VGA_WR08(rinfo->riva.PVIO, 0x3c4, index);
- return (VGA_RD08(rinfo->riva.PVIO, 0x3c5));
+ VGA_WR08(par->riva.PVIO, 0x3c4, index);
+ return (VGA_RD08(par->riva.PVIO, 0x3c5));
}
-static inline void ATTRout(struct rivafb_info *rinfo, unsigned char index,
+static inline void ATTRout(struct riva_par *par, unsigned char index,
unsigned char val)
{
- VGA_WR08(rinfo->riva.PCIO, 0x3c0, index);
- VGA_WR08(rinfo->riva.PCIO, 0x3c0, val);
+ VGA_WR08(par->riva.PCIO, 0x3c0, index);
+ VGA_WR08(par->riva.PCIO, 0x3c0, val);
}
-static inline unsigned char ATTRin(struct rivafb_info *rinfo,
+static inline unsigned char ATTRin(struct riva_par *par,
unsigned char index)
{
- VGA_WR08(rinfo->riva.PCIO, 0x3c0, index);
- return (VGA_RD08(rinfo->riva.PCIO, 0x3c1));
+ VGA_WR08(par->riva.PCIO, 0x3c0, index);
+ return (VGA_RD08(par->riva.PCIO, 0x3c1));
}
-static inline void MISCout(struct rivafb_info *rinfo, unsigned char val)
+static inline void MISCout(struct riva_par *par, unsigned char val)
{
- VGA_WR08(rinfo->riva.PVIO, 0x3c2, val);
+ VGA_WR08(par->riva.PVIO, 0x3c2, val);
}
-static inline unsigned char MISCin(struct rivafb_info *rinfo)
+static inline unsigned char MISCin(struct riva_par *par)
{
- return (VGA_RD08(rinfo->riva.PVIO, 0x3cc));
+ return (VGA_RD08(par->riva.PVIO, 0x3cc));
}
@@ -398,240 +395,63 @@ static inline unsigned char MISCin(struct rivafb_info *rinfo)
* ------------------------------------------------------------------------- */
/**
- * riva_cursor_timer_handler - blink timer
- * @dev_addr: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Cursor blink timer.
- */
-static void riva_cursor_timer_handler(unsigned long dev_addr)
-{
- struct rivafb_info *rinfo = (struct rivafb_info *)dev_addr;
-
- if (!rinfo->cursor) return;
-
- if (!rinfo->cursor->enable) goto out;
-
- if (rinfo->cursor->last_move_delay < 1000)
- rinfo->cursor->last_move_delay++;
-
- if (rinfo->cursor->vbl_cnt && --rinfo->cursor->vbl_cnt == 0) {
- rinfo->cursor->on ^= 1;
- if (rinfo->cursor->on)
- *(rinfo->riva.CURSORPOS) = (rinfo->cursor->pos.x & 0xFFFF)
- | (rinfo->cursor->pos.y << 16);
- rinfo->riva.ShowHideCursor(&rinfo->riva, rinfo->cursor->on);
- if (!noblink)
- rinfo->cursor->vbl_cnt = rinfo->cursor->blink_rate;
- }
-out:
- rinfo->cursor->timer->expires = jiffies + (HZ / 100);
- add_timer(rinfo->cursor->timer);
-}
-
-/**
- * rivafb_init_cursor - allocates cursor structure and starts blink timer
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Allocates cursor structure and starts blink timer.
- *
- * RETURNS:
- * Pointer to allocated cursor structure.
- *
- * CALLED FROM:
- * rivafb_init_one()
- */
-static struct riva_cursor * __init rivafb_init_cursor(struct rivafb_info *rinfo)
-{
- struct riva_cursor *cursor;
-
- cursor = kmalloc(sizeof(struct riva_cursor), GFP_KERNEL);
- if (!cursor) return 0;
- memset(cursor, 0, sizeof(*cursor));
-
- cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
- if (!cursor->timer) {
- kfree(cursor);
- return 0;
- }
- memset(cursor->timer, 0, sizeof(*cursor->timer));
-
- cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
-
- init_timer(cursor->timer);
- cursor->timer->expires = jiffies + (HZ / 100);
- cursor->timer->data = (unsigned long)rinfo;
- cursor->timer->function = riva_cursor_timer_handler;
- add_timer(cursor->timer);
-
- return cursor;
-}
-
-/**
- * rivafb_exit_cursor - stops blink timer and releases cursor structure
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Stops blink timer and releases cursor structure.
- *
- * CALLED FROM:
- * rivafb_init_one()
- * rivafb_remove_one()
- */
-static void rivafb_exit_cursor(struct rivafb_info *rinfo)
-{
- struct riva_cursor *cursor = rinfo->cursor;
-
- if (cursor) {
- if (cursor->timer) {
- del_timer_sync(cursor->timer);
- kfree(cursor->timer);
- }
- kfree(cursor);
- rinfo->cursor = 0;
- }
-}
-
-/**
- * rivafb_download_cursor - writes cursor shape into card registers
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Writes cursor shape into card registers.
- *
- * CALLED FROM:
- * riva_load_video_mode()
- */
-static void rivafb_download_cursor(struct rivafb_info *rinfo)
-{
- int i, save;
- int *image;
-
- if (!rinfo->cursor) return;
-
- image = (int *)rinfo->cursor->image;
- save = rinfo->riva.ShowHideCursor(&rinfo->riva, 0);
- for (i = 0; i < (MAX_CURS*MAX_CURS*2)/sizeof(int); i++)
- writel(image[i], rinfo->riva.CURSOR + i);
-
- rinfo->riva.ShowHideCursor(&rinfo->riva, save);
-}
-
-/**
- * rivafb_create_cursor - sets rectangular cursor
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- * @width: cursor width in pixels
- * @height: cursor height in pixels
- *
- * DESCRIPTION:
- * Sets rectangular cursor.
+ * rivafb_load_cursor_image - load cursor image to hardware
+ * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
+ * @mask: address to mask (1 = write image pixel, 0 = do not write pixel)
+ * @par: pointer to private data
+ * @w: width of cursor image in pixels
+ * @h: height of cursor image in scanlines
+ * @bg: background color (ARGB1555) - alpha bit determines opacity
+ * @fg: foreground color (ARGB1555)
+ *
+ * DESCRIPTiON:
+ * Loads cursor image based on a monochrome source and mask bitmap. The
+ * mask bit determines if the image pixel is to be written to the framebuffer
+ * or not. The imaage bits determines the color of the pixel, 0 for
+ * background, 1 for foreground. Only the affected region (as determined
+ * by @w and @h parameters) will be updated.
*
* CALLED FROM:
- * rivafb_set_font()
- * rivafb_set_var()
- */
-static void rivafb_create_cursor(struct rivafb_info *rinfo, int width, int height)
-{
- struct riva_cursor *c = rinfo->cursor;
- int i, j, idx;
-
- if (c) {
- if (width <= 0 || height <= 0) {
- width = 8;
- height = 16;
- }
- if (width > MAX_CURS) width = MAX_CURS;
- if (height > MAX_CURS) height = MAX_CURS;
-
- c->size.x = width;
- c->size.y = height;
-
- idx = 0;
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++,idx++)
- c->image[idx] = CURSOR_COLOR;
- for (j = width; j < MAX_CURS; j++,idx++)
- c->image[idx] = TRANSPARENT_COLOR;
- }
- for (i = height; i < MAX_CURS; i++)
- for (j = 0; j < MAX_CURS; j++,idx++)
- c->image[idx] = TRANSPARENT_COLOR;
- }
-}
-
-/**
- * rivafb_set_font - change font size
- * @p: pointer to display object
- * @width: font width in pixels
- * @height: font height in pixels
- *
- * DESCRIPTION:
- * Callback function called if font settings changed.
- *
- * RETURNS:
- * 1 (Always succeeds.)
- */
-static int rivafb_set_font(struct display *p, int width, int height)
-{
- struct rivafb_info *fb = (struct rivafb_info *)(p->fb_info);
-
- rivafb_create_cursor(fb, width, height);
- return 1;
-}
-
-/**
- * rivafb_cursor - cursor handler
- * @p: pointer to display object
- * @mode: cursor mode (see CM_*)
- * @x: cursor x coordinate in characters
- * @y: cursor y coordinate in characters
- *
- * DESCRIPTION:
- * Cursor handler.
+ * rivafb_cursor()
*/
-static void rivafb_cursor(struct display *p, int mode, int x, int y)
+static void rivafb_load_cursor_image(u8 *data, u8 *mask, struct riva_par *par,
+ int w, int h, u16 bg, u16 fg)
{
- struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
- struct riva_cursor *c = rinfo->cursor;
-
- if (!c) return;
-
- x = x * fontwidth(p) - p->var.xoffset;
- y = y * fontheight(p) - p->var.yoffset;
-
- if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->enable)
- return;
-
- c->enable = 0;
- if (c->on) rinfo->riva.ShowHideCursor(&rinfo->riva, 0);
-
- c->pos.x = x;
- c->pos.y = y;
-
- switch (mode) {
- case CM_ERASE:
- c->on = 0;
- break;
- case CM_DRAW:
- case CM_MOVE:
- if (c->last_move_delay <= 1) { /* rapid cursor movement */
- c->vbl_cnt = CURSOR_SHOW_DELAY;
- } else {
- *(rinfo->riva.CURSORPOS) = (x & 0xFFFF) | (y << 16);
- rinfo->riva.ShowHideCursor(&rinfo->riva, 1);
- if (!noblink) c->vbl_cnt = CURSOR_HIDE_DELAY;
- c->on = 1;
+ int i, j, k = 0;
+ u32 b, m, tmp;
+
+
+ for (i = 0; i < h; i++) {
+ b = *((u32 *)data)++;
+ m = *((u32 *)mask)++;
+ for (j = 0; j < w/2; j++) {
+ tmp = 0;
+#if defined (__BIG_ENDIAN__)
+ if (m & (1 << 31))
+ tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
+ b <<= 1;
+ m <<= 1;
+
+ if (m & (1 << 31))
+ tmp |= (b & (1 << 31)) ? fg : bg;
+ b <<= 1;
+ m <<= 1;
+#else
+ if (m & 1)
+ tmp = (b & 1) ? fg : bg;
+ b >>= 1;
+ m >>= 1;
+ if (m & 1)
+ tmp |= (b & 1) ? fg << 16 : bg << 16;
+ b >>= 1;
+ m >>= 1;
+#endif
+ writel(tmp, par->riva.CURSOR + k++);
}
- c->last_move_delay = 0;
- c->enable = 1;
- break;
+ k += (MAX_CURS - w)/2;
}
}
-
-
/* ------------------------------------------------------------------------- *
*
* general utility functions
@@ -639,80 +459,6 @@ static void rivafb_cursor(struct display *p, int mode, int x, int y)
* ------------------------------------------------------------------------- */
/**
- * riva_set_dispsw - sets dispsw
- * @rinfo: pointer to internal driver struct for a given Riva card
- * @disp: pointer to display object
- *
- * DESCRIPTION:
- * Sets up console low level operations depending on the current? color depth
- * of the display.
- *
- * CALLED FROM:
- * rivafb_set_var()
- * rivafb_switch()
- * riva_init_disp()
- */
-static void riva_set_dispsw(struct rivafb_info *rinfo, struct display *disp)
-{
- int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
-
- DPRINTK("ENTER\n");
-
- assert(rinfo != NULL);
-
- disp->dispsw_data = NULL;
-
- disp->type = FB_TYPE_PACKED_PIXELS;
- disp->type_aux = 0;
- disp->ypanstep = 1;
- disp->ywrapstep = 0;
- disp->can_soft_blank = 1;
- disp->inverse = 0;
-
- switch (disp->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- rinfo->dispsw = accel ? fbcon_riva8 : fbcon_cfb8;
- disp->dispsw = &rinfo->dispsw;
- disp->line_length = disp->var.xres_virtual;
- disp->visual = FB_VISUAL_PSEUDOCOLOR;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- rinfo->dispsw = accel ? fbcon_riva16 : fbcon_cfb16;
- disp->dispsw_data = &rinfo->con_cmap.cfb16;
- disp->dispsw = &rinfo->dispsw;
- disp->line_length = disp->var.xres_virtual * 2;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- rinfo->dispsw = accel ? fbcon_riva32 : fbcon_cfb32;
- disp->dispsw_data = rinfo->con_cmap.cfb32;
- disp->dispsw = &rinfo->dispsw;
- disp->line_length = disp->var.xres_virtual * 4;
- disp->visual = FB_VISUAL_DIRECTCOLOR;
- break;
-#endif
- default:
- DPRINTK("Setting fbcon_dummy renderer\n");
- rinfo->dispsw = fbcon_dummy;
- disp->dispsw = &rinfo->dispsw;
- }
-
- /* FIXME: verify that the above code sets dsp->* fields correctly */
-
- if (rinfo->cursor) {
- rinfo->dispsw.cursor = rivafb_cursor;
- rinfo->dispsw.set_font = rivafb_set_font;
- }
-
- DPRINTK("EXIT\n");
-}
-
-/**
* riva_wclut - set CLUT entry
* @chip: pointer to RIVA_HW_INST object
* @regnum: register number
@@ -738,7 +484,7 @@ static void riva_wclut(RIVA_HW_INST *chip,
/**
* riva_save_state - saves current chip state
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @par: pointer to riva_par object containing info for current riva board
* @regs: pointer to riva_regs object
*
* DESCRIPTION:
@@ -748,36 +494,36 @@ static void riva_wclut(RIVA_HW_INST *chip,
* rivafb_init_one()
*/
/* from GGI */
-static void riva_save_state(struct rivafb_info *rinfo, struct riva_regs *regs)
+static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
{
int i;
- rinfo->riva.LockUnlock(&rinfo->riva, 0);
+ par->riva.LockUnlock(&par->riva, 0);
- rinfo->riva.UnloadStateExt(&rinfo->riva, &regs->ext);
+ par->riva.UnloadStateExt(&par->riva, &regs->ext);
- regs->misc_output = MISCin(rinfo);
+ regs->misc_output = MISCin(par);
for (i = 0; i < NUM_CRT_REGS; i++) {
- regs->crtc[i] = CRTCin(rinfo, i);
+ regs->crtc[i] = CRTCin(par, i);
}
for (i = 0; i < NUM_ATC_REGS; i++) {
- regs->attr[i] = ATTRin(rinfo, i);
+ regs->attr[i] = ATTRin(par, i);
}
for (i = 0; i < NUM_GRC_REGS; i++) {
- regs->gra[i] = GRAin(rinfo, i);
+ regs->gra[i] = GRAin(par, i);
}
for (i = 0; i < NUM_SEQ_REGS; i++) {
- regs->seq[i] = SEQin(rinfo, i);
+ regs->seq[i] = SEQin(par, i);
}
}
/**
* riva_load_state - loads current chip state
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @par: pointer to riva_par object containing info for current riva board
* @regs: pointer to riva_regs object
*
* DESCRIPTION:
@@ -789,18 +535,18 @@ static void riva_save_state(struct rivafb_info *rinfo, struct riva_regs *regs)
* rivafb_remove_one()
*/
/* from GGI */
-static void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
+static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
{
- int i;
RIVA_HW_STATE *state = &regs->ext;
+ int i;
- CRTCout(rinfo, 0x11, 0x00);
+ CRTCout(par, 0x11, 0x00);
- rinfo->riva.LockUnlock(&rinfo->riva, 0);
+ par->riva.LockUnlock(&par->riva, 0);
- rinfo->riva.LoadStateExt(&rinfo->riva, state);
+ par->riva.LoadStateExt(&par->riva, state);
- MISCout(rinfo, regs->misc_output);
+ MISCout(par, regs->misc_output);
for (i = 0; i < NUM_CRT_REGS; i++) {
switch (i) {
@@ -808,26 +554,26 @@ static void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
case 0x20 ... 0x40:
break;
default:
- CRTCout(rinfo, i, regs->crtc[i]);
+ CRTCout(par, i, regs->crtc[i]);
}
}
for (i = 0; i < NUM_ATC_REGS; i++) {
- ATTRout(rinfo, i, regs->attr[i]);
+ ATTRout(par, i, regs->attr[i]);
}
for (i = 0; i < NUM_GRC_REGS; i++) {
- GRAout(rinfo, i, regs->gra[i]);
+ GRAout(par, i, regs->gra[i]);
}
for (i = 0; i < NUM_SEQ_REGS; i++) {
- SEQout(rinfo, i, regs->seq[i]);
+ SEQout(par, i, regs->seq[i]);
}
}
/**
* riva_load_video_mode - calculate timings
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @info: pointer to fb_info object containing info for current riva board
* @video_mode: video mode to set
*
* DESCRIPTION:
@@ -836,36 +582,36 @@ static void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
* CALLED FROM:
* rivafb_set_var()
*/
-static void riva_load_video_mode(struct rivafb_info *rinfo,
- struct fb_var_screeninfo *video_mode)
+static void riva_load_video_mode(struct fb_info *info)
{
- struct riva_regs newmode;
int bpp, width, hDisplaySize, hDisplay, hStart,
hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
+ struct riva_par *par = (struct riva_par *) info->par;
+ struct riva_regs newmode;
/* time to calculate */
- rivafb_blank(1, (struct fb_info *)rinfo);
+ rivafb_blank(1, info);
- bpp = video_mode->bits_per_pixel;
- if (bpp == 16 && video_mode->green.length == 5)
+ bpp = info->var.bits_per_pixel;
+ if (bpp == 16 && info->var.green.length == 5)
bpp = 15;
- width = video_mode->xres_virtual;
- hDisplaySize = video_mode->xres;
+ width = info->var.xres_virtual;
+ hDisplaySize = info->var.xres;
hDisplay = (hDisplaySize / 8) - 1;
- hStart = (hDisplaySize + video_mode->right_margin) / 8 + 2;
- hEnd = (hDisplaySize + video_mode->right_margin +
- video_mode->hsync_len) / 8 - 1;
- hTotal = (hDisplaySize + video_mode->right_margin +
- video_mode->hsync_len + video_mode->left_margin) / 8 - 1;
- height = video_mode->yres_virtual;
- vDisplay = video_mode->yres - 1;
- vStart = video_mode->yres + video_mode->lower_margin - 1;
- vEnd = video_mode->yres + video_mode->lower_margin +
- video_mode->vsync_len - 1;
- vTotal = video_mode->yres + video_mode->lower_margin +
- video_mode->vsync_len + video_mode->upper_margin + 2;
- dotClock = 1000000000 / video_mode->pixclock;
+ hStart = (hDisplaySize + info->var.right_margin) / 8 + 2;
+ hEnd = (hDisplaySize + info->var.right_margin +
+ info->var.hsync_len) / 8 - 1;
+ hTotal = (hDisplaySize + info->var.right_margin +
+ info->var.hsync_len + info->var.left_margin) / 8 - 1;
+ height = info->var.yres_virtual;
+ vDisplay = info->var.yres - 1;
+ vStart = info->var.yres + info->var.lower_margin - 1;
+ vEnd = info->var.yres + info->var.lower_margin +
+ info->var.vsync_len - 1;
+ vTotal = info->var.yres + info->var.lower_margin +
+ info->var.vsync_len + info->var.upper_margin + 2;
+ dotClock = 1000000000 / info->var.pixclock;
memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
@@ -899,83 +645,19 @@ static void riva_load_video_mode(struct rivafb_info *rinfo,
newmode.ext.width = width;
newmode.ext.height = height;
- rinfo->riva.CalcStateExt(&rinfo->riva, &newmode.ext, bpp, width,
+ par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
hDisplaySize, hDisplay, hStart, hEnd,
hTotal, height, vDisplay, vStart, vEnd,
vTotal, dotClock);
- rinfo->current_state = newmode;
- riva_load_state(rinfo, &rinfo->current_state);
-
- rinfo->riva.LockUnlock(&rinfo->riva, 0); /* important for HW cursor */
- rivafb_download_cursor(rinfo);
-}
-
-/**
- * riva_board_list_add - maintains board list
- * @board_list: root node of list of boards
- * @new_node: new node to be added
- *
- * DESCRIPTION:
- * Adds @new_node to the list referenced by @board_list.
- *
- * RETURNS:
- * New root node
- *
- * CALLED FROM:
- * rivafb_init_one()
- */
-static struct rivafb_info *riva_board_list_add(struct rivafb_info *board_list,
- struct rivafb_info *new_node)
-{
- struct rivafb_info *i_p = board_list;
-
- new_node->next = NULL;
-
- if (board_list == NULL)
- return new_node;
-
- while (i_p->next != NULL)
- i_p = i_p->next;
- i_p->next = new_node;
-
- return board_list;
-}
-
-/**
- * riva_board_list_del - maintains board list
- * @board_list: root node of list of boards
- * @del_node: node to be removed
- *
- * DESCRIPTION:
- * Removes @del_node from the list referenced by @board_list.
- *
- * RETURNS:
- * New root node
- *
- * CALLED FROM:
- * rivafb_remove_one()
- */
-static struct rivafb_info *riva_board_list_del(struct rivafb_info *board_list,
- struct rivafb_info *del_node)
-{
- struct rivafb_info *i_p = board_list;
-
- if (board_list == del_node)
- return del_node->next;
-
- while (i_p->next != del_node)
- i_p = i_p->next;
- i_p->next = del_node->next;
-
- return board_list;
+ par->current_state = newmode;
+ riva_load_state(par, &par->current_state);
}
/**
* rivafb_do_maximize -
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @info: pointer to fb_info object containing info for current riva board
* @var:
- * @v:
* @nom:
* @den:
*
@@ -989,9 +671,8 @@ static struct rivafb_info *riva_board_list_del(struct rivafb_info *board_list,
* CALLED FROM:
* rivafb_set_var()
*/
-static int rivafb_do_maximize(struct rivafb_info *rinfo,
+static int rivafb_do_maximize(struct fb_info *info,
struct fb_var_screeninfo *var,
- struct fb_var_screeninfo *v,
int nom, int den)
{
static struct {
@@ -1007,12 +688,12 @@ static int rivafb_do_maximize(struct rivafb_info *rinfo,
int i;
/* use highest possible virtual resolution */
- if (v->xres_virtual == -1 && v->yres_virtual == -1) {
+ if (var->xres_virtual == -1 && var->yres_virtual == -1) {
printk(KERN_WARNING PFX
"using maximum available virtual resolution\n");
for (i = 0; modes[i].xres != -1; i++) {
if (modes[i].xres * nom / den * modes[i].yres <
- rinfo->ram_amount / 2)
+ info->fix.smem_len / 2)
break;
}
if (modes[i].xres == -1) {
@@ -1021,26 +702,26 @@ static int rivafb_do_maximize(struct rivafb_info *rinfo,
DPRINTK("EXIT - EINVAL error\n");
return -EINVAL;
}
- v->xres_virtual = modes[i].xres;
- v->yres_virtual = modes[i].yres;
+ var->xres_virtual = modes[i].xres;
+ var->yres_virtual = modes[i].yres;
printk(KERN_INFO PFX
"virtual resolution set to maximum of %dx%d\n",
- v->xres_virtual, v->yres_virtual);
- } else if (v->xres_virtual == -1) {
- v->xres_virtual = (rinfo->ram_amount * den /
- (nom * v->yres_virtual * 2)) & ~15;
+ var->xres_virtual, var->yres_virtual);
+ } else if (var->xres_virtual == -1) {
+ var->xres_virtual = (info->fix.smem_len * den /
+ (nom * var->yres_virtual * 2)) & ~15;
printk(KERN_WARNING PFX
- "setting virtual X resolution to %d\n", v->xres_virtual);
- } else if (v->yres_virtual == -1) {
- v->xres_virtual = (v->xres_virtual + 15) & ~15;
- v->yres_virtual = rinfo->ram_amount * den /
- (nom * v->xres_virtual * 2);
+ "setting virtual X resolution to %d\n", var->xres_virtual);
+ } else if (var->yres_virtual == -1) {
+ var->xres_virtual = (var->xres_virtual + 15) & ~15;
+ var->yres_virtual = info->fix.smem_len * den /
+ (nom * var->xres_virtual * 2);
printk(KERN_WARNING PFX
- "setting virtual Y resolution to %d\n", v->yres_virtual);
+ "setting virtual Y resolution to %d\n", var->yres_virtual);
} else {
- v->xres_virtual = (v->xres_virtual + 15) & ~15;
- if (v->xres_virtual * nom / den * v->yres_virtual > rinfo->ram_amount) {
+ var->xres_virtual = (var->xres_virtual + 15) & ~15;
+ if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
printk(KERN_ERR PFX
"mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
var->xres, var->yres, var->bits_per_pixel);
@@ -1049,397 +730,535 @@ static int rivafb_do_maximize(struct rivafb_info *rinfo,
}
}
- if (v->xres_virtual * nom / den >= 8192) {
+ if (var->xres_virtual * nom / den >= 8192) {
printk(KERN_WARNING PFX
"virtual X resolution (%d) is too high, lowering to %d\n",
- v->xres_virtual, 8192 * den / nom - 16);
- v->xres_virtual = 8192 * den / nom - 16;
+ var->xres_virtual, 8192 * den / nom - 16);
+ var->xres_virtual = 8192 * den / nom - 16;
}
- if (v->xres_virtual < v->xres) {
+ if (var->xres_virtual < var->xres) {
printk(KERN_ERR PFX
- "virtual X resolution (%d) is smaller than real\n", v->xres_virtual);
+ "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
return -EINVAL;
}
- if (v->yres_virtual < v->yres) {
+ if (var->yres_virtual < var->yres) {
printk(KERN_ERR PFX
- "virtual Y resolution (%d) is smaller than real\n", v->yres_virtual);
+ "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
return -EINVAL;
}
-
return 0;
}
+/* acceleration routines */
+inline void wait_for_idle(struct riva_par *par)
+{
+ while (par->riva.Busy(&par->riva));
+}
+/* set copy ROP, no mask */
+static void riva_setup_ROP(struct riva_par *par)
+{
+ RIVA_FIFO_FREE(par->riva, Patt, 5);
+ par->riva.Patt->Shape = 0;
+ par->riva.Patt->Color0 = 0xffffffff;
+ par->riva.Patt->Color1 = 0xffffffff;
+ par->riva.Patt->Monochrome[0] = 0xffffffff;
+ par->riva.Patt->Monochrome[1] = 0xffffffff;
+
+ RIVA_FIFO_FREE(par->riva, Rop, 1);
+ par->riva.Rop->Rop3 = 0xCC;
+}
-/* ------------------------------------------------------------------------- *
- *
- * internal fb_ops helper functions
- *
- * ------------------------------------------------------------------------- */
+void riva_setup_accel(struct riva_par *par)
+{
+ RIVA_FIFO_FREE(par->riva, Clip, 2);
+ par->riva.Clip->TopLeft = 0x0;
+ par->riva.Clip->WidthHeight = 0x80008000;
+ riva_setup_ROP(par);
+}
/**
- * riva_get_cmap_len - query current color map length
- * @var: standard kernel fb changeable data
- *
+ * rivafb_fillrect - hardware accelerated color fill function
+ * @info: pointer to fb_info structure
+ * @rect: pointer to fb_fillrect structure
+ *
* DESCRIPTION:
- * Get current color map length.
- *
- * RETURNS:
- * Length of color map
+ * This function fills up a region of framebuffer memory with a solid
+ * color with a choice of two different ROP's, copy or invert.
*
* CALLED FROM:
- * riva_getcolreg()
- * rivafb_setcolreg()
- * rivafb_get_cmap()
- * rivafb_set_cmap()
+ * framebuffer hook
*/
-static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
+static void rivafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
{
- int rc = 16; /* reasonable default */
+ struct riva_par *par = (struct riva_par *) info->par;
+ u_int color, rop = 0;
- assert(var != NULL);
+ if (info->var.bits_per_pixel == 8)
+ color = rect->color;
+ else
+ color = par->riva_palette[rect->color];
- switch (var->bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- rc = 256; /* pseudocolor... 256 entries HW palette */
+ switch (rect->rop) {
+ case ROP_XOR:
+ rop = 0x66;
break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 15:
- rc = 15; /* fix for 15 bpp depths on Riva 128 based cards */
- break;
- case 16:
- rc = 16; /* directcolor... 16 entries SW palette */
- break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- rc = 16; /* directcolor... 16 entries SW palette */
- break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-#endif
+ case ROP_COPY:
default:
- /* should not occur */
+ rop = 0xCC;
break;
}
- return rc;
+ RIVA_FIFO_FREE(par->riva, Rop, 1);
+ par->riva.Rop->Rop3 = rop;
+
+ RIVA_FIFO_FREE(par->riva, Bitmap, 1);
+ par->riva.Bitmap->Color1A = color;
+
+ RIVA_FIFO_FREE(par->riva, Bitmap, 2);
+ par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
+ (rect->dx << 16) | rect->dy;
+ par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
+ (rect->width << 16) | rect->height;
}
/**
- * riva_getcolreg
- * @regno: register index
- * @red: red component
- * @green: green component
- * @blue: blue component
- * @transp: transparency
- * @info: pointer to rivafb_info object containing info for current riva board
+ * rivafb_copyarea - hardware accelerated blit function
+ * @info: pointer to fb_info structure
+ * @region: pointer to fb_copyarea structure
*
* DESCRIPTION:
- * Read a single color register and split it into colors/transparent.
- * The return values must have a 16 bit magnitude.
- *
- * RETURNS:
- * Return != 0 for invalid regno.
+ * This copies an area of pixels from one location to another
*
* CALLED FROM:
- * rivafb_get_cmap()
- * rivafb_switch()
- * fbcmap.c:fb_get_cmap()
- * fbgen.c:fbgen_get_cmap()
- * fbgen.c:fbgen_switch()
+ * framebuffer hook
*/
-static int riva_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info)
+static void rivafb_copyarea(struct fb_info *info, struct fb_copyarea *region)
{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-
- if (regno >= riva_get_cmap_len(&rivainfo->currcon_display->var))
- return 1;
-
- *red = rivainfo->palette[regno].red;
- *green = rivainfo->palette[regno].green;
- *blue = rivainfo->palette[regno].blue;
- *transp = 0;
+ struct riva_par *par = (struct riva_par *) info->par;
- return 0;
+ RIVA_FIFO_FREE(par->riva, Blt, 3);
+ par->riva.Blt->TopLeftSrc = (region->sy << 16) | region->sx;
+ par->riva.Blt->TopLeftDst = (region->dy << 16) | region->dx;
+ par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
+ wait_for_idle(par);
}
+static u8 byte_rev[256] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
/**
- * rivafb_setcolreg
- * @regno: register index
- * @red: red component
- * @green: green component
- * @blue: blue component
- * @transp: transparency
- * @info: pointer to rivafb_info object containing info for current riva board
+ * rivafb_imageblit: hardware accelerated color expand function
+ * @info: pointer to fb_info structure
+ * @image: pointer to fb_image structure
*
* DESCRIPTION:
- * Set a single color register. The values supplied have a 16 bit
- * magnitude.
+ * If the source is a monochrome bitmap, the function fills up a a region
+ * of framebuffer memory with pixels whose color is determined by the bit
+ * setting of the bitmap, 1 - foreground, 0 - background.
*
- * RETURNS:
- * Return != 0 for invalid regno.
+ * If the source is not a monochrome bitmap, color expansion is not done.
+ * In this case, it is channeled to a software function.
*
* CALLED FROM:
- * rivafb_set_cmap()
- * fbcmap.c:fb_set_cmap()
- * fbgen.c:fbgen_get_cmap()
- * fbgen.c:do_install_cmap()
- * fbgen.c:fbgen_set_var()
- * fbgen.c:fbgen_switch()
- * fbgen.c:fbgen_blank()
- * fbgen.c:fbgen_blank()
+ * framebuffer hook
*/
-static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
+static void rivafb_imageblit(struct fb_info *info, struct fb_image *image)
{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
- RIVA_HW_INST *chip = &rivainfo->riva;
- struct display *p;
-
- DPRINTK("ENTER\n");
-
- assert(rivainfo != NULL);
- assert(rivainfo->currcon_display != NULL);
-
- p = rivainfo->currcon_display;
+ struct riva_par *par = (struct riva_par *) info->par;
+ u8 *cdat = image->data, *dat;
+ int w, h, dx, dy;
+ volatile u32 *d;
+ u32 fgx = 0, bgx = 0, size, width, mod;
+ int i, j;
+
+ if (image->depth != 1) {
+ wait_for_idle(par);
+ cfb_imageblit(info, image);
+ return;
+ }
- if (regno >= riva_get_cmap_len(&p->var))
- return -EINVAL;
+ w = image->width;
+ h = image->height;
+ dx = image->dx;
+ dy = image->dy;
- rivainfo->palette[regno].red = red;
- rivainfo->palette[regno].green = green;
- rivainfo->palette[regno].blue = blue;
+ width = (w + 7)/8;
- if (p->var.grayscale) {
- /* gray = 0.30*R + 0.59*G + 0.11*B */
- red = green = blue =
- (red * 77 + green * 151 + blue * 28) >> 8;
+ size = width * h;
+ dat = cdat;
+ for (i = 0; i < size; i++) {
+ *dat = byte_rev[*dat];
+ dat++;
}
- switch (p->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
+ switch (info->var.bits_per_pixel) {
case 8:
- /* "transparent" stuff is completely ignored. */
- riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
+ fgx = image->fg_color | ~((1 << 8) - 1);
+ bgx = image->bg_color | ~((1 << 8) - 1);
+
break;
-#endif /* FBCON_HAS_CFB8 */
-#ifdef FBCON_HAS_CFB16
case 16:
- assert(regno < 16);
- if (p->var.green.length == 5) {
- /* 0rrrrrgg gggbbbbb */
- rivainfo->con_cmap.cfb16[regno] =
- ((red & 0xf800) >> 1) |
- ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
- } else {
- /* rrrrrggg gggbbbbb */
- rivainfo->con_cmap.cfb16[regno] =
- ((red & 0xf800) >> 0) |
- ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
+ /* set alpha bit */
+ if (info->var.green.length == 5) {
+ fgx = 1 << 15;
+ bgx = fgx;
}
- break;
-#endif /* FBCON_HAS_CFB16 */
-#ifdef FBCON_HAS_CFB32
+ /* Fall through... */
case 32:
- assert(regno < 16);
- rivainfo->con_cmap.cfb32[regno] =
- ((red & 0xff00) << 8) |
- ((green & 0xff00)) | ((blue & 0xff00) >> 8);
- break;
-#endif /* FBCON_HAS_CFB32 */
- default:
- /* do nothing */
+ fgx |= par->riva_palette[image->fg_color];
+ bgx |= par->riva_palette[image->bg_color];
break;
}
- return 0;
-}
-
+ RIVA_FIFO_FREE(par->riva, Bitmap, 7);
+ par->riva.Bitmap->ClipE.TopLeft = (dy << 16) | (dx & 0xFFFF);
+ par->riva.Bitmap->ClipE.BottomRight = (((dy + h) << 16) |
+ ((dx + w) & 0xffff));
+ par->riva.Bitmap->Color0E = bgx;
+ par->riva.Bitmap->Color1E = fgx;
+ par->riva.Bitmap->WidthHeightInE = (h << 16) | ((w + 31) & ~31);
+ par->riva.Bitmap->WidthHeightOutE = (h << 16) | ((w + 31) & ~31);
+ par->riva.Bitmap->PointE = (dy << 16) | (dx & 0xFFFF);
+
+ d = &par->riva.Bitmap->MonochromeData01E;
+
+ mod = width % 4;
+
+ if (width >= 4) {
+ while (h--) {
+ size = width / 4;
+ while (size >= 16) {
+ RIVA_FIFO_FREE(par->riva, Bitmap, 16);
+ for (i = 0; i < 16; i++)
+ d[i] = *((u32 *)cdat)++;
+ size -= 16;
+ }
+
+ if (size) {
+ RIVA_FIFO_FREE(par->riva, Bitmap, size);
+ for (i = 0; i < size; i++)
+ d[i] = *((u32 *) cdat)++;
+ }
+
+ if (mod) {
+ u32 tmp;
+ RIVA_FIFO_FREE(par->riva, Bitmap, 1);
+ for (i = 0; i < mod; i++)
+ ((u8 *)&tmp)[i] = *cdat++;
+ d[i] = tmp;
+ }
+ }
+ }
+ else {
+ u32 k, tmp;
+ for (i = h; i > 0; i-=16) {
+ if (i >= 16)
+ size = 16;
+ else
+ size = i;
+ RIVA_FIFO_FREE(par->riva, Bitmap, size);
+ for (j = 0; j < size; j++) {
+ for (k = 0; k < width; k++)
+ ((u8 *)&tmp)[k] = *cdat++;
+ d[j] = tmp;
+ }
+ }
+ }
+}
-/* ------------------------------------------------------------------------- *
+/**
+ * rivafb_cursor - hardware cursor function
+ * @info: pointer to info structure
+ * @cursor: pointer to fbcursor structure
*
- * framebuffer operations
+ * DESCRIPTION:
+ * A cursor function that supports displaying a cursor image via hardware.
+ * Within the kernel, copy and invert rops are supported. If exported
+ * to user space, only the copy rop will be supported.
*
- * ------------------------------------------------------------------------- */
-
-static int rivafb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
+ * CALLED FROM
+ * framebuffer hook
+ */
+static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
- struct display *p;
-
- DPRINTK("ENTER\n");
-
- assert(fix != NULL);
- assert(info != NULL);
- assert(rivainfo->drvr_name && rivainfo->drvr_name[0]);
- assert(rivainfo->fb_base_phys > 0);
- assert(rivainfo->ram_amount > 0);
-
- p = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- sprintf(fix->id, "nVidia %s", rivainfo->drvr_name);
+ static u8 data[MAX_CURS*MAX_CURS/8], mask[MAX_CURS*MAX_CURS/8];
+ struct riva_par *par = (struct riva_par *) info->par;
+ int i, j, d_idx = 0, s_idx = 0;
+ u16 flags = cursor->set, fg, bg;
+
+ /*
+ * Can't do invert if one of the operands (dest) is missing,
+ * ie, only opaque cursor supported. This should be
+ * standard for GUI apps.
+ */
+ if (cursor->dest == NULL && cursor->rop == ROP_XOR)
+ return 1;
- fix->smem_start = rivainfo->fb_base_phys;
- fix->smem_len = rivainfo->ram_amount;
+ if (par->cursor_reset) {
+ flags = FB_CUR_SETALL;
+ par->cursor_reset = 0;
+ }
- fix->type = p->type;
- fix->type_aux = p->type_aux;
- fix->visual = p->visual;
+ par->riva.ShowHideCursor(&par->riva, 0);
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- fix->ywrapstep = 0; /* FIXME: no ywrap for now */
+ if (flags & FB_CUR_SETPOS) {
+ u32 xx, yy, temp;
+
+ yy = cursor->image.dy - info->var.yoffset;
+ xx = cursor->image.dx - info->var.xoffset;
+ temp = xx & 0xFFFF;
+ temp |= yy << 16;
- fix->line_length = p->line_length;
+ *(par->riva.CURSORPOS) = temp;
+ }
- fix->mmio_start = rivainfo->ctrl_base_phys;
- fix->mmio_len = rivainfo->base0_region_size;
- fix->smem_start = rivainfo->fb_base_phys;
- fix->smem_len = rivainfo->base1_region_size;
+ if (flags & FB_CUR_SETSIZE) {
+ memset(data, 0, MAX_CURS * MAX_CURS/8);
+ memset(mask, 0, MAX_CURS * MAX_CURS/8);
+ memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
+ }
- switch (rivainfo->riva.Architecture) {
- case NV_ARCH_03:
- fix->accel = FB_ACCEL_NV3;
- break;
- case NV_ARCH_04: /* riva_hw.c now doesn't distinguish between TNT & TNT2 */
- fix->accel = FB_ACCEL_NV4;
- break;
- case NV_ARCH_10: /* FIXME: ID for GeForce */
- fix->accel = FB_ACCEL_NV4;
- break;
+ if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETDEST)) {
+ int bg_idx = cursor->image.bg_color;
+ int fg_idx = cursor->image.fg_color;
+
+ switch (cursor->rop) {
+ case ROP_XOR:
+ for (i = 0; i < cursor->image.height; i++) {
+ for (j = 0; j < (cursor->image.width + 7)/8;
+ j++) {
+ d_idx = i * MAX_CURS/8 + j;
+ data[d_idx] = byte_rev[((u8 *)cursor->image.data)[s_idx] ^
+ ((u8 *)cursor->dest)[s_idx]];
+ mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+ s_idx++;
+ }
+ }
+ break;
+ case ROP_COPY:
+ default:
+ for (i = 0; i < cursor->image.height; i++) {
+ for (j = 0; j < (cursor->image.width + 7)/8; j++) {
+ d_idx = i * MAX_CURS/8 + j;
+ data[d_idx] = byte_rev[((u8 *)cursor->image.data)[s_idx]];
+ mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+ s_idx++;
+ }
+ }
+ break;
+ }
+
+ bg = ((par->cmap[bg_idx].red & 0xf8) << 7) |
+ ((par->cmap[bg_idx].green & 0xf8) << 2) |
+ ((par->cmap[bg_idx].blue & 0xf8) >> 3) | 1 << 15;
+
+ fg = ((par->cmap[fg_idx].red & 0xf8) << 7) |
+ ((par->cmap[fg_idx].green & 0xf8) << 2) |
+ ((par->cmap[fg_idx].blue & 0xf8) >> 3) | 1 << 15;
+ par->riva.LockUnlock(&par->riva, 0);
+ rivafb_load_cursor_image(data, mask, par, cursor->image.width,
+ cursor->image.height, bg, fg);
}
-
- DPRINTK("EXIT, returning 0\n");
+
+ if (cursor->enable)
+ par->riva.ShowHideCursor(&par->riva, 1);
return 0;
}
-static int rivafb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+static int rivafb_sync(struct fb_info *info)
{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
+ struct riva_par *par = (struct riva_par *) info->par;
- DPRINTK("ENTER\n");
+ wait_for_idle(par);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- *
+ *
+ * internal fb_ops helper functions
+ *
+ * ------------------------------------------------------------------------- */
+
+/**
+ * riva_get_cmap_len - query current color map length
+ * @var: standard kernel fb changeable data
+ *
+ * DESCRIPTION:
+ * Get current color map length.
+ *
+ * RETURNS:
+ * Length of color map
+ *
+ * CALLED FROM:
+ * riva_getcolreg()
+ * rivafb_setcolreg()
+ * rivafb_get_cmap()
+ * rivafb_set_cmap()
+ */
+static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
+{
+ int rc = 16; /* reasonable default */
- assert(info != NULL);
assert(var != NULL);
- *var = (con < 0) ? rivainfo->disp.var : fb_display[con].var;
+ switch (var->green.length) {
+ case 5:
+ rc = 32; /* fix for 15 bpp depths on Riva 128 based cards */
+ break;
+ case 6:
+ rc = 64; /* directcolor... 16 entries SW palette */
+ break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+ default:
+ rc = 256; /* pseudocolor... 256 entries HW palette */
+ break;
+ }
- DPRINTK("EXIT, returning 0\n");
+ return rc;
+}
+/* ------------------------------------------------------------------------- *
+ *
+ * framebuffer operations
+ *
+ * ------------------------------------------------------------------------- */
+static int rivafb_open(struct fb_info *info, int user)
+{
+ struct riva_par *par = (struct riva_par *) info->par;
+ int cnt = atomic_read(&par->ref_count);
+
+ if (!cnt) {
+ memset(&par->state, 0, sizeof(struct fb_vgastate));
+ par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
+ /* save the DAC for Riva128 */
+ if (par->riva.Architecture == NV_ARCH_03)
+ par->state.flags |= VGA_SAVE_CMAP;
+ fb_save_vga(&par->state);
+
+ RivaGetConfig(&par->riva);
+ riva_save_state(par, &par->initial_state);
+ }
+
+ atomic_inc(&par->ref_count);
return 0;
}
-static int rivafb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+static int rivafb_release(struct fb_info *info, int user)
{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
- struct display *dsp;
- struct fb_var_screeninfo v;
- int nom, den; /* translating from pixels->bytes */
- int accel;
- unsigned chgvar = 0;
-
- DPRINTK("ENTER\n");
+ struct riva_par *par = (struct riva_par *) info->par;
+ int cnt = atomic_read(&par->ref_count);
- assert(info != NULL);
- assert(var != NULL);
+ if (!cnt)
+ return -EINVAL;
+ if (cnt == 1) {
+ par->riva.LockUnlock(&par->riva, 0);
+ par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
- DPRINTK("Requested: %dx%dx%d\n", var->xres, var->yres,
- var->bits_per_pixel);
- DPRINTK(" virtual: %dx%d\n", var->xres_virtual,
- var->yres_virtual);
- DPRINTK(" offset: (%d,%d)\n", var->xoffset, var->yoffset);
- DPRINTK("grayscale: %d\n", var->grayscale);
-
- dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
- assert(dsp != NULL);
-
- /* if var has changed, we should call changevar() later */
- if (con >= 0) {
- chgvar = ((dsp->var.xres != var->xres) ||
- (dsp->var.yres != var->yres) ||
- (dsp->var.xres_virtual != var->xres_virtual) ||
- (dsp->var.yres_virtual != var->yres_virtual) ||
- (dsp->var.accel_flags != var->accel_flags) ||
- (dsp->var.bits_per_pixel != var->bits_per_pixel)
- || memcmp(&dsp->var.red, &var->red,
- sizeof(var->red))
- || memcmp(&dsp->var.green, &var->green,
- sizeof(var->green))
- || memcmp(&dsp->var.blue, &var->blue,
- sizeof(var->blue)));
+ fb_restore_vga(&par->state);
+ par->riva.LockUnlock(&par->riva, 1);
}
- memcpy(&v, var, sizeof(v));
+ atomic_dec(&par->ref_count);
+
+ return 0;
+}
- accel = v.accel_flags & FB_ACCELF_TEXT;
+static int rivafb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct riva_par *par = (struct riva_par *) info->par;
+ int nom, den; /* translating from pixels->bytes */
+
+ if (par->riva.Architecture == NV_ARCH_03 &&
+ var->bits_per_pixel == 16)
+ var->bits_per_pixel = 15;
- switch (v.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
+ switch (var->bits_per_pixel) {
case 1 ... 8:
- v.bits_per_pixel = 8;
+ var->bits_per_pixel = 8;
nom = 1;
den = 1;
- v.red.offset = 0;
- v.red.length = 8;
- v.green.offset = 0;
- v.green.length = 8;
- v.blue.offset = 0;
- v.blue.length = 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;
-#endif
-#ifdef FBCON_HAS_CFB16
case 9 ... 15:
- v.green.length = 5;
+ var->green.length = 5;
/* fall through */
case 16:
- v.bits_per_pixel = 16;
+ var->bits_per_pixel = 16;
nom = 2;
den = 1;
- if (v.green.length == 5) {
+ if (var->green.length == 5) {
/* 0rrrrrgg gggbbbbb */
- v.red.offset = 10;
- v.green.offset = 5;
- v.blue.offset = 0;
- v.red.length = 5;
- v.green.length = 5;
- v.blue.length = 5;
+ var->red.offset = 10;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 5;
+ var->blue.length = 5;
} else {
/* rrrrrggg gggbbbbb */
- v.red.offset = 11;
- v.green.offset = 5;
- v.blue.offset = 0;
- v.red.length = 5;
- v.green.length = 6;
- v.blue.length = 5;
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
}
break;
-#endif
-#ifdef FBCON_HAS_CFB32
case 17 ... 32:
- v.bits_per_pixel = 32;
+ var->bits_per_pixel = 32;
nom = 4;
den = 1;
- v.red.offset = 16;
- v.green.offset = 8;
- v.blue.offset = 0;
- v.red.length = 8;
- v.green.length = 8;
- v.blue.length = 8;
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
break;
-#endif
default:
printk(KERN_ERR PFX
"mode %dx%dx%d rejected...color depth not supported.\n",
@@ -1448,122 +1267,53 @@ static int rivafb_set_var(struct fb_var_screeninfo *var, int con,
return -EINVAL;
}
- if (rivafb_do_maximize(rivainfo, var, &v, nom, den) < 0)
+ if (rivafb_do_maximize(info, var, nom, den) < 0)
return -EINVAL;
- if (v.xoffset < 0)
- v.xoffset = 0;
- if (v.yoffset < 0)
- v.yoffset = 0;
+ if (var->xoffset < 0)
+ var->xoffset = 0;
+ if (var->yoffset < 0)
+ var->yoffset = 0;
/* truncate xoffset and yoffset to maximum if too high */
- if (v.xoffset > v.xres_virtual - v.xres)
- v.xoffset = v.xres_virtual - v.xres - 1;
-
- if (v.yoffset > v.yres_virtual - v.yres)
- v.yoffset = v.yres_virtual - v.yres - 1;
-
- v.red.msb_right =
- v.green.msb_right =
- v.blue.msb_right =
- v.transp.offset = v.transp.length = v.transp.msb_right = 0;
-
- switch (v.activate & FB_ACTIVATE_MASK) {
- case FB_ACTIVATE_TEST:
- DPRINTK("EXIT - FB_ACTIVATE_TEST\n");
- return 0;
- case FB_ACTIVATE_NXTOPEN: /* ?? */
- case FB_ACTIVATE_NOW:
- break; /* continue */
- default:
- DPRINTK("EXIT - unknown activation type\n");
- return -EINVAL; /* unknown */
- }
-
- memcpy(&dsp->var, &v, sizeof(v));
- if (chgvar) {
- riva_set_dispsw(rivainfo, dsp);
-
- if (accel) {
- if (nomove)
- dsp->scrollmode = SCROLL_YNOMOVE;
- else
- dsp->scrollmode = 0;
- } else
- dsp->scrollmode = SCROLL_YREDRAW;
+ if (var->xoffset > var->xres_virtual - var->xres)
+ var->xoffset = var->xres_virtual - var->xres - 1;
- if (info && info->changevar)
- info->changevar(con);
- }
+ if (var->yoffset > var->yres_virtual - var->yres)
+ var->yoffset = var->yres_virtual - var->yres - 1;
- rivafb_create_cursor(rivainfo, fontwidth(dsp), fontheight(dsp));
- riva_load_video_mode(rivainfo, &v);
- if (accel) riva_setup_accel(rivainfo);
-
- DPRINTK("EXIT, returning 0\n");
+ var->red.msb_right =
+ var->green.msb_right =
+ var->blue.msb_right =
+ var->transp.offset = var->transp.length = var->transp.msb_right = 0;
return 0;
}
-static int rivafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
+static int rivafb_set_par(struct fb_info *info)
{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
- struct display *dsp;
-
- DPRINTK("ENTER\n");
-
- assert(rivainfo != NULL);
- assert(cmap != NULL);
-
- dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
- if (con == info->currcon) { /* current console? */
- int rc = fb_get_cmap(cmap, kspc, riva_getcolreg, info);
- DPRINTK("EXIT - returning %d\n", rc);
- return rc;
- } else if (dsp->cmap.len) /* non default colormap? */
- fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap
- (riva_get_cmap_len(&dsp->var)), cmap,
- kspc ? 0 : 2);
-
- DPRINTK("EXIT, returning 0\n");
-
- return 0;
-}
-
-static int rivafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
- struct display *dsp;
- unsigned int cmap_len;
-
- DPRINTK("ENTER\n");
-
- assert(rivainfo != NULL);
- assert(cmap != NULL);
-
- dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
- cmap_len = riva_get_cmap_len(&dsp->var);
- if (dsp->cmap.len != cmap_len) {
- int err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);
- if (err) {
- DPRINTK("EXIT - returning %d\n", err);
- return err;
- }
+ struct riva_par *par = (struct riva_par *) info->par;
+
+ //rivafb_create_cursor(info, fontwidth(dsp), fontheight(dsp));
+ riva_load_video_mode(info);
+ if (info->var.accel_flags) {
+ riva_setup_accel(par);
+ info->fbops->fb_fillrect = rivafb_fillrect;
+ info->fbops->fb_copyarea = rivafb_copyarea;
+ info->fbops->fb_imageblit = rivafb_imageblit;
+ info->fbops->fb_cursor = rivafb_cursor;
+ info->fbops->fb_sync = rivafb_sync;
+ }
+ else {
+ info->fbops->fb_fillrect = cfb_fillrect;
+ info->fbops->fb_copyarea = cfb_copyarea;
+ info->fbops->fb_imageblit = cfb_imageblit;
+ info->fbops->fb_cursor = soft_cursor;
+ info->fbops->fb_sync = NULL;
}
- if (con == info->currcon) { /* current console? */
- int rc = fb_set_cmap(cmap, kspc, info);
- DPRINTK("EXIT - returning %d\n", rc);
- return rc;
- } else
- fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);
-
- DPRINTK("EXIT, returning 0\n");
+ info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
return 0;
}
@@ -1580,135 +1330,58 @@ static int rivafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
*
* This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
*/
-static int rivafb_pan_display(struct fb_var_screeninfo *var, int con,
+static int rivafb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
+ struct riva_par *par = (struct riva_par *) info->par;
unsigned int base;
- struct display *dsp;
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-
- DPRINTK("ENTER\n");
-
- assert(rivainfo != NULL);
-
+
if (var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
if (var->yoffset > (var->yres_virtual - var->yres))
return -EINVAL;
- dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
if (var->vmode & FB_VMODE_YWRAP) {
if (var->yoffset < 0
- || var->yoffset >= dsp->var.yres_virtual
+ || var->yoffset >= info->var.yres_virtual
|| var->xoffset) return -EINVAL;
} else {
- if (var->xoffset + dsp->var.xres > dsp->var.xres_virtual ||
- var->yoffset + dsp->var.yres > dsp->var.yres_virtual)
+ if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+ var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
}
- base = var->yoffset * dsp->line_length + var->xoffset;
+ base = var->yoffset * info->fix.line_length + var->xoffset;
- if (con == info->currcon) {
- rivainfo->riva.SetStartAddress(&rivainfo->riva, base);
- }
+ par->riva.SetStartAddress(&par->riva, base);
- dsp->var.xoffset = var->xoffset;
- dsp->var.yoffset = var->yoffset;
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
if (var->vmode & FB_VMODE_YWRAP)
- dsp->var.vmode |= FB_VMODE_YWRAP;
+ info->var.vmode |= FB_VMODE_YWRAP;
else
- dsp->var.vmode &= ~FB_VMODE_YWRAP;
-
- DPRINTK("EXIT, returning 0\n");
-
- return 0;
-}
-
-static int rivafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, int con, struct fb_info *info)
-{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-
- DPRINTK("ENTER\n");
-
- assert(rivainfo != NULL);
-
- /* no rivafb-specific ioctls */
-
- DPRINTK("EXIT, returning -EINVAL\n");
-
- return -EINVAL;
-}
-
-static int rivafb_rasterimg(struct fb_info *info, int start)
-{
- struct rivafb_info *rinfo = (struct rivafb_info *)info;
-
- wait_for_idle(rinfo);
-
- return 0;
-}
-
-static int rivafb_switch(int con, struct fb_info *info)
-{
- struct rivafb_info *rivainfo = (struct rivafb_info *)info;
- struct fb_cmap *cmap;
- struct display *dsp;
-
- DPRINTK("ENTER\n");
-
- assert(rivainfo != NULL);
+ info->var.vmode &= ~FB_VMODE_YWRAP;
- dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
- if (info->currcon >= 0) {
- /* Do we have to save the colormap? */
- cmap = &(rivainfo->currcon_display->cmap);
- DPRINTK("switch1: con = %d, cmap.len = %d\n",
- info->currcon, cmap->len);
-
- if (cmap->len) {
- DPRINTK("switch1a: %p %p %p %p\n", cmap->red,
- cmap->green, cmap->blue, cmap->transp);
- fb_get_cmap(cmap, 1, riva_getcolreg, info);
- }
- }
- info->currcon = con;
- rivainfo->currcon_display = dsp;
-
- rivafb_set_var(&dsp->var, con, info);
- riva_set_dispsw(rivainfo, dsp);
+ /*
+ * HACK: The hardware cursor occasionally disappears during fast scrolling.
+ * We just reset the cursor each time we change the start address.
+ * This also has a beneficial side effect of restoring the cursor
+ * image when switching from X.
+ */
+ par->cursor_reset = 1;
DPRINTK("EXIT, returning 0\n");
return 0;
}
-static int rivafb_updatevar(int con, struct fb_info *info)
-{
- int rc;
-
- DPRINTK("ENTER\n");
-
- rc = (con < 0) ? -EINVAL : rivafb_pan_display(&fb_display[con].var,
- con, info);
- DPRINTK("EXIT, returning %d\n", rc);
- return rc;
-}
-
static int rivafb_blank(int blank, struct fb_info *info)
{
+ struct riva_par *par = (struct riva_par *) info->par;
unsigned char tmp, vesa;
- struct rivafb_info *rinfo = (struct rivafb_info *)info;
-
- DPRINTK("ENTER\n");
-
- assert(rinfo != NULL);
- tmp = SEQin(rinfo, 0x01) & ~0x20; /* screen on/off */
- vesa = CRTCin(rinfo, 0x1a) & ~0xc0; /* sync on/off */
+ tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
+ vesa = CRTCin(par, 0x1a) & ~0xc0; /* sync on/off */
if (blank) {
tmp |= 0x20;
@@ -1727,14 +1400,127 @@ static int rivafb_blank(int blank, struct fb_info *info)
}
}
- SEQout(rinfo, 0x01, tmp);
- CRTCout(rinfo, 0x1a, vesa);
+ SEQout(par, 0x01, tmp);
+ CRTCout(par, 0x1a, vesa);
DPRINTK("EXIT\n");
return 0;
}
+/**
+ * rivafb_setcolreg
+ * @regno: register index
+ * @red: red component
+ * @green: green component
+ * @blue: blue component
+ * @transp: transparency
+ * @info: pointer to rivafb_info object containing info for current riva board
+ *
+ * DESCRIPTION:
+ * Set a single color register. The values supplied have a 16 bit
+ * magnitude.
+ *
+ * RETURNS:
+ * Return != 0 for invalid regno.
+ *
+ * CALLED FROM:
+ * rivafb_set_cmap()
+ * fbcmap.c:fb_set_cmap()
+ * fbgen.c:fbgen_get_cmap()
+ * fbgen.c:do_install_cmap()
+ * fbgen.c:fbgen_set_var()
+ * fbgen.c:fbgen_switch()
+ * fbgen.c:fbgen_blank()
+ * fbgen.c:fbgen_blank()
+ */
+static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ struct riva_par *par = (struct riva_par *) info->par;
+ RIVA_HW_INST *chip = &par->riva;
+ int i;
+
+ if (regno >= riva_get_cmap_len(&info->var))
+ return -EINVAL;
+
+ if (info->var.grayscale) {
+ /* gray = 0.30*R + 0.59*G + 0.11*B */
+ red = green = blue =
+ (red * 77 + green * 151 + blue * 28) >> 8;
+ }
+
+ if (!regno) {
+ for (i = 0; i < 256; i++) {
+ par->cmap[i].red = 0;
+ par->cmap[i].green = 0;
+ par->cmap[i].blue = 0;
+ }
+ }
+ par->cmap[regno].red = (u8) red;
+ par->cmap[regno].green = (u8) green;
+ par->cmap[regno].blue = (u8) blue;
+
+ if (info->var.green.length == 5) {
+ /* RGB555: all components have 32 entries, 8 indices apart */
+ for (i = 0; i < 8; i++)
+ riva_wclut(chip, (regno*8)+i, (u8) red, (u8) green, (u8) blue);
+ }
+ else if (info->var.green.length == 6) {
+ /*
+ * RGB 565: red and blue have 32 entries, 8 indices apart, while
+ * green has 64 entries, 4 indices apart
+ */
+ if (regno < 32) {
+ for (i = 0; i < 8; i++) {
+ riva_wclut(chip, (regno*8)+i, (u8) red,
+ par->cmap[regno*2].green,
+ (u8) blue);
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ riva_wclut(chip, (regno*4)+i, par->cmap[regno/2].red,
+ (u8) green, par->cmap[regno/2].blue);
+
+ }
+ }
+ else {
+ riva_wclut(chip, regno, (u8) red, (u8) green, (u8) blue);
+ }
+ if (regno < 16) {
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ if (info->var.green.length == 5) {
+ /* 0rrrrrgg gggbbbbb */
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (regno << 10) | (regno << 5) | regno;
+ par->riva_palette[regno] =
+ ((red & 0xf800) >> 1) |
+ ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
+
+ } else {
+ /* rrrrrggg gggbbbbb */
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (regno << 11) | (regno << 6) | regno;
+ par->riva_palette[regno] = ((red & 0xf800) >> 0) |
+ ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
+ }
+ break;
+ case 32:
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (regno << 16) | (regno << 8) | regno;
+ par->riva_palette[regno] =
+ ((red & 0xff00) << 8) |
+ ((green & 0xff00)) | ((blue & 0xff00) >> 8);
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+ return 0;
+}
/* ------------------------------------------------------------------------- *
*
@@ -1745,294 +1531,341 @@ static int rivafb_blank(int blank, struct fb_info *info)
/* kernel interface */
static struct fb_ops riva_fb_ops = {
.owner = THIS_MODULE,
- .fb_get_fix = rivafb_get_fix,
- .fb_get_var = rivafb_get_var,
- .fb_set_var = rivafb_set_var,
- .fb_get_cmap = rivafb_get_cmap,
- .fb_set_cmap = rivafb_set_cmap,
+ .fb_open = rivafb_open,
+ .fb_release = rivafb_release,
+ .fb_check_var = rivafb_check_var,
+ .fb_set_par = rivafb_set_par,
.fb_setcolreg = rivafb_setcolreg,
- .fb_pan_display =rivafb_pan_display,
+ .fb_pan_display=rivafb_pan_display,
.fb_blank = rivafb_blank,
- .fb_ioctl = rivafb_ioctl,
- .fb_rasterimg = rivafb_rasterimg,
+ .fb_fillrect = rivafb_fillrect,
+ .fb_copyarea = rivafb_copyarea,
+ .fb_imageblit = rivafb_imageblit,
+ .fb_cursor = rivafb_cursor,
+ .fb_sync = rivafb_sync,
};
-static int __devinit riva_init_disp_var(struct rivafb_info *rinfo)
-{
-#ifndef MODULE
- if (mode_option)
- fb_find_mode(&rinfo->disp.var, &rinfo->info, mode_option,
- NULL, 0, NULL, 8);
-#endif
- return 0;
-}
-
-static int __devinit riva_init_disp(struct rivafb_info *rinfo)
-{
- struct fb_info *info;
- struct display *disp;
-
- DPRINTK("ENTER\n");
-
- assert(rinfo != NULL);
-
- info = &rinfo->info;
- disp = &rinfo->disp;
-
- disp->var = rivafb_default_var;
-
- if (noaccel)
- disp->var.accel_flags &= ~FB_ACCELF_TEXT;
- else
- disp->var.accel_flags |= FB_ACCELF_TEXT;
-
- info->disp = disp;
-
- /* FIXME: assure that disp->cmap is completely filled out */
-
- rinfo->currcon_display = disp;
-
- if ((riva_init_disp_var(rinfo)) < 0) {
- DPRINTK("EXIT, returning -1\n");
- return -1;
- }
-
- riva_set_dispsw(rinfo, disp);
-
- DPRINTK("EXIT, returning 0\n");
- return 0;
-
-}
-
-static int __devinit riva_set_fbinfo(struct rivafb_info *rinfo)
+static int __devinit riva_set_fbinfo(struct fb_info *info)
{
- struct fb_info *info;
-
- assert(rinfo != NULL);
-
- info = &rinfo->info;
+ unsigned int cmap_len;
- strcpy(info->modename, rinfo->drvr_name);
info->node = NODEV;
info->flags = FBINFO_FLAG_DEFAULT;
info->fbops = &riva_fb_ops;
- info->screen_base = rinfo->fb_base;
- /* FIXME: set monspecs to what??? */
+ info->var = rivafb_default_var;
+ info->fix = rivafb_fix;
+ /* FIXME: set monspecs to what??? */
info->display_fg = NULL;
- info->currcon = -1;
- strncpy(info->fontname, fontname, sizeof(info->fontname));
- info->fontname[sizeof(info->fontname) - 1] = 0;
-
- info->changevar = NULL;
- info->switch_con = rivafb_switch;
- info->updatevar = rivafb_updatevar;
-
- if (riva_init_disp(rinfo) < 0) /* must be done last */
- return -1;
+ info->pseudo_palette = pseudo_palette;
+ cmap_len = riva_get_cmap_len(&info->var);
+ fb_alloc_cmap(&info->cmap, cmap_len, 0);
+#ifndef MODULE
+ if (mode_option)
+ fb_find_mode(&info->var, info, mode_option,
+ NULL, 0, NULL, 8);
+#endif
return 0;
}
-
-
/* ------------------------------------------------------------------------- *
*
* PCI bus
*
* ------------------------------------------------------------------------- */
+static void __devinit rivafb_get_mem_len(struct riva_par *par,
+ struct fb_fix_screeninfo *fix)
+{
+ RIVA_HW_INST *chip = &par->riva;
+
+ switch (chip->Architecture) {
+ case NV_ARCH_03:
+ if (chip->PFB[0x00000000/4] & 0x00000020) {
+ if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
+ && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) {
+ /*
+ * SDRAM 128 ZX.
+ */
+ switch (chip->PFB[0x00000000/4] & 0x03) {
+ case 2:
+ fix->smem_len = 1024 * 1024 * 4;
+ break;
+ case 1:
+ fix->smem_len = 1024 * 1024 * 2;
+ break;
+ default:
+ fix->smem_len = 1024 * 1024 * 8;
+ break;
+ }
+ }
+ else {
+ fix->smem_len = 1024 * 1024 * 8;
+ }
+ }
+ else {
+ /*
+ * SGRAM 128.
+ */
+ switch (chip->PFB[0x00000000/4] & 0x00000003) {
+ case 0:
+ fix->smem_len = 1024 * 1024 * 8;
+ break;
+ case 2:
+ fix->smem_len = 1024 * 1024 * 4;
+ break;
+ default:
+ fix->smem_len = 1024 * 1024 * 2;
+ break;
+ }
+ }
+ break;
+ case NV_ARCH_04:
+ if (chip->PFB[0x00000000/4] & 0x00000100) {
+ fix->smem_len = (((chip->PFB[0x00000000/4] >> 12)
+ & 0x0F) * 1024 * 2 + 1024 * 2) * 1024;
+ }
+ else {
+ switch (chip->PFB[0x00000000/4] & 0x00000003) {
+ case 0:
+ fix->smem_len = 1024 * 1024 * 32;
+ break;
+ case 1:
+ fix->smem_len = 1024 * 1024 * 4;
+ break;
+ case 2:
+ fix->smem_len = 1024 * 1024 * 8;
+ break;
+ case 3:
+ default:
+ fix->smem_len = 1024 * 1024 * 16;
+ break;
+ }
+ }
+ break;
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF) {
+ case 0x02:
+ fix->smem_len = 1024 * 1024 * 2;
+ break;
+ case 0x04:
+ fix->smem_len = 1024 * 1024 * 4;
+ break;
+ case 0x08:
+ fix->smem_len = 1024 * 1024 * 8;
+ break;
+ case 0x10:
+ fix->smem_len = 1024 * 1024 * 16;
+ break;
+ case 0x20:
+ fix->smem_len = 1024 * 1024 * 32;
+ break;
+ case 0x40:
+ fix->smem_len = 1024 * 1024 * 64;
+ break;
+ case 0x80:
+ fix->smem_len = 1024 * 1024 * 128;
+ break;
+ default:
+ fix->smem_len = 1024 * 1024 * 16;
+ break;
+ }
+ }
+}
+
static int __devinit rivafb_init_one(struct pci_dev *pd,
const struct pci_device_id *ent)
{
- struct rivafb_info *rinfo;
struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
+ struct riva_par *default_par;
+ struct fb_info *info;
assert(pd != NULL);
assert(rci != NULL);
- rinfo = kmalloc(sizeof(struct rivafb_info), GFP_KERNEL);
- if (!rinfo)
+ info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
+ if (!info)
goto err_out;
- memset(rinfo, 0, sizeof(struct rivafb_info));
+ default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
+ if (!default_par)
+ goto err_out_kfree;
- rinfo->drvr_name = rci->name;
- rinfo->riva.Architecture = rci->arch_rev;
+ memset(info, 0, sizeof(struct fb_info));
+ memset(default_par, 0, sizeof(struct riva_par));
- rinfo->pd = pd;
- rinfo->base0_region_size = pci_resource_len(pd, 0);
- rinfo->base1_region_size = pci_resource_len(pd, 1);
+ strcat(rivafb_fix.id, rci->name);
+ default_par->riva.Architecture = rci->arch_rev;
- assert(rinfo->base0_region_size >= 0x00800000); /* from GGI */
- assert(rinfo->base1_region_size >= 0x01000000); /* from GGI */
+ rivafb_fix.mmio_len = pci_resource_len(pd, 0);
+ rivafb_fix.smem_len = pci_resource_len(pd, 1);
- rinfo->ctrl_base_phys = pci_resource_start(rinfo->pd, 0);
- rinfo->fb_base_phys = pci_resource_start(rinfo->pd, 1);
+ rivafb_fix.mmio_start = pci_resource_start(pd, 0);
+ rivafb_fix.smem_start = pci_resource_start(pd, 1);
- if (!request_mem_region(rinfo->ctrl_base_phys,
- rinfo->base0_region_size, "rivafb")) {
+ if (!request_mem_region(rivafb_fix.mmio_start,
+ rivafb_fix.mmio_len, "rivafb")) {
printk(KERN_ERR PFX "cannot reserve MMIO region\n");
goto err_out_kfree;
}
- if (!request_mem_region(rinfo->fb_base_phys,
- rinfo->base1_region_size, "rivafb")) {
- printk(KERN_ERR PFX "cannot reserve FB region\n");
- goto err_out_free_base0;
- }
-
- rinfo->ctrl_base = ioremap(rinfo->ctrl_base_phys,
- rinfo->base0_region_size);
- if (!rinfo->ctrl_base) {
+ default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
+ rivafb_fix.mmio_len);
+ if (!default_par->ctrl_base) {
printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
goto err_out_free_base1;
}
- rinfo->fb_base = ioremap(rinfo->fb_base_phys,
- rinfo->base1_region_size);
- if (!rinfo->fb_base) {
+ info->screen_base = ioremap(rivafb_fix.smem_start,
+ rivafb_fix.smem_len);
+ if (!info->screen_base) {
printk(KERN_ERR PFX "cannot ioremap FB base\n");
goto err_out_iounmap_ctrl;
}
-#ifdef CONFIG_MTRR
- if (!nomtrr) {
- rinfo->mtrr.vram = mtrr_add(rinfo->fb_base_phys,
- rinfo->base1_region_size, MTRR_TYPE_WRCOMB, 1);
- if (rinfo->mtrr.vram < 0) {
- printk(KERN_ERR PFX "unable to setup MTRR\n");
- } else {
- rinfo->mtrr.vram_valid = 1;
- /* let there be speed */
- printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
- }
- }
-#endif /* CONFIG_MTRR */
-
- rinfo->riva.EnableIRQ = 0;
- rinfo->riva.PRAMDAC = (unsigned *)(rinfo->ctrl_base + 0x00680000);
- rinfo->riva.PFB = (unsigned *)(rinfo->ctrl_base + 0x00100000);
- rinfo->riva.PFIFO = (unsigned *)(rinfo->ctrl_base + 0x00002000);
- rinfo->riva.PGRAPH = (unsigned *)(rinfo->ctrl_base + 0x00400000);
- rinfo->riva.PEXTDEV = (unsigned *)(rinfo->ctrl_base + 0x00101000);
- rinfo->riva.PTIMER = (unsigned *)(rinfo->ctrl_base + 0x00009000);
- rinfo->riva.PMC = (unsigned *)(rinfo->ctrl_base + 0x00000000);
- rinfo->riva.FIFO = (unsigned *)(rinfo->ctrl_base + 0x00800000);
-
- rinfo->riva.PCIO = (U008 *)(rinfo->ctrl_base + 0x00601000);
- rinfo->riva.PDIO = (U008 *)(rinfo->ctrl_base + 0x00681000);
- rinfo->riva.PVIO = (U008 *)(rinfo->ctrl_base + 0x000C0000);
-
- rinfo->riva.IO = (MISCin(rinfo) & 0x01) ? 0x3D0 : 0x3B0;
-
- switch (rinfo->riva.Architecture) {
+ default_par->riva.EnableIRQ = 0;
+ default_par->riva.PRAMDAC = (unsigned *)(default_par->ctrl_base +
+ 0x00680000);
+ default_par->riva.PFB = (unsigned *)(default_par->ctrl_base +
+ 0x00100000);
+ default_par->riva.PFIFO = (unsigned *)(default_par->ctrl_base +
+ 0x00002000);
+ default_par->riva.PGRAPH = (unsigned *)(default_par->ctrl_base +
+ 0x00400000);
+ default_par->riva.PEXTDEV = (unsigned *)(default_par->ctrl_base +
+ 0x00101000);
+ default_par->riva.PTIMER = (unsigned *)(default_par->ctrl_base +
+ 0x00009000);
+ default_par->riva.PMC = (unsigned *)(default_par->ctrl_base +
+ 0x00000000);
+ default_par->riva.FIFO = (unsigned *)(default_par->ctrl_base +
+ 0x00800000);
+
+ default_par->riva.PCIO = (U008 *)(default_par->ctrl_base + 0x00601000);
+ default_par->riva.PDIO = (U008 *)(default_par->ctrl_base + 0x00681000);
+ default_par->riva.PVIO = (U008 *)(default_par->ctrl_base + 0x000C0000);
+
+ default_par->riva.IO = (MISCin(default_par) & 0x01) ? 0x3D0 : 0x3B0;
+
+ switch (default_par->riva.Architecture) {
case NV_ARCH_03:
- rinfo->riva.PRAMIN = (unsigned *)(rinfo->fb_base + 0x00C00000);
+ default_par->riva.PRAMIN = (unsigned *)(info->screen_base +
+ 0x00C00000);
+ default_par->dclk_max = 256000000;
+ rivafb_fix.accel = FB_ACCEL_NV3;
break;
case NV_ARCH_04:
case NV_ARCH_10:
- rinfo->riva.PCRTC = (unsigned *)(rinfo->ctrl_base + 0x00600000);
- rinfo->riva.PRAMIN = (unsigned *)(rinfo->ctrl_base + 0x00710000);
+ case NV_ARCH_20:
+ default_par->riva.PCRTC = (unsigned *)(default_par->ctrl_base
+ + 0x00600000);
+ default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base
+ + 0x00710000);
+ default_par->dclk_max = 250000000;
+ rivafb_fix.accel = FB_ACCEL_NV4;
break;
}
- RivaGetConfig(&rinfo->riva);
+ rivafb_get_mem_len(default_par, &rivafb_fix);
- /* back to normal */
+ info->par = default_par;
- assert(rinfo->pd != NULL);
-
- /* unlock io */
- CRTCout(rinfo, 0x11, 0xFF); /* vgaHWunlock() + riva unlock (0x7F) */
- rinfo->riva.LockUnlock(&rinfo->riva, 0);
-
- riva_save_state(rinfo, &rinfo->initial_state);
-
- rinfo->ram_amount = rinfo->riva.RamAmountKBytes * 1024;
- rinfo->dclk_max = rinfo->riva.MaxVClockFreqKHz * 1000;
+ if (!request_mem_region(rivafb_fix.smem_start,
+ rivafb_fix.smem_len, "rivafb")) {
+ printk(KERN_ERR PFX "cannot reserve FB region\n");
+ goto err_out_free_base0;
+ }
+
+ info->screen_base = ioremap(rivafb_fix.smem_start,
+ rivafb_fix.smem_len);
+ if (!info->screen_base) {
+ printk(KERN_ERR PFX "cannot ioremap FB base\n");
+ goto err_out_iounmap_ctrl;
+ }
- if (!nohwcursor) rinfo->cursor = rivafb_init_cursor(rinfo);
+#ifdef CONFIG_MTRR
+ if (!nomtrr) {
+ default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,
+ rivafb_fix.smem_len,
+ MTRR_TYPE_WRCOMB, 1);
+ if (default_par->mtrr.vram < 0) {
+ printk(KERN_ERR PFX "unable to setup MTRR\n");
+ } else {
+ default_par->mtrr.vram_valid = 1;
+ /* let there be speed */
+ printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
+ }
+ }
+#endif /* CONFIG_MTRR */
- if (riva_set_fbinfo(rinfo) < 0) {
+ if (riva_set_fbinfo(info) < 0) {
printk(KERN_ERR PFX "error setting initial video mode\n");
goto err_out_cursor;
}
- if (register_framebuffer((struct fb_info *)rinfo) < 0) {
+ if (register_framebuffer(info) < 0) {
printk(KERN_ERR PFX
"error registering riva framebuffer\n");
goto err_out_load_state;
}
- riva_boards = riva_board_list_add(riva_boards, rinfo);
-
- pci_set_drvdata(pd, rinfo);
+ pci_set_drvdata(pd,info);
printk(KERN_INFO PFX
- "PCI nVidia NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
- rinfo->riva.Architecture,
+ "PCI nVidia NV%x framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
+ default_par->riva.Architecture,
RIVAFB_VERSION,
- rinfo->drvr_name,
- rinfo->ram_amount / (1024 * 1024),
- rinfo->fb_base_phys);
+ info->fix.id,
+ info->fix.smem_len / (1024 * 1024),
+ info->fix.smem_start);
return 0;
err_out_load_state:
- riva_load_state(rinfo, &rinfo->initial_state);
err_out_cursor:
- rivafb_exit_cursor(rinfo);
/* err_out_iounmap_fb: */
- iounmap(rinfo->fb_base);
+ iounmap(info->screen_base);
err_out_iounmap_ctrl:
- iounmap(rinfo->ctrl_base);
+ iounmap(default_par->ctrl_base);
err_out_free_base1:
- release_mem_region(rinfo->fb_base_phys, rinfo->base1_region_size);
+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
err_out_free_base0:
- release_mem_region(rinfo->ctrl_base_phys, rinfo->base0_region_size);
+ release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
err_out_kfree:
- kfree(rinfo);
+ kfree(info);
err_out:
return -ENODEV;
}
static void __devexit rivafb_remove_one(struct pci_dev *pd)
{
- struct rivafb_info *board = pci_get_drvdata(pd);
+ struct fb_info *info = pci_get_drvdata(pd);
+ struct riva_par *par = (struct riva_par *) info->par;
- if (!board)
+ if (!info)
return;
- riva_boards = riva_board_list_del(riva_boards, board);
-
- riva_load_state(board, &board->initial_state);
-
- unregister_framebuffer((struct fb_info *)board);
-
- rivafb_exit_cursor(board);
+ unregister_framebuffer(info);
#ifdef CONFIG_MTRR
- if (board->mtrr.vram_valid)
- mtrr_del(board->mtrr.vram, board->fb_base_phys,
- board->base1_region_size);
+ if (par->mtrr.vram_valid)
+ mtrr_del(par->mtrr.vram, info->fix.smem_start,
+ info->fix.smem_len);
#endif /* CONFIG_MTRR */
- iounmap(board->ctrl_base);
- iounmap(board->fb_base);
-
- release_mem_region(board->ctrl_base_phys,
- board->base0_region_size);
- release_mem_region(board->fb_base_phys,
- board->base1_region_size);
-
- kfree(board);
+ iounmap(par->ctrl_base);
+ iounmap(info->screen_base);
+ release_mem_region(info->fix.mmio_start,
+ info->fix.mmio_len);
+ release_mem_region(info->fix.smem_start,
+ info->fix.smem_len);
+ kfree(info);
pci_set_drvdata(pd, NULL);
}
-
-
/* ------------------------------------------------------------------------- *
*
* initialization
@@ -2050,30 +1883,11 @@ int __init rivafb_setup(char *options)
while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt)
continue;
- 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;
-
- } else if (!strncmp(this_opt, "noblink", 7)) {
- noblink = 1;
- } else if (!strncmp(this_opt, "noaccel", 7)) {
- noaccel = 1;
- } else if (!strncmp(this_opt, "nomove", 6)) {
- nomove = 1;
#ifdef CONFIG_MTRR
- } else if (!strncmp(this_opt, "nomtrr", 6)) {
+ if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
-#endif
- } else if (!strncmp(this_opt, "nohwcursor", 10)) {
- nohwcursor = 1;
} else
+#endif
mode_option = this_opt;
}
return 0;
@@ -2081,10 +1895,10 @@ int __init rivafb_setup(char *options)
#endif /* !MODULE */
static struct pci_driver rivafb_driver = {
- .name = "rivafb",
- .id_table = rivafb_pci_tbl,
- .probe = rivafb_init_one,
- .remove = __devexit_p(rivafb_remove_one),
+ name: "rivafb",
+ id_table: rivafb_pci_tbl,
+ probe: rivafb_init_one,
+ remove: __devexit_p(rivafb_remove_one),
};
@@ -2098,9 +1912,7 @@ static struct pci_driver rivafb_driver = {
int __init rivafb_init(void)
{
int err;
-#ifdef MODULE
- if (font) strncpy(fontname, font, sizeof(fontname)-1);
-#endif
+
err = pci_module_init(&rivafb_driver);
if (err)
return err;
@@ -2121,12 +1933,6 @@ MODULE_PARM(font, "s");
MODULE_PARM_DESC(font, "Specifies one of the compiled-in fonts (default=none)");
MODULE_PARM(noaccel, "i");
MODULE_PARM_DESC(noaccel, "Disables hardware acceleration (0 or 1=disabled) (default=0)");
-MODULE_PARM(nomove, "i");
-MODULE_PARM_DESC(nomove, "Enables YSCROLL_NOMOVE (0 or 1=enabled) (default=0)");
-MODULE_PARM(nohwcursor, "i");
-MODULE_PARM_DESC(nohwcursor, "Disables hardware cursor (0 or 1=disabled) (default=0)");
-MODULE_PARM(noblink, "i");
-MODULE_PARM_DESC(noblink, "Disables hardware cursor blinking (0 or 1=disabled) (default=0)");
#ifdef CONFIG_MTRR
MODULE_PARM(nomtrr, "i");
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/riva/riva_hw.h
index 708667d39ab6..22d056b0fd2e 100644
--- a/drivers/video/riva/riva_hw.h
+++ b/drivers/video/riva/riva_hw.h
@@ -74,6 +74,7 @@ typedef unsigned int U032;
#define NV_ARCH_03 0x03
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
+#define NV_ARCH_20 0x20
/***************************************************************************\
* *
* FIFO registers. *
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
index d0e64d2b0211..f36a1ea21521 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/riva/rivafb.h
@@ -3,11 +3,6 @@
#include <linux/config.h>
#include <linux/fb.h>
-#include <video/fbcon.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
#include "riva_hw.h"
/* GGI compatibility macros */
@@ -31,52 +26,20 @@ typedef struct {
unsigned char red, green, blue, transp;
} riva_cfb8_cmap_t;
-struct rivafb_info;
-struct rivafb_info {
- struct fb_info info; /* kernel framebuffer info */
-
+struct riva_par {
RIVA_HW_INST riva; /* interface to riva_hw.c */
- const char *drvr_name; /* Riva hardware board type */
-
- unsigned long ctrl_base_phys; /* physical control register base addr */
- unsigned long fb_base_phys; /* physical framebuffer base addr */
-
caddr_t ctrl_base; /* virtual control register base addr */
- caddr_t fb_base; /* virtual framebuffer base addr */
-
- unsigned ram_amount; /* amount of RAM on card, in bytes */
unsigned dclk_max; /* max DCLK */
struct riva_regs initial_state; /* initial startup video mode */
struct riva_regs current_state;
-
- struct display disp;
- int currcon;
- struct display *currcon_display;
-
- struct rivafb_info *next;
-
- struct pci_dev *pd; /* pointer to board's pci info */
- unsigned base0_region_size; /* size of control register region */
- unsigned base1_region_size; /* size of framebuffer region */
-
- struct riva_cursor *cursor;
-
- struct display_switch dispsw;
-
- riva_cfb8_cmap_t palette[256]; /* VGA DAC palette cache */
-
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
- union {
-#ifdef FBCON_HAS_CFB16
- u_int16_t cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u_int32_t cfb32[16];
-#endif
- } con_cmap;
-#endif /* FBCON_HAS_CFB16 | FBCON_HAS_CFB32 */
+ struct fb_vgastate state;
+ atomic_t ref_count;
+ riva_cfb8_cmap_t cmap[256]; /* VGA DAC palette cache */
+ u32 riva_palette[16];
+ u32 cursor_data[32 * 32/4];
+ int cursor_reset;
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
#endif
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index d8ac3095f2d0..e296037e6225 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1432,7 +1432,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
LCCR0 &= ~LCCR0_LEN; /* Disable LCD Controller */
schedule_timeout(20 * HZ / 1000);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
remove_wait_queue(&fbi->ctrlr_wait, &wait);
}
diff --git a/drivers/video/sbusfb.c b/drivers/video/sbusfb.c
index 35c12a2da743..dd152737110f 100644
--- a/drivers/video/sbusfb.c
+++ b/drivers/video/sbusfb.c
@@ -1066,7 +1066,7 @@ sizechange:
kfree(fb);
return;
}
- printk(KERN_INFO "fb%d: %s\n", GET_FB_IDX(fb->info.node), p);
+ printk(KERN_INFO "fb%d: %s\n", minor(fb->info.node), p);
}
static inline int known_card(char *name)
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 59400e61e448..fe9cc1d9c512 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -23,17 +23,16 @@
#include <asm/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
+#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/mtrr.h>
-#include <video/fbcon.h>
-
#define INCLUDE_TIMING_TABLE_DATA
-#define DBE_REG_BASE regs
-#include <video/sgivw.h>
+#define DBE_REG_BASE default_par.regs
+#include <asm/sgi-vwdbe.h>
struct sgivw_par {
- asregs *regs;
+ struct asregs *regs;
u32 cmap_fifo;
u_long timing_num;
};
@@ -46,11 +45,12 @@ struct sgivw_par {
*/
/* set by arch/i386/kernel/setup.c */
-u_long sgivwfb_mem_phys;
-u_long sgivwfb_mem_size;
+extern unsigned long sgivwfb_mem_phys;
+extern unsigned long sgivwfb_mem_size;
-static struct fb_info fb_info;
static struct sgivw_par default_par;
+static u32 pseudo_palette[17];
+static struct fb_info fb_info;
static int ypan = 0;
static int ywrap = 0;
@@ -60,7 +60,7 @@ static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
.visual = FB_VISUAL_PSEUDOCOLOR,
.mmio_start = DBE_REG_PHYS,
.mmio_len = DBE_REG_SIZE,
- .accel_flags = FB_ACCEL_NONE
+ .accel = FB_ACCEL_NONE
};
static struct fb_var_screeninfo sgivwfb_var __initdata = {
@@ -85,9 +85,6 @@ static struct fb_var_screeninfo sgivwfb_var __initdata = {
.vmode = FB_VMODE_NONINTERLACED
};
-/* console related variables */
-static struct display disp;
-
/*
* Interface used by the world
*/
@@ -104,15 +101,13 @@ static int sgivwfb_mmap(struct fb_info *info, struct file *file,
static struct fb_ops sgivwfb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_check_var = sgivwfb_check_var,
.fb_set_par = sgivwfb_set_par,
.fb_setcolreg = sgivwfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
.fb_mmap = sgivwfb_mmap,
};
@@ -159,8 +154,8 @@ static unsigned long bytes_per_pixel(int bpp)
static void dbe_TurnOffDma(void)
{
- int i;
unsigned int readVal;
+ int i;
// Check to see if things are already turned off:
// 1) Check to see if dbe is not using the internal dotclock.
@@ -226,7 +221,7 @@ static void dbe_TurnOffDma(void)
static int sgivwfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- int err, activate = var->activate;
+ struct sgivw_par *par = (struct sgivw_par *)info->par;
struct dbe_timing_info *timing;
u_long line_length;
u_long min_mode;
@@ -240,8 +235,8 @@ static int sgivwfb_check_var(struct fb_var_screeninfo *var,
if (var->vmode & FB_VMODE_CONUPDATE) {
var->vmode |= FB_VMODE_YWRAP;
- var->xoffset = display->var.xoffset;
- var->yoffset = display->var.yoffset;
+ var->xoffset = info->var.xoffset;
+ var->yoffset = info->var.yoffset;
}
/* XXX FIXME - forcing var's */
@@ -369,7 +364,7 @@ static int sgivwfb_set_par(struct fb_info *info)
u32 readVal, outputVal;
int wholeTilesX, maxPixelsPerTileX;
int frmWrite1, frmWrite2, frmWrite3b;
- dbe_timing_info_t *currentTiming; /* Current Video Timing */
+ struct dbe_timing_info_t *currentTiming; /* Current Video Timing */
int xpmax, ypmax; // Monitor resolution
int bytesPerPixel; // Bytes per pixel
@@ -705,11 +700,16 @@ int __init sgivwfb_init(void)
printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
sgivwfb_mem_phys, sgivwfb_mem_size / 1024);
- default_par.regs = (asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
+ if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {
+ printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");
+ goto fail_request_mem_region;
+ }
+ default_par.regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
if (!default_par.regs) {
printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
goto fail_ioremap_regs;
}
+
#ifdef CONFIG_MTRR
mtrr_add((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size,
MTRR_TYPE_WRCOMB, 1);
@@ -720,41 +720,29 @@ int __init sgivwfb_init(void)
sgivwfb_fix.ywrapstep = ywrap;
sgivwfb_fix.ypanstep = ypan;
- strcpy(fb_info.modename, sgivwfb_fix.id);
- fb_info.changevar = NULL;
fb_info.node = NODEV;
fb_info.fix = sgivwfb_fix;
fb_info.var = sgivwfb_var;
fb_info.fbops = &sgivwfb_ops;
fb_info.pseudo_palette = pseudo_palette;
fb_info.par = &default_par;
- fb_info.disp = &disp;
- fb_info.currcon = -1;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.screen_base =
- ioremap_nocache((unsigned long) sgivwfb_mem_phys,
- sgivwfb_mem_size);
+ fb_info.screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);
if (!fb_info.screen_base) {
printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
goto fail_ioremap_fbmem;
}
- /* turn on default video mode */
- gen_set_var(&fb_info->var, -1, &fb_info);
+ fb_alloc_cmap(&fb_info.cmap, 256, 0);
if (register_framebuffer(&fb_info) < 0) {
- printk(KERN_ERR
- "sgivwfb: couldn't register framebuffer\n");
+ printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
goto fail_register_framebuffer;
}
- printk(KERN_INFO
- "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.node), sgivwfb_mem_size >> 10);
-
+ printk(KERN_INFO "fb%d: SGI BDE frame buffer device, using %ldK of video memory\n", minor(fb_info.node, sgivwfb_mem_size >> 10);
return 0;
fail_register_framebuffer:
diff --git a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile
index 8987332dd1ce..c816cec01859 100644
--- a/drivers/video/sis/Makefile
+++ b/drivers/video/sis/Makefile
@@ -6,7 +6,7 @@ export-objs := sis_main.o
obj-$(CONFIG_FB_SIS) += sisfb.o
-sisfb-objs := sis_main.o init.o init301.o
+sisfb-objs := sis_main.o sis_accel.o init.o init301.o
include $(TOPDIR)/Rules.make
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
new file mode 100644
index 000000000000..fa0a1851f09b
--- /dev/null
+++ b/drivers/video/sis/sis_accel.c
@@ -0,0 +1,495 @@
+/*
+ * SiS 300/630/730/540/315/550/650/740 frame buffer driver
+ * for Linux kernels 2.4.x and 2.5.x
+ *
+ * 2D acceleration part
+ *
+ * Based on the X driver's sis300_accel.c which is
+ * Copyright Xavier Ducoin <x.ducoin@lectra.com>
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ * and sis310_accel.c which is
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ * (see http://www.winischhofer.net/
+ * for more information and updates)
+ */
+
+#include <linux/config.h>
+#include <linux/version.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/slab.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 <linux/pci.h>
+#include <linux/vt_kern.h>
+#include <linux/capability.h>
+#include <linux/fs.h>
+#include <linux/agp_backend.h>
+
+#include <linux/types.h>
+#include <linux/sisfb.h>
+
+#include <asm/io.h>
+#include <asm/mtrr.h>
+
+#include <video/fbcon.h>
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+#endif
+
+#include "osdef.h"
+#include "vgatypes.h"
+#include "vstruct.h"
+#include "sis_accel.h"
+
+extern struct video_info ivideo;
+extern VGA_ENGINE sisvga_engine;
+
+static const int sisALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0x88, /* dest &= src; DSa, GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+ 0xCC, /* dest = src; S, GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+/* same ROP but with Pattern as Source */
+static const int sisPatALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+ 0xF0, /* dest = src; P, GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
+static const unsigned char myrops[] = {
+ 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
+ };
+#endif
+
+/* 300 series */
+
+static void
+SiS300Sync(void)
+{
+ SiS300Idle
+}
+
+static void
+SiS310Sync(void)
+{
+ SiS310Idle
+}
+
+static void
+SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color)
+{
+ SiS300SetupDSTColorDepth(ivideo.DstColor);
+ SiS300SetupSRCPitch(ivideo.video_linelength)
+ SiS300SetupDSTRect(ivideo.video_linelength, -1)
+
+ if(trans_color != -1) {
+ SiS300SetupROP(0x0A)
+ SiS300SetupSRCTrans(trans_color)
+ SiS300SetupCMDFlag(TRANSPARENT_BITBLT)
+ } else {
+ SiS300SetupROP(sisALUConv[rop])
+ }
+ if(xdir > 0) {
+ SiS300SetupCMDFlag(X_INC)
+ }
+ if(ydir > 0) {
+ SiS300SetupCMDFlag(Y_INC)
+ }
+}
+
+static void
+SiS300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
+ int width, int height)
+{
+ long srcbase, dstbase;
+
+ srcbase = dstbase = 0;
+ if (src_y >= 2048) {
+ srcbase = ivideo.video_linelength * src_y;
+ src_y = 0;
+ }
+ if (dst_y >= 2048) {
+ dstbase = ivideo.video_linelength * dst_y;
+ dst_y = 0;
+ }
+
+ SiS300SetupSRCBase(srcbase);
+ SiS300SetupDSTBase(dstbase);
+
+ if(!(ivideo.CommandReg & X_INC)) {
+ src_x += width-1;
+ dst_x += width-1;
+ }
+ if(!(ivideo.CommandReg & Y_INC)) {
+ src_y += height-1;
+ dst_y += height-1;
+ }
+ SiS300SetupRect(width, height)
+ SiS300SetupSRCXY(src_x, src_y)
+ SiS300SetupDSTXY(dst_x, dst_y)
+ SiS300DoCMD
+}
+
+static void
+SiS300SetupForSolidFill(int color, int rop, unsigned int planemask)
+{
+ SiS300SetupPATFG(color)
+ SiS300SetupDSTRect(ivideo.video_linelength, -1)
+ SiS300SetupDSTColorDepth(ivideo.DstColor);
+ SiS300SetupROP(sisPatALUConv[rop])
+ SiS300SetupCMDFlag(PATFG)
+}
+
+static void
+SiS300SubsequentSolidFillRect(int x, int y, int w, int h)
+{
+ long dstbase;
+
+ dstbase = 0;
+ if(y >= 2048) {
+ dstbase = ivideo.video_linelength * y;
+ y = 0;
+ }
+ SiS300SetupDSTBase(dstbase)
+ SiS300SetupDSTXY(x,y)
+ SiS300SetupRect(w,h)
+ SiS300SetupCMDFlag(X_INC | Y_INC | BITBLT)
+ SiS300DoCMD
+}
+
+/* 310/325 series ------------------------------------------------ */
+
+static void
+SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color)
+{
+ SiS310SetupDSTColorDepth(ivideo.DstColor);
+ SiS310SetupSRCPitch(ivideo.video_linelength)
+ SiS310SetupDSTRect(ivideo.video_linelength, -1)
+ if (trans_color != -1) {
+ SiS310SetupROP(0x0A)
+ SiS310SetupSRCTrans(trans_color)
+ SiS310SetupCMDFlag(TRANSPARENT_BITBLT)
+ } else {
+ SiS310SetupROP(sisALUConv[rop])
+ /* Set command - not needed, both 0 */
+ /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
+ }
+ SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
+ /* TW: The 310/325 series is smart enough to know the direction */
+}
+
+static void
+SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
+ int width, int height)
+{
+ long srcbase, dstbase;
+
+ srcbase = dstbase = 0;
+ if (src_y >= 2048) {
+ srcbase = ivideo.video_linelength * src_y;
+ src_y = 0;
+ }
+ if (dst_y >= 2048) {
+ dstbase = ivideo.video_linelength * dst_y;
+ dst_y = 0;
+ }
+
+ SiS310SetupSRCBase(srcbase);
+ SiS310SetupDSTBase(dstbase);
+ SiS310SetupRect(width, height)
+ SiS310SetupSRCXY(src_x, src_y)
+ SiS310SetupDSTXY(dst_x, dst_y)
+ SiS310DoCMD
+}
+
+static void
+SiS310SetupForSolidFill(int color, int rop, unsigned int planemask)
+{
+ SiS310SetupPATFG(color)
+ SiS310SetupDSTRect(ivideo.video_linelength, -1)
+ SiS310SetupDSTColorDepth(ivideo.DstColor);
+ SiS310SetupROP(sisPatALUConv[rop])
+ SiS310SetupCMDFlag(PATFG | ivideo.SiS310_AccelDepth)
+}
+
+static void
+SiS310SubsequentSolidFillRect(int x, int y, int w, int h)
+{
+ long dstbase;
+
+ dstbase = 0;
+ if(y >= 2048) {
+ dstbase = ivideo.video_linelength * y;
+ y = 0;
+ }
+ SiS310SetupDSTBase(dstbase)
+ SiS310SetupDSTXY(x,y)
+ SiS310SetupRect(w,h)
+ SiS310SetupCMDFlag(BITBLT)
+ SiS310DoCMD
+}
+
+/* --------------------------------------------------------------------- */
+
+/* The exported routines */
+
+int sisfb_initaccel(void)
+{
+#ifdef SISFB_USE_SPINLOCKS
+ spin_lock_init(&ivideo.lockaccel);
+#endif
+ return(0);
+}
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) /* --- KERNEL 2.5.34 and later --- */
+
+void fbcon_sis_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+ CRITFLAGS
+
+ if(!rect->width || !rect->height)
+ return;
+
+ if(sisvga_engine == SIS_300_VGA) {
+ CRITBEGIN
+ SiS300SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+ SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+ CRITEND
+ SiS300Sync();
+ } else {
+ CRITBEGIN
+ SiS310SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+ SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+ CRITEND
+ SiS310Sync();
+ }
+
+}
+
+void fbcon_sis_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+ int xdir, ydir;
+ CRITFLAGS
+
+ if(!area->width || !area->height)
+ return;
+
+ if(area->sx < area->dx) xdir = 0;
+ else xdir = 1;
+ if(area->sy < area->dy) ydir = 0;
+ else ydir = 1;
+
+ if(sisvga_engine == SIS_300_VGA) {
+ CRITBEGIN
+ SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+ SiS300SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+ CRITEND
+ SiS300Sync();
+ } else {
+ CRITBEGIN
+ SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+ SiS310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+ CRITEND
+ SiS310Sync();
+ }
+}
+
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33) /* ------ KERNEL <2.5.34 ------ */
+
+void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
+ int dsty, int dstx, int height, int width)
+{
+ int xdir, ydir;
+ CRITFLAGS
+
+ srcx *= fontwidth(p);
+ srcy *= fontheight(p);
+ dstx *= fontwidth(p);
+ dsty *= fontheight(p);
+ width *= fontwidth(p);
+ height *= fontheight(p);
+
+
+ if(srcx < dstx) xdir = 0;
+ else xdir = 1;
+ if(srcy < dsty) ydir = 0;
+ else ydir = 1;
+
+ if(sisvga_engine == SIS_300_VGA) {
+ CRITBEGIN
+ SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+ SiS300SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+ CRITEND
+ SiS300Sync();
+ } else {
+ CRITBEGIN
+ SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+ SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+ CRITEND
+ SiS310Sync();
+ }
+}
+
+
+static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
+ int srcy, int srcx, int height, int width, int color)
+{
+ CRITFLAGS
+
+ srcx *= fontwidth(p);
+ srcy *= fontheight(p);
+ width *= fontwidth(p);
+ height *= fontheight(p);
+
+ if(sisvga_engine == SIS_300_VGA) {
+ CRITBEGIN
+ SiS300SetupForSolidFill(color, 3, 0);
+ SiS300SubsequentSolidFillRect(srcx, srcy, width, height);
+ CRITEND
+ SiS300Sync();
+ } else {
+ CRITBEGIN
+ SiS310SetupForSolidFill(color, 3, 0);
+ SiS310SubsequentSolidFillRect(srcx, srcy, width, height);
+ CRITEND
+ SiS310Sync();
+ }
+}
+
+void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
+ int srcy, int srcx, int height, int width)
+{
+ u32 bgx;
+
+ bgx = attr_bgcol_ec(p, conp);
+ fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+}
+
+void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
+ int srcy, int srcx, int height, int width)
+{
+ u32 bgx;
+
+ bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+ fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+}
+
+void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
+ int srcy, int srcx, int height, int width)
+{
+ u32 bgx;
+
+ bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+ fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+}
+
+void fbcon_sis_revc(struct display *p, int srcx, int srcy)
+{
+ CRITFLAGS
+
+ srcx *= fontwidth(p);
+ srcy *= fontheight(p);
+
+ if(sisvga_engine == SIS_300_VGA) {
+ CRITBEGIN
+ SiS300SetupForSolidFill(0, 0x0a, 0);
+ SiS300SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+ CRITEND
+ SiS300Sync();
+ } else {
+ CRITBEGIN
+ SiS310SetupForSolidFill(0, 0x0a, 0);
+ SiS310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+ CRITEND
+ SiS310Sync();
+ }
+}
+
+#ifdef FBCON_HAS_CFB8
+struct display_switch fbcon_sis8 = {
+ setup: fbcon_cfb8_setup,
+ bmove: fbcon_sis_bmove,
+ clear: fbcon_sis_clear8,
+ putc: fbcon_cfb8_putc,
+ putcs: fbcon_cfb8_putcs,
+ revc: fbcon_cfb8_revc,
+ clear_margins: fbcon_cfb8_clear_margins,
+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+#ifdef FBCON_HAS_CFB16
+struct display_switch fbcon_sis16 = {
+ setup: fbcon_cfb16_setup,
+ bmove: fbcon_sis_bmove,
+ clear: fbcon_sis_clear16,
+ putc: fbcon_cfb16_putc,
+ putcs: fbcon_cfb16_putcs,
+ revc: fbcon_sis_revc,
+ clear_margins: fbcon_cfb16_clear_margins,
+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+#ifdef FBCON_HAS_CFB32
+struct display_switch fbcon_sis32 = {
+ setup: fbcon_cfb32_setup,
+ bmove: fbcon_sis_bmove,
+ clear: fbcon_sis_clear32,
+ putc: fbcon_cfb32_putc,
+ putcs: fbcon_cfb32_putcs,
+ revc: fbcon_sis_revc,
+ clear_margins: fbcon_cfb32_clear_margins,
+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#endif /* KERNEL VERSION */
+
+
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 83b4f07c6652..a6cb38550bc7 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -3391,7 +3391,7 @@ int __init sisfb_init(void)
return -EINVAL;
printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
- GET_FB_IDX(fb_info.node), fb_info.modename, VER_MAJOR, VER_MINOR,
+ minor(fb_info.node), fb_info.modename, VER_MAJOR, VER_MINOR,
VER_LEVEL);
printk(KERN_INFO "sisfb: Added SISFB_GET_INFO ioctl = %x\n", SISFB_GET_INFO);
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 110e85dea332..fd6aba8342d7 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -125,9 +125,6 @@ static struct fb_info info;
*/
static struct xxx_par __initdata current_par;
- /* To go away in the near future */
-static struct display disp;
-
int xxxfb_init(void);
int xxxfb_setup(char*);
@@ -287,6 +284,12 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
}
/**
+ * xxxfb_cursor -
+ *
+ * Returns negative errno on error, or zero on success.
+ */
+
+/**
* xxxfb_pan_display - NOT a required function. Pans the display.
* @var: frame buffer variable screen structure
* @info: frame buffer structure that represents a single frame buffer
@@ -298,7 +301,7 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
* Returns negative errno on error, or zero on success.
*
*/
-static int xxxfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int xxxfb_pan_display(struct fb_var_screeninfo *var,
const struct fb_info *info)
{
/* ... */
@@ -421,15 +424,6 @@ int __init xxxfb_init(void)
info.flags = FBINFO_FLAG_DEFAULT;
info.par = current_par;
- /* The following has to be set but in th efuture will go away */
- strcpy(info.modename, xxxfb_fix.id);
- info.changevar = NULL;
- info.currcon = -1;
- info.disp = &disp;
- info.switch_con = gen_switch;
- info.updatevar = gen_update_var;
-
-
/*
* This should give a reasonable default video mode. The following is
* done when we can set a video mode.
@@ -450,11 +444,10 @@ int __init xxxfb_init(void)
* mode. If we are setting the mode ourselves we don't call this.
*/
info.var = xxxfb_var;
- gen_set_disp(-1, &fb_info);
if (register_framebuffer(&info) < 0)
return -EINVAL;
- printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(info.node),
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", minor(info.node),
info.fix.id);
return 0;
}
@@ -510,11 +503,6 @@ static struct fb_ops xxxfb_ops = {
.owner = THIS_MODULE,
.fb_open = xxxfb_open, /* only if you need it to do something */
.fb_release = xxxfb_release, /* only if you need it to do something */
- /* Stuff to go away. Use generic functions for now */
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
-
.fb_check_var = xxxfb_check_var,
.fb_set_par = xxxfb_set_par, /* optional */
.fb_setcolreg = xxxfb_setcolreg,
diff --git a/drivers/video/softcursor.c b/drivers/video/softcursor.c
new file mode 100644
index 000000000000..28b378925d47
--- /dev/null
+++ b/drivers/video/softcursor.c
@@ -0,0 +1,62 @@
+/*
+ * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices
+ *
+ * Created 14 Nov 2002 by James Simmons
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ int i, size = ((cursor->image.width + 7) / 8) * cursor->image.height;
+ struct fb_image image;
+ static char data[64];
+
+ if (cursor->enable) {
+ switch (cursor->rop) {
+ case ROP_XOR:
+ for (i = 0; i < size; i++)
+ data[i] = (cursor->image.data[i] &
+ cursor->mask[i]) ^
+ cursor->dest[i];
+ break;
+ case ROP_COPY:
+ default:
+ for (i = 0; i < size; i++)
+ data[i] =
+ cursor->image.data[i] & cursor->mask[i];
+ break;
+ }
+ } else
+ memcpy(data, cursor->dest, size);
+
+ image.bg_color = cursor->image.bg_color;
+ image.fg_color = cursor->image.fg_color;
+ image.dx = cursor->image.dx;
+ image.dy = cursor->image.dy;
+ image.width = cursor->image.width;
+ image.height = cursor->image.height;
+ image.depth = cursor->image.depth;
+ image.data = data;
+
+ if (info->fbops->fb_imageblit)
+ info->fbops->fb_imageblit(info, &image);
+ return 0;
+}
+
+EXPORT_SYMBOL(soft_cursor);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software cursor");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index cb78eeb93607..024a4fb2e963 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1906,7 +1906,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_i
goto fail;
}
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(sst_info->info.node),sst_info->info.modename);
+ minor(sst_info->info.node),sst_info->info.modename);
return 0;
fail:
diff --git a/drivers/video/sti-bmode.h b/drivers/video/sti-bmode.h
deleted file mode 100644
index 4aa38f6d9daa..000000000000
--- a/drivers/video/sti-bmode.h
+++ /dev/null
@@ -1,287 +0,0 @@
-#define STI_REGION_MAX 8
-#define STI_DEV_NAME_LENGTH 32
-
-typedef struct {
- u8 res[3];
- u8 data;
-} __attribute__((packed)) sti_u8;
-
-typedef struct {
- sti_u8 data[2];
-} __attribute__((packed)) sti_u16;
-
-typedef struct {
- sti_u8 data[4];
-} __attribute__((packed)) sti_u32;
-
-#define STI_U8( u8) ((u8).data)
-#define STI_U16(u16) ((STI_U8((u16).data[0])<<8) | STI_U8((u16).data[1]))
-#define STI_U32(u32) ((STI_U8((u32).data[0])<<24) | \
- (STI_U8((u32).data[1])<<16) | \
- (STI_U8((u32).data[2])<< 8) | \
- (STI_U8((u32).data[3])<< 0))
-
-struct sti_rom_region {
- sti_u32 region;
-};
-
-struct sti_rom_font {
- sti_u16 first_char;
- sti_u16 last_char;
- sti_u8 width;
- sti_u8 height;
- sti_u8 font_type;
- sti_u8 bytes_per_char;
- sti_u32 next_font;
- sti_u8 underline_height;
- sti_u8 underline_pos;
- sti_u8 res008[2];
-};
-
-struct sti_rom {
- sti_u8 type;
- sti_u8 num_mons;
- sti_u8 revno[2];
-
- sti_u8 graphics_id[8]; /* 0x010 */
-
- sti_u32 font_start; /* 0x030 */
- sti_u32 statesize;
- sti_u32 last_addr;
- sti_u32 region_list;
-
- sti_u16 reentsize; /* 0x070 */
- sti_u16 maxtime;
- sti_u32 mon_tbl_addr;
- sti_u32 user_data_addr;
- sti_u32 sti_mem_req;
-
- sti_u32 user_data_size; /* 0x0b0 */
- sti_u16 power; /* 0x0c0 */
- sti_u8 bus_support;
- sti_u8 ext_bus_support;
- sti_u8 alt_code_type; /* 0x0d0 */
- sti_u8 ext_dd_struct[3];
- sti_u32 cfb_addr; /* 0x0e0 */
-
- sti_u8 res0f0[4];
-
- sti_u32 init_graph; /* 0x0e0 */
- sti_u32 state_mgmt;
- sti_u32 font_unpmv;
- sti_u32 block_move;
- sti_u32 self_test;
- sti_u32 excep_hdlr;
- sti_u32 inq_conf;
- sti_u32 set_cm_entry;
- sti_u32 dma_ctrl;
- sti_u32 flow_ctrl;
- sti_u32 user_timing;
- sti_u32 process_mgr;
- sti_u32 sti_util;
- sti_u32 end_addr;
- sti_u32 res0b8;
- sti_u32 res0bc;
-
- sti_u32 init_graph_m68k; /* 0x0e0 */
- sti_u32 state_mgmt_m68k;
- sti_u32 font_unpmv_m68k;
- sti_u32 block_move_m68k;
- sti_u32 self_test_m68k;
- sti_u32 excep_hdlr_m68k;
- sti_u32 inq_conf_m68k;
- sti_u32 set_cm_entry_m68k;
- sti_u32 dma_ctrl_m68k;
- sti_u32 flow_ctrl_m68k;
- sti_u32 user_timing_m68k;
- sti_u32 process_mgr_m68k;
- sti_u32 sti_util_m68k;
- sti_u32 end_addr_m68k;
- sti_u32 res0b8_m68k;
- sti_u32 res0bc_m68k;
-
- sti_u8 res040[7 * 4];
-};
-
-struct sti_cooked_font {
- struct sti_rom_font *raw;
- struct sti_cooked_font *next_font;
-};
-
-struct sti_cooked_rom {
- struct sti_rom *raw;
- struct sti_cooked_font *font_start;
- u32 *region_list;
-};
-
-struct sti_glob_cfg_ext {
- u8 curr_mon;
- u8 friendly_boot;
- s16 power;
- s32 freq_ref;
- s32 *sti_mem_addr;
- s32 *future_ptr;
-};
-
-struct sti_glob_cfg {
- s32 text_planes;
- s16 onscreen_x;
- s16 onscreen_y;
- s16 offscreen_x;
- s16 offscreen_y;
- s16 total_x;
- s16 total_y;
- u32 region_ptrs[STI_REGION_MAX];
- s32 reent_lvl;
- s32 *save_addr;
- struct sti_glob_cfg_ext *ext_ptr;
-};
-
-struct sti_init_flags {
- u32 wait : 1;
- u32 reset : 1;
- u32 text : 1;
- u32 nontext : 1;
- u32 clear : 1;
- u32 cmap_blk : 1;
- u32 enable_be_timer : 1;
- u32 enable_be_int : 1;
- u32 no_chg_tx : 1;
- u32 no_chg_ntx : 1;
- u32 no_chg_bet : 1;
- u32 no_chg_bei : 1;
- u32 init_cmap_tx : 1;
- u32 cmt_chg : 1;
- u32 retain_ie : 1;
- u32 pad : 17;
-
- s32 *future_ptr;
-};
-
-struct sti_init_inptr_ext {
- u8 config_mon_type;
- u8 pad[1];
- u16 inflight_data;
- s32 *future_ptr;
-};
-
-struct sti_init_inptr {
- s32 text_planes;
- struct sti_init_inptr_ext *ext_ptr;
-};
-
-struct sti_init_outptr {
- s32 errno;
- s32 text_planes;
- s32 *future_ptr;
-};
-
-struct sti_conf_flags {
- u32 wait : 1;
- u32 pad : 31;
- s32 *future_ptr;
-};
-
-struct sti_conf_inptr {
- s32 *future_ptr;
-};
-
-struct sti_conf_outptr_ext {
- u32 crt_config[3];
- u32 crt_hdw[3];
- s32 *future_ptr;
-};
-
-struct sti_conf_outptr {
- s32 errno;
- s16 onscreen_x;
- s16 onscreen_y;
- s16 offscreen_x;
- s16 offscreen_y;
- s16 total_x;
- s16 total_y;
- s32 bits_per_pixel;
- s32 bits_used;
- s32 planes;
- u8 dev_name[STI_DEV_NAME_LENGTH];
- u32 attributes;
- struct sti_conf_outptr_ext *ext_ptr;
-};
-
-
-struct sti_font_inptr {
- u32 font_start_addr;
- s16 index;
- u8 fg_color;
- u8 bg_color;
- s16 dest_x;
- s16 dest_y;
- s32 *future_ptr;
-};
-
-struct sti_font_flags {
- u32 wait : 1;
- u32 non_text : 1;
- u32 pad : 30;
-
- s32 *future_ptr;
-};
-
-struct sti_font_outptr {
- s32 errno;
- s32 *future_ptr;
-};
-
-struct sti_blkmv_flags {
- u32 wait : 1;
- u32 color : 1;
- u32 clear : 1;
- u32 non_text : 1;
- u32 pad : 28;
- s32 *future_ptr;
-};
-
-struct sti_blkmv_inptr {
- u8 fg_color;
- u8 bg_color;
- s16 src_x;
- s16 src_y;
- s16 dest_x;
- s16 dest_y;
- s16 width;
- s16 height;
- s32 *future_ptr;
-};
-
-struct sti_blkmv_outptr {
- s32 errno;
- s32 *future_ptr;
-};
-
-struct sti_struct {
- spinlock_t lock;
-
- struct sti_cooked_rom *rom;
-
- unsigned long font_unpmv;
- unsigned long block_move;
- unsigned long init_graph;
- unsigned long inq_conf;
-
- struct sti_glob_cfg *glob_cfg;
- struct sti_rom_font *font;
-
- s32 text_planes;
-
- char **mon_strings;
- u32 *regions;
- u8 *pci_regions;
-};
-
-#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
- ({ \
- real32_call( func, (unsigned long)STI_PTR(flags), \
- STI_PTR(inptr), STI_PTR(outptr), \
- glob_cfg); \
- })
-
diff --git a/drivers/video/sticon-bmode.c b/drivers/video/sticon-bmode.c
deleted file mode 100644
index 3ab5077ac27a..000000000000
--- a/drivers/video/sticon-bmode.c
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
-TPG CVS users: please don't commit changes to this file directly, send
-them to prumpf@tux.org and wait for a new version instead. Otherwise,
-your changes will get lost when prumpf releases the next version, as
-this file *will* be replaced with it. You have been warned.
-
-2000-05-30, <deller@gmx.de>
-*/
-#if 1
-#define DPRINTK(x) printk x
-#else
-#define DPRINTK(x)
-#endif
-
-/*
- * linux/drivers/video/sticon.c - console driver using HP's STI firmware
- *
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- * Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
- * which were
- *
- * Created 28 Sep 1997 by Geert Uytterhoeven
- * Rewritten by Martin Mares <mj@ucw.cz>, July 1998
- * Copyright (C) 1991, 1992 Linus Torvalds
- * 1995 Jay Estabrook
- * Copyright (C) 1995 Geert Uytterhoeven
- * Copyright (C) 1993 Bjoern Brauel
- * Roman Hodek
- * Copyright (C) 1993 Hamish Macdonald
- * Greg Harp
- * Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
- *
- * with work by William Rucklidge (wjr@cs.cornell.edu)
- * Geert Uytterhoeven
- * Jes Sorensen (jds@kom.auc.dk)
- * Martin Apel
- * with work by Guenther Kelleter
- * Martin Schaller
- * Andreas Schwab
- * Emmanuel Marty (core@ggi-project.org)
- * Jakub Jelinek (jj@ultra.linux.cz)
- * 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 for
- * more details.
- */
-/*
- * TODO:
- * - call STI in virtual mode rather than in real mode
- * - support for PCI-only STI ROMs (which don't have a traditional region
- * list)
- * - safe detection (i.e. verify there is a graphics device at a given
- * address first, not just read a random device's io space)
- * - support for multiple STI devices in one machine
- * - support for byte-mode STI ROMs
- * - support for just using STI to switch to a colour fb (stifb ?)
- * - try to make it work on m68k hp workstations ;)
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/kd.h>
-#include <linux/slab.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/real.h>
-
-#include <linux/module.h>
-#include <linux/fb.h>
-#include <linux/smp.h>
-
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <video/fbcon.h>
-#include <video/font.h>
-
-#include "sti-bmode.h"
-
-/* The latency of the STI functions cannot really be reduced by setting
- * this to 0; STI doesn't seem to be designed to allow calling a different
- * function (or the same function with different arguments) after a
- * function exited with 1 as return value.
- *
- * As all of the functions below could be called from interrupt context,
- * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
- * block. Really bad latency there.
- *
- * Probably the best solution to all this is have the generic code manage
- * the screen buffer and a kernel thread to call STI occasionally.
- *
- * Luckily, the frame buffer guys have the same problem so we can just wait
- * for them to fix it and steal their solution. prumpf
- *
- * Actually, another long-term viable solution is to completely do STI
- * support in userspace - that way we avoid the potential license issues
- * of using proprietary fonts, too. */
-
-#define STI_WAIT 1
-#define STI_PTR(p) ( (typeof(p)) virt_to_phys(p))
-#define PTR_STI(p) ( (typeof(p)) phys_to_virt((unsigned long)p) )
-
-static struct sti_struct default_sti = {
- SPIN_LOCK_UNLOCKED,
-};
-
-static struct sti_font_flags default_font_flags = {
- STI_WAIT, 0, 0, NULL
-};
-
-/* The colour indices used by STI are
- * 0 - Black
- * 1 - White
- * 2 - Red
- * 3 - Yellow/Brown
- * 4 - Green
- * 5 - Cyan
- * 6 - Blue
- * 7 - Magenta
- *
- * So we have the same colours as VGA (basically one bit each for R, G, B),
- * but have to translate them, anyway. */
-
-static u8 col_trans[8] = {
- 0, 6, 4, 5,
- 2, 7, 3, 1
-};
-
-#define c_fg(sti, c) col_trans[((c>> 8) & 7)]
-#define c_bg(sti, c) col_trans[((c>>11) & 7)]
-#define c_index(sti, c) (c&0xff)
-
-#define sti_onscreen_x(sti) (PTR_STI(sti->glob_cfg)->onscreen_x)
-#define sti_onscreen_y(sti) (PTR_STI(sti->glob_cfg)->onscreen_y)
-#define sti_font_x(sti) (STI_U8(PTR_STI(sti->font)->width))
-#define sti_font_y(sti) (STI_U8(PTR_STI(sti->font)->height))
-
-static struct sti_init_flags default_init_flags = {
- STI_WAIT, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, NULL
-};
-
-static void sti_init_graph(struct sti_struct *sti)
-{
- struct sti_init_inptr_ext inptr_ext = {
- 0, { 0 }, 0, NULL
- };
- struct sti_init_inptr inptr = {
- 3, STI_PTR(&inptr_ext)
- };
- struct sti_init_outptr outptr = { 0 };
- unsigned long flags;
- s32 ret;
-
- spin_lock_irqsave(&sti->lock, flags);
-
- ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
- &outptr, sti->glob_cfg);
-
- spin_unlock_irqrestore(&sti->lock, flags);
-
- sti->text_planes = outptr.text_planes;
-}
-
-#if 0
-static struct sti_conf_flags default_conf_flags = {
- STI_WAIT, 0, NULL
-};
-
-static void sti_inq_conf(struct sti_struct *sti)
-{
- struct sti_conf_inptr inptr = { NULL };
- struct sti_conf_outptr_ext outptr_ext = { .future_ptr = NULL };
- struct sti_conf_outptr outptr = {
- .ext_ptr = STI_PTR(&outptr_ext)
- };
- unsigned long flags;
- s32 ret;
-
- do {
- spin_lock_irqsave(&sti->lock, flags);
- ret = STI_CALL(sti->inq_conf, &default_conf_flags,
- &inptr, &outptr, sti->glob_cfg);
- spin_unlock_irqrestore(&sti->lock, flags);
- } while(ret == 1);
-}
-#endif
-
-static void sti_putc(struct sti_struct *sti, int c, int y, int x)
-{
- struct sti_font_inptr inptr = {
- (u32) sti->font, c_index(sti, c), c_fg(sti, c), c_bg(sti, c),
- x * sti_font_x(sti), y * sti_font_y(sti), NULL
- };
- struct sti_font_outptr outptr = {
- 0, NULL
- };
- s32 ret;
- unsigned long flags;
-
- do {
- spin_lock_irqsave(&sti->lock, flags);
- ret = STI_CALL(sti->font_unpmv, &default_font_flags,
- &inptr, &outptr, sti->glob_cfg);
- spin_unlock_irqrestore(&sti->lock, flags);
- } while(ret == 1);
-}
-
-static struct sti_blkmv_flags clear_blkmv_flags = {
- STI_WAIT, 1, 1, 0, 0, NULL
-};
-
-static void sti_set(struct sti_struct *sti, int src_y, int src_x,
- int height, int width, u8 color)
-{
- struct sti_blkmv_inptr inptr = {
- color, color,
- src_x, src_y ,
- src_x, src_y ,
- width, height,
- NULL
- };
- struct sti_blkmv_outptr outptr = { 0, NULL };
- s32 ret = 0;
- unsigned long flags;
-
- do {
- spin_lock_irqsave(&sti->lock, flags);
- ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
- &inptr, &outptr, sti->glob_cfg);
- spin_unlock_irqrestore(&sti->lock, flags);
- } while(ret == 1);
-}
-
-static void sti_clear(struct sti_struct *sti, int src_y, int src_x,
- int height, int width)
-{
- struct sti_blkmv_inptr inptr = {
- 0, 0,
- src_x * sti_font_x(sti), src_y * sti_font_y(sti),
- src_x * sti_font_x(sti), src_y * sti_font_y(sti),
- width * sti_font_x(sti), height* sti_font_y(sti),
- NULL
- };
- struct sti_blkmv_outptr outptr = { 0, NULL };
- s32 ret = 0;
- unsigned long flags;
-
- do {
- spin_lock_irqsave(&sti->lock, flags);
- ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
- &inptr, &outptr, sti->glob_cfg);
- spin_unlock_irqrestore(&sti->lock, flags);
- } while(ret == 1);
-}
-
-static struct sti_blkmv_flags default_blkmv_flags = {
- STI_WAIT, 0, 0, 0, 0, NULL
-};
-
-static void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
- int dst_y, int dst_x, int height, int width)
-{
- struct sti_blkmv_inptr inptr = {
- 0, 0,
- src_x * sti_font_x(sti), src_y * sti_font_y(sti),
- dst_x * sti_font_x(sti), dst_y * sti_font_y(sti),
- width * sti_font_x(sti), height* sti_font_y(sti),
- NULL
- };
- struct sti_blkmv_outptr outptr = { 0, NULL };
- s32 ret = 0;
- unsigned long flags;
-
- do {
- spin_lock_irqsave(&sti->lock, flags);
- ret = STI_CALL(sti->block_move, &default_blkmv_flags,
- &inptr, &outptr, sti->glob_cfg);
- spin_unlock_irqrestore(&sti->lock, flags);
- } while(ret == 1);
-}
-
-
-/* STICON */
-
-static const char __init *sticon_startup(void)
-{
- return "STI console";
-}
-
-static int sticon_set_palette(struct vc_data *c, unsigned char *table)
-{
- return -EINVAL;
-}
-static int sticon_font_op(struct vc_data *c, struct console_font_op *op)
-{
- return -ENOSYS;
-}
-
-static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
-{
- sti_putc(&default_sti, c, ypos, xpos);
-}
-
-static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
- int count, int ypos, int xpos)
-{
- while(count--) {
- sti_putc(&default_sti, scr_readw(s++), ypos, xpos++);
- }
-}
-
-static void sticon_cursor(struct vc_data *conp, int mode)
-{
-}
-
-static int sticon_scroll(struct vc_data *conp, int t, int b, int dir,
- int count)
-{
- struct sti_struct *sti = &default_sti;
-
- if(console_blanked)
- return 0;
-
- sticon_cursor(conp, CM_ERASE);
-
- switch(dir) {
- case SM_UP:
- sti_bmove(sti, t+count, 0, t, 0, b-t-count, conp->vc_cols);
- sti_clear(sti, b-count, 0, count, conp->vc_cols);
-
- break;
-
- case SM_DOWN:
- sti_bmove(sti, t, 0, t+count, 0, b-t-count, conp->vc_cols);
- sti_clear(sti, t, 0, count, conp->vc_cols);
-
- break;
- }
-
- return 0;
-}
-
-static void sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- sti_bmove(&default_sti, sy, sx, dy, dx, height, width);
-}
-
-static void sticon_init(struct vc_data *c, int init)
-{
- struct sti_struct *sti = &default_sti;
- int vc_cols, vc_rows;
-
- sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
- c->vc_can_do_color = 1;
- vc_cols = PTR_STI(sti->glob_cfg)->onscreen_x / sti_font_x(sti);
- vc_rows = PTR_STI(sti->glob_cfg)->onscreen_y / sti_font_y(sti);
-
- vc_resize_con(vc_rows, vc_cols, c->vc_num);
-}
-
-static void sticon_deinit(struct vc_data *c)
-{
-}
-
-static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
- int width)
-{
- sti_clear(&default_sti, sy, sx, height, width);
-}
-
-static int sticon_switch(struct vc_data *conp)
-{
- return 0;
-}
-
-static int sticon_blank(struct vc_data *conp, int blank)
-{
- return 0;
-}
-
-static int sticon_scrolldelta(struct vc_data *conp, int lines)
-{
- return 0;
-}
-
-static int sticon_set_origin(struct vc_data *conp)
-{
- return 0;
-}
-
-static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse)
-{
- u8 attr = ((color & 0x70) >> 1) | ((color & 7));
-
- if(reverse) {
- color = ((color>>3)&0x7) | ((color &0x7)<<3);
- }
-
-
- return attr;
-}
-
-static struct consw sti_con = {
- .con_startup = sticon_startup,
- .con_init = sticon_init,
- .con_deinit = sticon_deinit,
- .con_clear = sticon_clear,
- .con_putc = sticon_putc,
- .con_putcs = sticon_putcs,
- .con_cursor = sticon_cursor,
- .con_scroll = sticon_scroll,
- .con_bmove = sticon_bmove,
- .con_switch = sticon_switch,
- .con_blank = sticon_blank,
- .con_font_op = sticon_font_op,
- .con_set_palette = sticon_set_palette,
- .con_scrolldelta = sticon_scrolldelta,
- .con_set_origin = sticon_set_origin,
- .con_build_attr = sticon_build_attr,
-};
-
-#include <asm/pgalloc.h> /* need cache flush routines */
-static void __init sti_rom_copy(unsigned long base, unsigned long offset,
- unsigned long count, void *dest)
-{
- void *savedest = dest;
- int savecount = count;
-
- while(count >= 4) {
- count -= 4;
- *(u32 *)dest = gsc_readl(base + offset);
-#if 0
- DPRINTK(("%08x\n", *(u32 *)dest));
- if(*(u32 *)dest == 0x64646464) {
- DPRINTK(("!!!!\n"));
- { u32 foo = 0; while(foo += 0x100); }
- }
-#endif
- offset += 4;
- dest += 4;
- }
- while(count) {
- count--;
- *(u8 *)dest = gsc_readb(base + offset);
- offset++;
- dest++;
- }
-
- flush_kernel_dcache_range((unsigned long)dest, count);
- flush_icache_range((unsigned long)dest, dest + count);
-}
-
-static void dump_sti_rom(struct sti_rom *rom)
-{
- printk("STI byte mode ROM type %d\n", STI_U8(rom->type));
- printk(" supports %d monitors\n", STI_U8(rom->num_mons));
- printk(" conforms to STI ROM spec revision %d.%02x\n",
- STI_U8(rom->revno[0]) >> 4, STI_U8(rom->revno[0]) & 0x0f);
- printk(__FUNCTION__ ": %d\n", __LINE__);
- printk(" graphics id %02x%02x%02x%02x%02x%02x%02x%02x\n",
- (unsigned int) STI_U8(rom->graphics_id[0]),
- (unsigned int) STI_U8(rom->graphics_id[1]),
- (unsigned int) STI_U8(rom->graphics_id[2]),
- (unsigned int) STI_U8(rom->graphics_id[3]),
- (unsigned int) STI_U8(rom->graphics_id[4]),
- (unsigned int) STI_U8(rom->graphics_id[5]),
- (unsigned int) STI_U8(rom->graphics_id[6]),
- (unsigned int) STI_U8(rom->graphics_id[7]));
- printk(__FUNCTION__ ": %d\n", __LINE__);
- printk(" font start %08x\n", STI_U32(rom->font_start));
- printk(__FUNCTION__ ": %d\n", __LINE__);
- printk(" region list %08x\n", STI_U32(rom->region_list));
- printk(__FUNCTION__ ": %d\n", __LINE__);
- printk(" init_graph %08x\n", STI_U32(rom->init_graph));
- printk(__FUNCTION__ ": %d\n", __LINE__);
- printk(" alternate code type %d\n", STI_U8(rom->alt_code_type));
- printk(__FUNCTION__ ": %d\n", __LINE__);
-}
-
-static void __init sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
- struct sti_rom *raw_rom)
-{
- struct sti_rom_font *raw_font;
- struct sti_cooked_font *cooked_font;
- struct sti_rom_font *font_start;
-
- cooked_font =
- kmalloc(sizeof *cooked_font, GFP_KERNEL);
- if(!cooked_font)
- return;
-
- cooked_rom->font_start = cooked_font;
-
-#if 0
- DPRINTK(("%p = %p + %08x\n",
- ((void *)raw_rom) + (STI_U32(raw_rom->font_start)),
- ((void *)raw_rom), (STI_U32(raw_rom->font_start))));
-#endif
- raw_font = ((void *)raw_rom) + STI_U32(raw_rom->font_start) - 3;
-
- font_start = raw_font;
- cooked_font->raw = raw_font;
-
- DPRINTK(("next font %08x\n", STI_U32(raw_font->next_font)));
-
- while(0 && STI_U32(raw_font->next_font)) {
- raw_font = ((void *)font_start) + STI_U32(raw_font->next_font);
-
- cooked_font->next_font =
- kmalloc(sizeof *cooked_font, GFP_KERNEL);
- if(!cooked_font->next_font)
- return;
-
- cooked_font = cooked_font->next_font;
-
-// cooked_font->raw = raw_font;
-
- DPRINTK(("raw_font %p\n",
- raw_font));
- DPRINTK(("next_font %08x %p\n",
- STI_U32(raw_font->next_font),
- ((void *)font_start) + STI_U32(raw_font->next_font)));
- }
-
- cooked_font->next_font = NULL;
-}
-
-static unsigned long __init sti_cook_function(void *function,
- u32 size)
-{
- sti_u32 *func = (sti_u32 *)function;
- u32 *ret;
- int i;
-
- ret = kmalloc(size, GFP_KERNEL);
- if(!ret) {
- printk(KERN_ERR __FILE__ ": could not get memory.\n");
- return 0;
- }
-
- for(i=0; i<(size/4); i++)
- ret[i] = STI_U32(func[i]);
-
- flush_all_caches();
-
- return virt_to_phys(ret);
-}
-
-static int font_index, font_height, font_width;
-
-static int __init sti_search_font(struct sti_cooked_rom *rom,
- int height, int width)
-{
- struct sti_cooked_font *font;
- int i = 0;
-
- for(font = rom->font_start; font; font = font->next_font, i++) {
- if((STI_U8(font->raw->width) == width) &&
- (STI_U8(font->raw->height) == height))
- return i;
- }
-
- return 0;
-}
-
-static struct sti_cooked_font * __init
-sti_select_font(struct sti_cooked_rom *rom)
-{
- struct sti_cooked_font *font;
- int i;
-
- if(font_width && font_height)
- font_index = sti_search_font(rom, font_height, font_width);
-
- for(font = rom->font_start, i = font_index;
- font && (i > 0);
- font = font->next_font, i--);
-
- if(font)
- return font;
- else
- return rom->font_start;
-}
-
-/* address is a pointer to a word mode or pci rom */
-static struct sti_struct * __init sti_read_rom(unsigned long address)
-{
- struct sti_struct *ret = NULL;
- struct sti_cooked_rom *cooked = NULL;
- struct sti_rom *raw = NULL;
- unsigned long size;
-
- ret = &default_sti;
-
- if(!ret)
- goto out_err;
-
- cooked = kmalloc(sizeof *cooked, GFP_KERNEL);
- raw = kmalloc(sizeof *raw, GFP_KERNEL);
-
- if(!(raw && cooked))
- goto out_err;
-
- /* reallocate raw */
- sti_rom_copy(address, 0, sizeof *raw, raw);
-
- dump_sti_rom(raw);
-
- size = STI_U32(raw->last_addr) + 1;
- size = 128*1024;
-// DPRINTK(("size %08lx\n", size));
-// DPRINTK(("font_start %08x\n", STI_U32(raw->font_start)));
-// kfree(raw);
- raw = kmalloc(size, GFP_KERNEL);
- if(!raw)
- goto out_err;
- sti_rom_copy(address, 0, size-1, raw);
-
- sti_cook_fonts(cooked, raw);
-// sti_cook_regions(cooked, raw);
-// sti_cook_functions(cooked, raw);
-
- if(STI_U32(raw->region_list)) {
- struct sti_rom_region *region =
- ((void *)raw) + STI_U32(raw->region_list) - 3;
-
-// DPRINTK(("region_list %08x\n", STI_U32(raw->region_list)));
-
- ret->regions = kmalloc(32, GFP_KERNEL); /* FIXME!! */
-
- ret->regions[0] = STI_U32(region[0].region);
- ret->regions[1] = STI_U32(region[1].region);
- ret->regions[2] = STI_U32(region[2].region);
- ret->regions[3] = STI_U32(region[3].region);
- ret->regions[4] = STI_U32(region[4].region);
- ret->regions[5] = STI_U32(region[5].region);
- ret->regions[6] = STI_U32(region[6].region);
- ret->regions[7] = STI_U32(region[7].region);
- }
-
- address = virt_to_phys(raw);
-
-#if 0
- DPRINTK(("init_graph %08x %08x\n"
- "state_mgmt %08x %08x\n"
- "font_unpmv %08x %08x\n"
- "block_move %08x %08x\n"
- "self_test %08x %08x\n"
- "excep_hdlr %08x %08x\n"
- "irq_conf %08x %08x\n"
- "set_cm_e %08x %08x\n"
- "dma_ctrl %08x %08x\n"
- "flow_ctrl %08x %08x\n"
- "user_timin %08x %08x\n"
- "process_m %08x %08x\n"
- "sti_util %08x %08x\n"
- "end_addr %08x %08x\n",
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->state_mgmt), STI_U32(raw->state_mgmt_m68k),
- STI_U32(raw->font_unpmv), STI_U32(raw->font_unpmv_m68k),
- STI_U32(raw->block_move), STI_U32(raw->block_move_m68k),
- STI_U32(raw->self_test), STI_U32(raw->self_test_m68k),
- STI_U32(raw->excep_hdlr), STI_U32(raw->excep_hdlr_m68k),
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
- STI_U32(raw->end_addr), STI_U32(raw->end_addr_m68k) ) );
-#endif
-
- ret->init_graph = sti_cook_function(((void *)raw)+STI_U32(raw->init_graph)-3,
- (STI_U32(raw->state_mgmt) -
- STI_U32(raw->init_graph))/4);
-
-
- ret->font_unpmv = sti_cook_function(((void *)raw)+STI_U32(raw->font_unpmv)-3,
- (STI_U32(raw->block_move) -
- STI_U32(raw->font_unpmv))/4);
-
- ret->block_move = sti_cook_function(((void *)raw)+STI_U32(raw->block_move)-3,
- (STI_U32(raw->self_test) -
- STI_U32(raw->block_move))/4);
-
- ret->inq_conf = sti_cook_function(((void *)raw)+STI_U32(raw->inq_conf),
- STI_U32(raw->set_cm_entry) -
- STI_U32(raw->inq_conf));
-
- ret->rom = cooked;
- ret->rom->raw = raw;
-
- ret->font = (struct sti_rom_font *) virt_to_phys(sti_select_font(ret->rom)->raw);
-
- return ret;
-
-out_err:
- if(raw)
- kfree(raw);
- if(cooked)
- kfree(cooked);
-
- return NULL;
-}
-
-#if 0
-static void dump_globcfg_ext(struct sti_glob_cfg_ext *cfg)
-{
- DPRINTK(("monitor %d\n"
- "in friendly mode: %d\n"
- "power consumption %d watts\n"
- "freq ref %d\n"
- "sti_mem_addr %p\n",
- cfg->curr_mon,
- cfg->friendly_boot,
- cfg->power,
- cfg->freq_ref,
- cfg->sti_mem_addr));
-}
-
-static void dump_globcfg(struct sti_glob_cfg *glob_cfg)
-{
- DPRINTK(("%d text planes\n"
- "%4d x %4d screen resolution\n"
- "%4d x %4d offscreen\n"
- "%4d x %4d layout\n"
- "regions at %08x %08x %08x %08x\n"
- "regions at %08x %08x %08x %08x\n"
- "reent_lvl %d\n"
- "save_addr %p\n",
- glob_cfg->text_planes,
- glob_cfg->onscreen_x, glob_cfg->onscreen_y,
- glob_cfg->offscreen_x, glob_cfg->offscreen_y,
- glob_cfg->total_x, glob_cfg->total_y,
- glob_cfg->region_ptrs[0], glob_cfg->region_ptrs[1],
- glob_cfg->region_ptrs[2], glob_cfg->region_ptrs[3],
- glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
- glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
- glob_cfg->reent_lvl,
- glob_cfg->save_addr));
- dump_globcfg_ext(PTR_STI(glob_cfg->ext_ptr));
-}
-#endif
-
-static void __init sti_init_glob_cfg(struct sti_struct *sti, unsigned long hpa,
- unsigned long rom_address)
-{
- struct sti_glob_cfg *glob_cfg;
- struct sti_glob_cfg_ext *glob_cfg_ext;
- void *save_addr;
- void *sti_mem_addr;
-
- glob_cfg = kmalloc(sizeof *sti->glob_cfg, GFP_KERNEL);
- glob_cfg_ext = kmalloc(sizeof *glob_cfg_ext, GFP_KERNEL);
- save_addr = kmalloc(1024 /*XXX*/, GFP_KERNEL);
- sti_mem_addr = kmalloc(1024, GFP_KERNEL);
-
- if((!glob_cfg) || (!glob_cfg_ext) || (!save_addr) || (!sti_mem_addr))
- return;
-
- memset(glob_cfg, 0, sizeof *glob_cfg);
- memset(glob_cfg_ext, 0, sizeof *glob_cfg_ext);
- memset(save_addr, 0, 1024);
- memset(sti_mem_addr, 0, 1024);
-
- glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
- glob_cfg->save_addr = STI_PTR(save_addr);
- glob_cfg->region_ptrs[0] = ((sti->regions[0]>>18)<<12) + rom_address;
- glob_cfg->region_ptrs[1] = ((sti->regions[1]>>18)<<12) + hpa;
- glob_cfg->region_ptrs[2] = ((sti->regions[2]>>18)<<12) + hpa;
- glob_cfg->region_ptrs[3] = ((sti->regions[3]>>18)<<12) + hpa;
- glob_cfg->region_ptrs[4] = ((sti->regions[4]>>18)<<12) + hpa;
- glob_cfg->region_ptrs[5] = ((sti->regions[5]>>18)<<12) + hpa;
- glob_cfg->region_ptrs[6] = ((sti->regions[6]>>18)<<12) + hpa;
- glob_cfg->region_ptrs[7] = ((sti->regions[7]>>18)<<12) + hpa;
-
- glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
-
- sti->glob_cfg = STI_PTR(glob_cfg);
-}
-
-static void __init sti_try_rom(unsigned long address, unsigned long hpa)
-{
- struct sti_struct *sti = NULL;
- u16 sig;
-
- /* if we can't read the ROM, bail out early. Not being able
- * to read the hpa is okay, for romless sti */
- if(pdc_add_valid((void*)address))
- return;
-
- printk("found potential STI ROM at %08lx\n", address);
-
- sig = le16_to_cpu(gsc_readw(address));
-
- if((sig&0xff) == 0x01) {
- sti = sti_read_rom(address);
- }
-
- if(sig == 0x0303) {
- printk("STI word mode ROM at %08lx, ignored\n",
- address);
-
- sti = NULL;
- }
-
- if(!sti)
- return;
-
- /* this is hacked. We need a better way to find out the HPA for
- * romless STI (eg search for the graphics devices we know about
- * by sversion) */
- if (!pdc_add_valid((void *)0xf5000000)) DPRINTK(("f4000000 b\n"));
- if (!pdc_add_valid((void *)0xf7000000)) DPRINTK(("f6000000 b\n"));
- if (!pdc_add_valid((void *)0xf9000000)) DPRINTK(("f8000000 b\n"));
- if (!pdc_add_valid((void *)0xfb000000)) DPRINTK(("fa000000 b\n"));
- sti_init_glob_cfg(sti, hpa, address);
-
- sti_init_graph(sti);
-
- //sti_inq_conf(sti);
-#if !defined(SERIAL_CONSOLE)
- {
- extern void pdc_console_die(void);
- pdc_console_die();
- }
-#endif
-
- take_over_console(&sti_con, 0, MAX_NR_CONSOLES-1, 1);
-
- /* sti_inq_conf(sti); */
-}
-
-static unsigned long sti_address;
-static unsigned long sti_hpa;
-
-static void __init sti_init_roms(void)
-{
- /* handle the command line */
- if(sti_address && sti_hpa) {
- sti_try_rom(sti_address, sti_hpa);
-
- return;
- }
-
- /* 712, 715, some other boxes don't have a separate STI ROM,
- * but use part of the regular flash */
- if(PAGE0->proc_sti) {
- printk("STI ROM from PDC at %08x\n", PAGE0->proc_sti);
- if(!pdc_add_valid((void *)0xf9000000))
- sti_try_rom(PAGE0->proc_sti, 0xf8000000);
- else if(!pdc_add_valid((void *)0xf5000000))
- sti_try_rom(PAGE0->proc_sti, 0xf4000000);
- else if(!pdc_add_valid((void *)0xf7000000))
- sti_try_rom(PAGE0->proc_sti, 0xf6000000);
- else if(!pdc_add_valid((void *)0xfb000000))
- sti_try_rom(PAGE0->proc_sti, 0xfa000000);
- }
-
- /* standard locations for GSC graphic devices */
- if(!pdc_add_valid((void *)0xf4000000))
- sti_try_rom(0xf4000000, 0xf4000000);
- if(!pdc_add_valid((void *)0xf6000000))
- sti_try_rom(0xf6000000, 0xf6000000);
- if(!pdc_add_valid((void *)0xf8000000))
- sti_try_rom(0xf8000000, 0xf8000000);
- if(!pdc_add_valid((void *)0xfa000000))
- sti_try_rom(0xfa000000, 0xfa000000);
-}
-
-static int __init sti_init(void)
-{
- printk("searching for byte mode STI ROMs\n");
- sti_init_roms();
- return 0;
-}
-
-module_init(sti_init)
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h
new file mode 100644
index 000000000000..0572f4fb1d5e
--- /dev/null
+++ b/drivers/video/sticore.h
@@ -0,0 +1,407 @@
+#ifndef STICORE_H
+#define STICORE_H
+
+/* generic STI structures & functions */
+
+#if 0
+#define DPRINTK(x) printk x
+#else
+#define DPRINTK(x)
+#endif
+
+#define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */
+
+#define STI_REGION_MAX 8 /* hardcoded STI constants */
+#define STI_DEV_NAME_LENGTH 32
+#define STI_MONITOR_MAX 256
+
+#define STI_FONT_HPROMAN8 1
+#define STI_FONT_KANA8 2
+
+/* The latency of the STI functions cannot really be reduced by setting
+ * this to 0; STI doesn't seem to be designed to allow calling a different
+ * function (or the same function with different arguments) after a
+ * function exited with 1 as return value.
+ *
+ * As all of the functions below could be called from interrupt context,
+ * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
+ * block. Really bad latency there.
+ *
+ * Probably the best solution to all this is have the generic code manage
+ * the screen buffer and a kernel thread to call STI occasionally.
+ *
+ * Luckily, the frame buffer guys have the same problem so we can just wait
+ * for them to fix it and steal their solution. prumpf
+ */
+
+#define STI_WAIT 1
+
+#include <asm/io.h> /* for USE_HPPA_IOREMAP */
+
+#if USE_HPPA_IOREMAP
+
+#define STI_PTR(p) (p)
+#define PTR_STI(p) (p)
+static int inline STI_CALL( unsigned long func,
+ void *flags, void *inptr, void *outptr, void *glob_cfg )
+{
+ int (*f)(void *,void *,void *,void *);
+ f = (void*)func;
+ return f(flags, inptr, outptr, glob_cfg);
+}
+
+#else /* !USE_HPPA_IOREMAP */
+
+#define STI_PTR(p) ( virt_to_phys(p) )
+#define PTR_STI(p) ( phys_to_virt((long)p) )
+#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
+ ({ \
+ pdc_sti_call( func, (unsigned long)STI_PTR(flags), \
+ (unsigned long)STI_PTR(inptr), \
+ (unsigned long)STI_PTR(outptr), \
+ (unsigned long)STI_PTR(glob_cfg)); \
+ })
+
+#endif /* USE_HPPA_IOREMAP */
+
+
+#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
+#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
+
+/* sti_font_xy() use the native font ROM ! */
+#define sti_font_x(sti) (PTR_STI(sti->font)->width)
+#define sti_font_y(sti) (PTR_STI(sti->font)->height)
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+extern struct sti_struct *sti_init_roms(void);
+
+/* XXX: this probably should not be here, but we rely on STI being
+ initialized early and independently of stifb at the moment, so
+ there's no other way for stifb to find it. */
+extern struct sti_struct *default_sti;
+
+extern struct display_switch fbcon_sti; /* fbcon-sti.c */
+
+int sti_init_graph(struct sti_struct *sti);
+void sti_inq_conf(struct sti_struct *sti);
+void sti_putc(struct sti_struct *sti, int c, int y, int x);
+void sti_set(struct sti_struct *sti, int src_y, int src_x,
+ int height, int width, u8 color);
+void sti_clear(struct sti_struct *sti, int src_y, int src_x,
+ int height, int width, int c);
+void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
+ int dst_y, int dst_x, int height, int width);
+
+
+/* STI function configuration structs */
+
+typedef union region {
+ struct {
+ u32 offset : 14; /* offset in 4kbyte page */
+ u32 sys_only : 1; /* don't map to user space */
+ u32 cache : 1; /* map to data cache */
+ u32 btlb : 1; /* map to block tlb */
+ u32 last : 1; /* last region in list */
+ u32 length : 14; /* length in 4kbyte page */
+ } region_desc;
+
+ u32 region; /* complete region value */
+} region_t;
+
+#define REGION_OFFSET_TO_PHYS( rt, hpa ) \
+ (((rt).region_desc.offset << 12) + (hpa))
+
+struct sti_glob_cfg_ext {
+ u8 curr_mon; /* current monitor configured */
+ u8 friendly_boot; /* in friendly boot mode */
+ s16 power; /* power calculation (in Watts) */
+ s32 freq_ref; /* frequency refrence */
+ u32 sti_mem_addr; /* pointer to global sti memory (size=sti_mem_request) */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_glob_cfg {
+ s32 text_planes; /* number of planes used for text */
+ s16 onscreen_x; /* screen width in pixels */
+ s16 onscreen_y; /* screen height in pixels */
+ s16 offscreen_x; /* offset width in pixels */
+ s16 offscreen_y; /* offset height in pixels */
+ s16 total_x; /* frame buffer width in pixels */
+ s16 total_y; /* frame buffer height in pixels */
+ u32 region_ptrs[STI_REGION_MAX]; /* region pointers */
+ s32 reent_lvl; /* storage for reentry level value */
+ u32 save_addr; /* where to save or restore reentrant state */
+ u32 ext_ptr; /* pointer to extended glob_cfg data structure */
+};
+
+
+/* STI init function structs */
+
+struct sti_init_flags {
+ u32 wait : 1; /* should routine idle wait or not */
+ u32 reset : 1; /* hard reset the device? */
+ u32 text : 1; /* turn on text display planes? */
+ u32 nontext : 1; /* turn on non-text display planes? */
+ u32 clear : 1; /* clear text display planes? */
+ u32 cmap_blk : 1; /* non-text planes cmap black? */
+ u32 enable_be_timer : 1; /* enable bus error timer */
+ u32 enable_be_int : 1; /* enable bus error timer interrupt */
+ u32 no_chg_tx : 1; /* don't change text settings */
+ u32 no_chg_ntx : 1; /* don't change non-text settings */
+ u32 no_chg_bet : 1; /* don't change berr timer settings */
+ u32 no_chg_bei : 1; /* don't change berr int settings */
+ u32 init_cmap_tx : 1; /* initialize cmap for text planes */
+ u32 cmt_chg : 1; /* change current monitor type */
+ u32 retain_ie : 1; /* don't allow reset to clear int enables */
+ u32 caller_bootrom : 1; /* set only by bootrom for each call */
+ u32 caller_kernel : 1; /* set only by kernel for each call */
+ u32 caller_other : 1; /* set only by non-[BR/K] caller */
+ u32 pad : 14; /* pad to word boundary */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_init_inptr_ext {
+ u8 config_mon_type; /* configure to monitor type */
+ u8 pad[1]; /* pad to word boundary */
+ u16 inflight_data; /* inflight data possible on PCI */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_init_inptr {
+ s32 text_planes; /* number of planes to use for text */
+ u32 ext_ptr; /* pointer to extended init_graph inptr data structure*/
+};
+
+
+struct sti_init_outptr {
+ s32 errno; /* error number on failure */
+ s32 text_planes; /* number of planes used for text */
+ u32 future_ptr; /* pointer to future data */
+};
+
+
+
+/* STI configuration function structs */
+
+struct sti_conf_flags {
+ u32 wait : 1; /* should routine idle wait or not */
+ u32 pad : 31; /* pad to word boundary */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_conf_inptr {
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_conf_outptr_ext {
+ u32 crt_config[3]; /* hardware specific X11/OGL information */
+ u32 crt_hdw[3];
+ u32 future_ptr;
+};
+
+struct sti_conf_outptr {
+ s32 errno; /* error number on failure */
+ s16 onscreen_x; /* screen width in pixels */
+ s16 onscreen_y; /* screen height in pixels */
+ s16 offscreen_x; /* offscreen width in pixels */
+ s16 offscreen_y; /* offscreen height in pixels */
+ s16 total_x; /* frame buffer width in pixels */
+ s16 total_y; /* frame buffer height in pixels */
+ s32 bits_per_pixel; /* bits/pixel device has configured */
+ s32 bits_used; /* bits which can be accessed */
+ s32 planes; /* number of fb planes in system */
+ u8 dev_name[STI_DEV_NAME_LENGTH]; /* null terminated product name */
+ u32 attributes; /* flags denoting attributes */
+ u32 ext_ptr; /* pointer to future data */
+};
+
+struct sti_rom {
+ u8 type[4];
+ u8 res004;
+ u8 num_mons;
+ u8 revno[2];
+ u32 graphics_id[2];
+
+ u32 font_start;
+ u32 statesize;
+ u32 last_addr;
+ u32 region_list;
+
+ u16 reentsize;
+ u16 maxtime;
+ u32 mon_tbl_addr;
+ u32 user_data_addr;
+ u32 sti_mem_req;
+
+ u32 user_data_size;
+ u16 power;
+ u8 bus_support;
+ u8 ext_bus_support;
+ u8 alt_code_type;
+ u8 ext_dd_struct[3];
+ u32 cfb_addr;
+
+ u32 init_graph;
+ u32 state_mgmt;
+ u32 font_unpmv;
+ u32 block_move;
+ u32 self_test;
+ u32 excep_hdlr;
+ u32 inq_conf;
+ u32 set_cm_entry;
+ u32 dma_ctrl;
+ u8 res040[7 * 4];
+
+ u32 init_graph_addr;
+ u32 state_mgmt_addr;
+ u32 font_unp_addr;
+ u32 block_move_addr;
+ u32 self_test_addr;
+ u32 excep_hdlr_addr;
+ u32 inq_conf_addr;
+ u32 set_cm_entry_addr;
+ u32 image_unpack_addr;
+ u32 pa_risx_addrs[7];
+};
+
+struct sti_rom_font {
+ u16 first_char;
+ u16 last_char;
+ u8 width;
+ u8 height;
+ u8 font_type; /* language type */
+ u8 bytes_per_char;
+ u32 next_font;
+ u8 underline_height;
+ u8 underline_pos;
+ u8 res008[2];
+};
+
+/* sticore internal font handling */
+
+struct sti_cooked_font {
+ struct sti_rom_font *raw;
+ struct sti_cooked_font *next_font;
+};
+
+struct sti_cooked_rom {
+ struct sti_rom *raw;
+ struct sti_cooked_font *font_start;
+};
+
+/* STI font printing function structs */
+
+struct sti_font_inptr {
+ u32 font_start_addr; /* address of font start */
+ s16 index; /* index into font table of character */
+ u8 fg_color; /* foreground color of character */
+ u8 bg_color; /* background color of character */
+ s16 dest_x; /* X location of character upper left */
+ s16 dest_y; /* Y location of character upper left */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_font_flags {
+ u32 wait : 1; /* should routine idle wait or not */
+ u32 non_text : 1; /* font unpack/move in non_text planes =1, text =0 */
+ u32 pad : 30; /* pad to word boundary */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_font_outptr {
+ s32 errno; /* error number on failure */
+ u32 future_ptr; /* pointer to future data */
+};
+
+/* STI blockmove structs */
+
+struct sti_blkmv_flags {
+ u32 wait : 1; /* should routine idle wait or not */
+ u32 color : 1; /* change color during move? */
+ u32 clear : 1; /* clear during move? */
+ u32 non_text : 1; /* block move in non_text planes =1, text =0 */
+ u32 pad : 28; /* pad to word boundary */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_blkmv_inptr {
+ u8 fg_color; /* foreground color after move */
+ u8 bg_color; /* background color after move */
+ s16 src_x; /* source upper left pixel x location */
+ s16 src_y; /* source upper left pixel y location */
+ s16 dest_x; /* dest upper left pixel x location */
+ s16 dest_y; /* dest upper left pixel y location */
+ s16 width; /* block width in pixels */
+ s16 height; /* block height in pixels */
+ u32 future_ptr; /* pointer to future data */
+};
+
+struct sti_blkmv_outptr {
+ s32 errno; /* error number on failure */
+ u32 future_ptr; /* pointer to future data */
+};
+
+
+/* internal generic STI struct */
+
+struct sti_struct {
+ spinlock_t lock;
+
+ /* the following fields needs to be filled in by the word/byte routines */
+ int font_width;
+ int font_height;
+ /* char **mon_strings; */
+ int sti_mem_request;
+ u32 graphics_id[2];
+
+ struct sti_cooked_rom *rom;
+
+ unsigned long font_unpmv;
+ unsigned long block_move;
+ unsigned long init_graph;
+ unsigned long inq_conf;
+
+ /* all following fields are initialized by the generic routines */
+ int text_planes;
+ region_t regions[STI_REGION_MAX];
+ unsigned long regions_phys[STI_REGION_MAX];
+
+ struct sti_glob_cfg *glob_cfg;
+ struct sti_cooked_font *font; /* ptr to selected font (cooked) */
+
+ struct sti_conf_outptr outptr; /* configuration */
+ struct sti_conf_outptr_ext outptr_ext;
+
+ /* PCI data structures (pg. 17ff from sti.pdf) */
+ struct pci_dev *pd;
+ u8 rm_entry[16]; /* pci region mapper array == pci config space offset */
+};
+
+
+
+/* helper functions */
+struct sti_struct *sti_init_roms(void);
+struct sti_struct *sti_get_rom(int);
+void sti_rom_copy(unsigned long base, unsigned long count, void *dest);
+struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
+ int (*search_font_fnc) (struct sti_cooked_rom *,int,int) );
+
+int sti_read_rom(int wordmode, struct sti_struct *sti,
+ unsigned long address);
+
+
+/* FIXME: Do we have another solution for this ? */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+static inline void sti_flush(unsigned long from, unsigned long len)
+{
+ flush_data_cache();
+ flush_kernel_dcache_range(from, len);
+ flush_icache_range(from, from+len);
+}
+
+#endif /* STICORE_H */
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 9f4af7cf66e1..27bf51f207bd 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1,27 +1,59 @@
/*
- * linux/drivers/video/stifb.c - Generic frame buffer driver for HP
- * workstations with STI (standard text interface) video firmware.
+ * linux/drivers/video/sti/stifb.c -
+ * Frame buffer driver for HP workstations with STI (standard text interface)
+ * video firmware.
*
+ * Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
+ * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+ *
* Based on:
- * linux/drivers/video/artistfb.c -- Artist frame buffer driver
- *
+ * - linux/drivers/video/artistfb.c -- Artist frame buffer driver
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- * based on skeletonfb, which was
+ * - based on skeletonfb, which was
* Created 28 Dec 1997 by Geert Uytterhoeven
+ * - HP Xhp cfb-based X11 window driver for XFree86
+ * (c)Copyright 1992 Hewlett-Packard Co.
+ *
+ *
+ * The following graphics display devices (NGLE family) are supported by this driver:
+ *
+ * HPA4070A known as "HCRX", a 1280x1024 color device with 8 planes
+ * HPA4071A known as "HCRX24", a 1280x1024 color device with 24 planes,
+ * optionally available with a hardware accelerator as HPA4071A_Z
+ * HPA1659A known as "CRX", a 1280x1024 color device with 8 planes
+ * HPA1439A known as "CRX24", a 1280x1024 color device with 24 planes,
+ * optionally available with a hardware accelerator.
+ * HPA1924A known as "GRX", a 1280x1024 grayscale device with 8 planes
+ * HPA2269A known as "Dual CRX", a 1280x1024 color device with 8 planes,
+ * implements support for two displays on a single graphics card.
+ * HP710C internal graphics support optionally available on the HP9000s710 SPU,
+ * supports 1280x1024 color displays with 8 planes.
+ * HP710G same as HP710C, 1280x1024 grayscale only
+ * HP710L same as HP710C, 1024x768 color only
+ * HP712 internal graphics support on HP9000s712 SPU, supports 640x480,
+ * 1024x768 or 1280x1024 color displays on 8 planes (Artist)
*
* 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. */
+ * for more details.
+ */
-/*
- * Notes:
- *
- * This driver assumes that the video has been set up in 1bpp mode by
- * the firmware. Since HP video tends to be planar rather than
- * packed-pixel this will probably work anyway even if it isn't.
+/* TODO:
+ * - remove the static fb_info to support multiple cards
+ * - remove the completely untested 1bpp mode
+ * - add support for h/w acceleration
+ * - add hardware cursor
+ * -
*/
+
+/* on supported graphic devices you may:
+ * #define FALLBACK_TO_1BPP to fall back to 1 bpp, or
+ * #undef FALLBACK_TO_1BPP to reject support for unsupported cards */
+#undef FALLBACK_TO_1BPP
+
+
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -32,179 +64,1322 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb32.h>
+
+#include <asm/grfioctl.h> /* for HP-UX compatibility */
+
+#include "sticore.h"
-#include "sti.h"
+#ifdef __LP64__
+/* return virtual address */
+#define REGION_BASE(fb_info, index) \
+ (fb_info->sti->glob_cfg->region_ptrs[index] | 0xffffffff00000000)
+#else
+/* return virtual address */
+#define REGION_BASE(fb_info, index) \
+ fb_info->sti->glob_cfg->region_ptrs[index]
+#endif
-static struct fb_ops stifb_ops;
+#define NGLEDEVDEPROM_CRT_REGION 1
+
+typedef struct {
+ __s32 video_config_reg;
+ __s32 misc_video_start;
+ __s32 horiz_timing_fmt;
+ __s32 serr_timing_fmt;
+ __s32 vert_timing_fmt;
+ __s32 horiz_state;
+ __s32 vert_state;
+ __s32 vtg_state_elements;
+ __s32 pipeline_delay;
+ __s32 misc_video_end;
+} video_setup_t;
+
+typedef struct {
+ __s16 sizeof_ngle_data;
+ __s16 x_size_visible; /* visible screen dim in pixels */
+ __s16 y_size_visible;
+ __s16 pad2[15];
+ __s16 cursor_pipeline_delay;
+ __s16 video_interleaves;
+ __s32 pad3[11];
+} ngle_rom_t;
struct stifb_info {
- struct fb_info_gen gen;
+ struct fb_info info;
+ unsigned int id;
+ ngle_rom_t ngle_rom;
struct sti_struct *sti;
+ int deviceSpecificConfig;
+ struct display disp;
};
-struct stifb_par {
-};
+static int stifb_force_bpp[MAX_STI_ROMS] = {0, };
-static struct stifb_info fb_info;
-static struct display disp;
+/* ------------------- chipset specific functions -------------------------- */
-int stifb_init(void);
-int stifb_setup(char*);
+/* offsets to graphic-chip internal registers */
-extern struct display_switch fbcon_sti;
+#define REG_1 0x000118
+#define REG_2 0x000480
+#define REG_3 0x0004a0
+#define REG_4 0x000600
+#define REG_6 0x000800
+#define REG_8 0x000820
+#define REG_9 0x000a04
+#define REG_10 0x018000
+#define REG_11 0x018004
+#define REG_12 0x01800c
+#define REG_13 0x018018
+#define REG_14 0x01801c
+#define REG_15 0x200000
+#define REG_15b0 0x200000
+#define REG_16b1 0x200005
+#define REG_16b3 0x200007
+#define REG_21 0x200218
+#define REG_22 0x0005a0
+#define REG_23 0x0005c0
+#define REG_26 0x200118
+#define REG_27 0x200308
+#define REG_32 0x21003c
+#define REG_33 0x210040
+#define REG_34 0x200008
+#define REG_35 0x018010
+#define REG_38 0x210020
+#define REG_39 0x210120
+#define REG_40 0x210130
+#define REG_42 0x210028
+#define REG_43 0x21002c
+#define REG_44 0x210030
+#define REG_45 0x210034
-/* ------------------- chipset specific functions -------------------------- */
+#define READ_BYTE(fb,reg) __raw_readb((fb)->info.fix.mmio_start + (reg))
+#define READ_WORD(fb,reg) __raw_readl((fb)->info.fix.mmio_start + (reg))
+#define WRITE_BYTE(value,fb,reg) __raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
+#define WRITE_WORD(value,fb,reg) __raw_writel((value),(fb)->info.fix.mmio_start + (reg))
-static int
-sti_encode_fix(struct fb_fix_screeninfo *fix,
- const void *par, struct fb_info_gen *info)
+#define ENABLE 1 /* for enabling/disabling screen */
+#define DISABLE 0
+
+#define NGLE_LOCK(fb_info) do { } while (0)
+#define NGLE_UNLOCK(fb_info) do { } while (0)
+
+static void
+SETUP_HW(struct stifb_info *fb)
{
- /* XXX: what about smem_len? */
- fix->smem_start = PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
- fix->type = FB_TYPE_PLANES; /* well, sort of */
+ char stat;
- return 0;
+ do {
+ stat = READ_BYTE(fb, REG_15b0);
+ if (!stat)
+ stat = READ_BYTE(fb, REG_15b0);
+ } while (stat);
}
-static int
-sti_decode_var(const struct fb_var_screeninfo *var,
- void *par, struct fb_info_gen *info)
+
+static void
+SETUP_FB(struct stifb_info *fb)
+{
+ unsigned int reg10_value = 0;
+
+ SETUP_HW(fb);
+ switch (fb->id)
+ {
+ case CRT_ID_VISUALIZE_EG:
+ case S9000_ID_ARTIST:
+ case S9000_ID_A1659A:
+ reg10_value = 0x13601000;
+ break;
+ case S9000_ID_A1439A:
+ if (fb->info.var.bits_per_pixel == 32)
+ reg10_value = 0xBBA0A000;
+ else
+ reg10_value = 0x13601000;
+ break;
+ case S9000_ID_HCRX:
+ if (fb->info.var.bits_per_pixel == 32)
+ reg10_value = 0xBBA0A000;
+ else
+ reg10_value = 0x13602000;
+ break;
+ case S9000_ID_TIMBER:
+ case CRX24_OVERLAY_PLANES:
+ reg10_value = 0x13602000;
+ break;
+ }
+ if (reg10_value)
+ WRITE_WORD(reg10_value, fb, REG_10);
+ WRITE_WORD(0x83000300, fb, REG_14);
+ SETUP_HW(fb);
+ WRITE_BYTE(1, fb, REG_16b1);
+}
+
+static void
+START_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
{
- return 0;
+ SETUP_HW(fb);
+ WRITE_WORD(0xBBE0F000, fb, REG_10);
+ WRITE_WORD(0x03000300, fb, REG_14);
+ WRITE_WORD(~0, fb, REG_13);
}
-static int
-sti_encode_var(struct fb_var_screeninfo *var,
- const void *par, struct fb_info_gen *info)
+static void
+WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color)
{
- var->xres = PTR_STI(fb_info.sti->glob_cfg)->onscreen_x;
- var->yres = PTR_STI(fb_info.sti->glob_cfg)->onscreen_y;
- var->xres_virtual = PTR_STI(fb_info.sti->glob_cfg)->total_x;
- var->yres_virtual = PTR_STI(fb_info.sti->glob_cfg)->total_y;
- var->xoffset = var->yoffset = 0;
+ SETUP_HW(fb);
+ WRITE_WORD(((0x100+index)<<2), fb, REG_3);
+ WRITE_WORD(color, fb, REG_4);
+}
- var->bits_per_pixel = 1;
- var->grayscale = 0;
+static void
+FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
+{
+ WRITE_WORD(0x400, fb, REG_2);
+ if (fb->info.var.bits_per_pixel == 32) {
+ WRITE_WORD(0x83000100, fb, REG_1);
+ } else {
+ if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG)
+ WRITE_WORD(0x80000100, fb, REG_26);
+ else
+ WRITE_WORD(0x80000100, fb, REG_1);
+ }
+ SETUP_FB(fb);
+}
- return 0;
+static void
+SETUP_RAMDAC(struct stifb_info *fb)
+{
+ SETUP_HW(fb);
+ WRITE_WORD(0x04000000, fb, 0x1020);
+ WRITE_WORD(0xff000000, fb, 0x1028);
+}
+
+static void
+CRX24_SETUP_RAMDAC(struct stifb_info *fb)
+{
+ SETUP_HW(fb);
+ WRITE_WORD(0x04000000, fb, 0x1000);
+ WRITE_WORD(0x02000000, fb, 0x1004);
+ WRITE_WORD(0xff000000, fb, 0x1008);
+ WRITE_WORD(0x05000000, fb, 0x1000);
+ WRITE_WORD(0x02000000, fb, 0x1004);
+ WRITE_WORD(0x03000000, fb, 0x1008);
+}
+
+#if 0
+static void
+HCRX_SETUP_RAMDAC(struct stifb_info *fb)
+{
+ WRITE_WORD(0xffffffff, fb, REG_32);
+}
+#endif
+
+static void
+CRX24_SET_OVLY_MASK(struct stifb_info *fb)
+{
+ SETUP_HW(fb);
+ WRITE_WORD(0x13a02000, fb, REG_11);
+ WRITE_WORD(0x03000300, fb, REG_14);
+ WRITE_WORD(0x000017f0, fb, REG_3);
+ WRITE_WORD(0xffffffff, fb, REG_13);
+ WRITE_WORD(0xffffffff, fb, REG_22);
+ WRITE_WORD(0x00000000, fb, REG_23);
+}
+
+static void
+ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+{
+ unsigned int value = enable ? 0x43000000 : 0x03000000;
+ SETUP_HW(fb);
+ WRITE_WORD(0x06000000, fb, 0x1030);
+ WRITE_WORD(value, fb, 0x1038);
+}
+
+static void
+CRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+{
+ unsigned int value = enable ? 0x10000000 : 0x30000000;
+ SETUP_HW(fb);
+ WRITE_WORD(0x01000000, fb, 0x1000);
+ WRITE_WORD(0x02000000, fb, 0x1004);
+ WRITE_WORD(value, fb, 0x1008);
+}
+
+static void
+ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+{
+ u32 DregsMiscVideo = REG_21;
+ u32 DregsMiscCtl = REG_27;
+
+ SETUP_HW(fb);
+ if (enable) {
+ WRITE_WORD(READ_WORD(fb, DregsMiscVideo) | 0x0A000000, fb, DregsMiscVideo);
+ WRITE_WORD(READ_WORD(fb, DregsMiscCtl) | 0x00800000, fb, DregsMiscCtl);
+ } else {
+ WRITE_WORD(READ_WORD(fb, DregsMiscVideo) & ~0x0A000000, fb, DregsMiscVideo);
+ WRITE_WORD(READ_WORD(fb, DregsMiscCtl) & ~0x00800000, fb, DregsMiscCtl);
+ }
+}
+
+#define GET_ROMTABLE_INDEX(fb) \
+ (READ_BYTE(fb, REG_16b3) - 1)
+
+#define HYPER_CONFIG_PLANES_24 0x00000100
+
+#define IS_24_DEVICE(fb) \
+ (fb->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)
+
+#define IS_888_DEVICE(fb) \
+ (!(IS_24_DEVICE(fb)))
+
+#define GET_FIFO_SLOTS(fb, cnt, numslots) \
+{ while (cnt < numslots) \
+ cnt = READ_WORD(fb, REG_34); \
+ cnt -= numslots; \
}
+#define IndexedDcd 0 /* Pixel data is indexed (pseudo) color */
+#define Otc04 2 /* Pixels in each longword transfer (4) */
+#define Otc32 5 /* Pixels in each longword transfer (32) */
+#define Ots08 3 /* Each pixel is size (8)d transfer (1) */
+#define OtsIndirect 6 /* Each bit goes through FG/BG color(8) */
+#define AddrLong 5 /* FB address is Long aligned (pixel) */
+#define BINovly 0x2 /* 8 bit overlay */
+#define BINapp0I 0x0 /* Application Buffer 0, Indexed */
+#define BINapp1I 0x1 /* Application Buffer 1, Indexed */
+#define BINapp0F8 0xa /* Application Buffer 0, Fractional 8-8-8 */
+#define BINattr 0xd /* Attribute Bitmap */
+#define RopSrc 0x3
+#define BitmapExtent08 3 /* Each write hits ( 8) bits in depth */
+#define BitmapExtent32 5 /* Each write hits (32) bits in depth */
+#define DataDynamic 0 /* Data register reloaded by direct access */
+#define MaskDynamic 1 /* Mask register reloaded by direct access */
+#define MaskOtc 0 /* Mask contains Object Count valid bits */
+
+#define MaskAddrOffset(offset) (offset)
+#define StaticReg(en) (en)
+#define BGx(en) (en)
+#define FGx(en) (en)
+
+#define BAJustPoint(offset) (offset)
+#define BAIndexBase(base) (base)
+#define BA(F,C,S,A,J,B,I) \
+ (((F)<<31)|((C)<<27)|((S)<<24)|((A)<<21)|((J)<<16)|((B)<<12)|(I))
+
+#define IBOvals(R,M,X,S,D,L,B,F) \
+ (((R)<<8)|((M)<<16)|((X)<<24)|((S)<<29)|((D)<<28)|((L)<<31)|((B)<<1)|(F))
+
+#define NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, val) \
+ WRITE_WORD(val, fb, REG_14)
+
+#define NGLE_QUICK_SET_DST_BM_ACCESS(fb, val) \
+ WRITE_WORD(val, fb, REG_11)
+
+#define NGLE_QUICK_SET_CTL_PLN_REG(fb, val) \
+ WRITE_WORD(val, fb, REG_12)
+
+#define NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, plnmsk32) \
+ WRITE_WORD(plnmsk32, fb, REG_13)
+
+#define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, fg32) \
+ WRITE_WORD(fg32, fb, REG_35)
+
+#define NGLE_SET_TRANSFERDATA(fb, val) \
+ WRITE_WORD(val, fb, REG_8)
+
+#define NGLE_SET_DSTXY(fb, val) \
+ WRITE_WORD(val, fb, REG_6)
+
+#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) ( \
+ (u32) (fbaddrbase) + \
+ ( (unsigned int) ( (y) << 13 ) | \
+ (unsigned int) ( (x) << 2 ) ) \
+ )
+
+#define NGLE_BINC_SET_DSTADDR(fb, addr) \
+ WRITE_WORD(addr, fb, REG_3)
+
+#define NGLE_BINC_SET_SRCADDR(fb, addr) \
+ WRITE_WORD(addr, fb, REG_2)
+
+#define NGLE_BINC_SET_DSTMASK(fb, mask) \
+ WRITE_WORD(mask, fb, REG_22)
+
+#define NGLE_BINC_WRITE32(fb, data32) \
+ WRITE_WORD(data32, fb, REG_23)
+
+#define START_COLORMAPLOAD(fb, cmapBltCtlData32) \
+ WRITE_WORD((cmapBltCtlData32), fb, REG_38)
+
+#define SET_LENXY_START_RECFILL(fb, lenxy) \
+ WRITE_WORD(lenxy, fb, REG_9)
+
+static void
+HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+{
+ u32 DregsHypMiscVideo = REG_33;
+ unsigned int value;
+ SETUP_HW(fb);
+ value = READ_WORD(fb, DregsHypMiscVideo);
+ if (enable)
+ value |= 0x0A000000;
+ else
+ value &= ~0x0A000000;
+ WRITE_WORD(value, fb, DregsHypMiscVideo);
+}
+
+
+/* BufferNumbers used by SETUP_ATTR_ACCESS() */
+#define BUFF0_CMAP0 0x00001e02
+#define BUFF1_CMAP0 0x02001e02
+#define BUFF1_CMAP3 0x0c001e02
+#define ARTIST_CMAP0 0x00000102
+#define HYPER_CMAP8 0x00000100
+#define HYPER_CMAP24 0x00000800
+
+static void
+SETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber)
+{
+ SETUP_HW(fb);
+ WRITE_WORD(0x2EA0D000, fb, REG_11);
+ WRITE_WORD(0x23000302, fb, REG_14);
+ WRITE_WORD(BufferNumber, fb, REG_12);
+ WRITE_WORD(0xffffffff, fb, REG_8);
+}
+
+static void
+SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
+{
+ WRITE_WORD(0x00000000, fb, REG_6);
+ WRITE_WORD((width<<16) | height, fb, REG_9);
+ WRITE_WORD(0x05000000, fb, REG_6);
+ WRITE_WORD(0x00040001, fb, REG_9);
+}
+
+static void
+FINISH_ATTR_ACCESS(struct stifb_info *fb)
+{
+ SETUP_HW(fb);
+ WRITE_WORD(0x00000000, fb, REG_12);
+}
+
+static void
+elkSetupPlanes(struct stifb_info *fb)
+{
+ SETUP_RAMDAC(fb);
+ SETUP_FB(fb);
+}
+
+static void
+ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber)
+{
+ SETUP_ATTR_ACCESS(fb, BufferNumber);
+ SET_ATTR_SIZE(fb, fb->info.var.xres, fb->info.var.yres);
+ FINISH_ATTR_ACCESS(fb);
+ SETUP_FB(fb);
+}
+
+
static void
-sti_get_par(void *par, struct fb_info_gen *info)
+rattlerSetupPlanes(struct stifb_info *fb)
+{
+ CRX24_SETUP_RAMDAC(fb);
+
+ /* replacement for: SETUP_FB(fb, CRX24_OVERLAY_PLANES); */
+ WRITE_WORD(0x83000300, fb, REG_14);
+ SETUP_HW(fb);
+ WRITE_BYTE(1, fb, REG_16b1);
+
+ /* XXX: replace by fb_setmem(), smem_start or screen_base ? */
+ memset_io(fb->info.fix.smem_start, 0xff,
+ fb->info.var.yres*fb->info.fix.line_length);
+
+ CRX24_SET_OVLY_MASK(fb);
+ SETUP_FB(fb);
+}
+
+
+#define HYPER_CMAP_TYPE 0
+#define NGLE_CMAP_INDEXED0_TYPE 0
+#define NGLE_CMAP_OVERLAY_TYPE 3
+
+/* typedef of LUT (Colormap) BLT Control Register */
+typedef union /* Note assumption that fields are packed left-to-right */
+{ u32 all;
+ struct
+ {
+ unsigned enable : 1;
+ unsigned waitBlank : 1;
+ unsigned reserved1 : 4;
+ unsigned lutOffset : 10; /* Within destination LUT */
+ unsigned lutType : 2; /* Cursor, image, overlay */
+ unsigned reserved2 : 4;
+ unsigned length : 10;
+ } fields;
+} NgleLutBltCtl;
+
+
+#if 0
+static NgleLutBltCtl
+setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
+{
+ NgleLutBltCtl lutBltCtl;
+
+ /* set enable, zero reserved fields */
+ lutBltCtl.all = 0x80000000;
+ lutBltCtl.fields.length = length;
+
+ switch (fb->id)
+ {
+ case S9000_ID_A1439A: /* CRX24 */
+ if (fb->var.bits_per_pixel == 8) {
+ lutBltCtl.fields.lutType = NGLE_CMAP_OVERLAY_TYPE;
+ lutBltCtl.fields.lutOffset = 0;
+ } else {
+ lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+ lutBltCtl.fields.lutOffset = 0 * 256;
+ }
+ break;
+
+ case S9000_ID_ARTIST:
+ lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+ lutBltCtl.fields.lutOffset = 0 * 256;
+ break;
+
+ default:
+ lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+ lutBltCtl.fields.lutOffset = 0;
+ break;
+ }
+
+ /* Offset points to start of LUT. Adjust for within LUT */
+ lutBltCtl.fields.lutOffset += offsetWithinLut;
+
+ return lutBltCtl;
+}
+#endif
+
+static NgleLutBltCtl
+setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
+{
+ NgleLutBltCtl lutBltCtl;
+
+ /* set enable, zero reserved fields */
+ lutBltCtl.all = 0x80000000;
+
+ lutBltCtl.fields.length = length;
+ lutBltCtl.fields.lutType = HYPER_CMAP_TYPE;
+
+ /* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */
+ if (fb->info.var.bits_per_pixel == 8)
+ lutBltCtl.fields.lutOffset = 2 * 256;
+ else
+ lutBltCtl.fields.lutOffset = 0 * 256;
+
+ /* Offset points to start of LUT. Adjust for within LUT */
+ lutBltCtl.fields.lutOffset += offsetWithinLut;
+
+ return lutBltCtl;
+}
+
+
+static void hyperUndoITE(struct stifb_info *fb)
+{
+ int nFreeFifoSlots = 0;
+ u32 fbAddr;
+
+ NGLE_LOCK(fb);
+
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1);
+ WRITE_WORD(0xffffffff, fb, REG_32);
+
+ /* Write overlay transparency mask so only entry 255 is transparent */
+
+ /* Hardware setup for full-depth write to "magic" location */
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ BA(IndexedDcd, Otc04, Ots08, AddrLong,
+ BAJustPoint(0), BINovly, BAIndexBase(0)));
+ NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
+ IBOvals(RopSrc, MaskAddrOffset(0),
+ BitmapExtent08, StaticReg(0),
+ DataDynamic, MaskOtc, BGx(0), FGx(0)));
+
+ /* Now prepare to write to the "magic" location */
+ fbAddr = NGLE_LONG_FB_ADDRESS(0, 1532, 0);
+ NGLE_BINC_SET_DSTADDR(fb, fbAddr);
+ NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffff);
+ NGLE_BINC_SET_DSTMASK(fb, 0xffffffff);
+
+ /* Finally, write a zero to clear the mask */
+ NGLE_BINC_WRITE32(fb, 0);
+
+ NGLE_UNLOCK(fb);
+}
+
+static void
+ngleDepth8_ClearImagePlanes(struct stifb_info *fb)
{
+ /* FIXME! */
+}
+
+static void
+ngleDepth24_ClearImagePlanes(struct stifb_info *fb)
+{
+ /* FIXME! */
}
static void
-sti_set_par(const void *par, struct fb_info_gen *info)
+ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
+{
+ int nFreeFifoSlots = 0;
+ u32 packed_dst;
+ u32 packed_len;
+
+ NGLE_LOCK(fb);
+
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 4);
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ BA(IndexedDcd, Otc32, OtsIndirect,
+ AddrLong, BAJustPoint(0),
+ BINattr, BAIndexBase(0)));
+ NGLE_QUICK_SET_CTL_PLN_REG(fb, ctlPlaneReg);
+ NGLE_SET_TRANSFERDATA(fb, 0xffffffff);
+
+ NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
+ IBOvals(RopSrc, MaskAddrOffset(0),
+ BitmapExtent08, StaticReg(1),
+ DataDynamic, MaskOtc,
+ BGx(0), FGx(0)));
+ packed_dst = 0;
+ packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2);
+ NGLE_SET_DSTXY(fb, packed_dst);
+ SET_LENXY_START_RECFILL(fb, packed_len);
+
+ /*
+ * In order to work around an ELK hardware problem (Buffy doesn't
+ * always flush it's buffers when writing to the attribute
+ * planes), at least 4 pixels must be written to the attribute
+ * planes starting at (X == 1280) and (Y != to the last Y written
+ * by BIF):
+ */
+
+ if (fb->id == S9000_ID_A1659A) { /* ELK_DEVICE_ID */
+ /* It's safe to use scanline zero: */
+ packed_dst = (1280 << 16);
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2);
+ NGLE_SET_DSTXY(fb, packed_dst);
+ packed_len = (4 << 16) | 1;
+ SET_LENXY_START_RECFILL(fb, packed_len);
+ } /* ELK Hardware Kludge */
+
+ /**** Finally, set the Control Plane Register back to zero: ****/
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1);
+ NGLE_QUICK_SET_CTL_PLN_REG(fb, 0);
+
+ NGLE_UNLOCK(fb);
+}
+
+static void
+ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)
+{
+ int nFreeFifoSlots = 0;
+ u32 packed_dst;
+ u32 packed_len;
+
+ NGLE_LOCK(fb);
+
+ /* Hardware setup */
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 8);
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ BA(IndexedDcd, Otc04, Ots08, AddrLong,
+ BAJustPoint(0), BINovly, BAIndexBase(0)));
+
+ NGLE_SET_TRANSFERDATA(fb, 0xffffffff); /* Write foreground color */
+
+ NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, data);
+ NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask);
+
+ packed_dst = 0;
+ packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
+ NGLE_SET_DSTXY(fb, packed_dst);
+
+ /* Write zeroes to overlay planes */
+ NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
+ IBOvals(RopSrc, MaskAddrOffset(0),
+ BitmapExtent08, StaticReg(0),
+ DataDynamic, MaskOtc, BGx(0), FGx(0)));
+
+ SET_LENXY_START_RECFILL(fb, packed_len);
+
+ NGLE_UNLOCK(fb);
+}
+
+static void
+hyperResetPlanes(struct stifb_info *fb, int enable)
+{
+ unsigned int controlPlaneReg;
+
+ NGLE_LOCK(fb);
+
+ if (IS_24_DEVICE(fb))
+ if (fb->info.var.bits_per_pixel == 32)
+ controlPlaneReg = 0x04000F00;
+ else
+ controlPlaneReg = 0x00000F00; /* 0x00000800 should be enought, but lets clear all 4 bits */
+ else
+ controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */
+
+ switch (enable) {
+ case 1: /* ENABLE */
+ /* clear screen */
+ if (IS_24_DEVICE(fb))
+ ngleDepth24_ClearImagePlanes(fb);
+ else
+ ngleDepth8_ClearImagePlanes(fb);
+
+ /* Paint attribute planes for default case.
+ * On Hyperdrive, this means all windows using overlay cmap 0. */
+ ngleResetAttrPlanes(fb, controlPlaneReg);
+
+ /* clear overlay planes */
+ ngleClearOverlayPlanes(fb, 0xff, 255);
+
+ /**************************************************
+ ** Also need to counteract ITE settings
+ **************************************************/
+ hyperUndoITE(fb);
+ break;
+
+ case 0: /* DISABLE */
+ /* clear screen */
+ if (IS_24_DEVICE(fb))
+ ngleDepth24_ClearImagePlanes(fb);
+ else
+ ngleDepth8_ClearImagePlanes(fb);
+ ngleResetAttrPlanes(fb, controlPlaneReg);
+ ngleClearOverlayPlanes(fb, 0xff, 0);
+ break;
+
+ case -1: /* RESET */
+ hyperUndoITE(fb);
+ ngleResetAttrPlanes(fb, controlPlaneReg);
+ break;
+ }
+
+ NGLE_UNLOCK(fb);
+}
+
+/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */
+
+static void
+ngleGetDeviceRomData(struct stifb_info *fb)
{
+#if 0
+XXX: FIXME: !!!
+ int *pBytePerLongDevDepData;/* data byte == LSB */
+ int *pRomTable;
+ NgleDevRomData *pPackedDevRomData;
+ int sizePackedDevRomData = sizeof(*pPackedDevRomData);
+ char *pCard8;
+ int i;
+ char *mapOrigin = NULL;
+
+ int romTableIdx;
+
+ pPackedDevRomData = fb->ngle_rom;
+
+ SETUP_HW(fb);
+ if (fb->id == S9000_ID_ARTIST) {
+ pPackedDevRomData->cursor_pipeline_delay = 4;
+ pPackedDevRomData->video_interleaves = 4;
+ } else {
+ /* Get pointer to unpacked byte/long data in ROM */
+ pBytePerLongDevDepData = fb->sti->regions[NGLEDEVDEPROM_CRT_REGION];
+
+ /* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480 */
+ if (fb->id == S9000_ID_TOMCAT)
+ {
+ /* jump to the correct ROM table */
+ GET_ROMTABLE_INDEX(romTableIdx);
+ while (romTableIdx > 0)
+ {
+ pCard8 = (Card8 *) pPackedDevRomData;
+ pRomTable = pBytePerLongDevDepData;
+ /* Pack every fourth byte from ROM into structure */
+ for (i = 0; i < sizePackedDevRomData; i++)
+ {
+ *pCard8++ = (Card8) (*pRomTable++);
+ }
+
+ pBytePerLongDevDepData = (Card32 *)
+ ((Card8 *) pBytePerLongDevDepData +
+ pPackedDevRomData->sizeof_ngle_data);
+
+ romTableIdx--;
+ }
+ }
+
+ pCard8 = (Card8 *) pPackedDevRomData;
+
+ /* Pack every fourth byte from ROM into structure */
+ for (i = 0; i < sizePackedDevRomData; i++)
+ {
+ *pCard8++ = (Card8) (*pBytePerLongDevDepData++);
+ }
+ }
+
+ SETUP_FB(fb);
+#endif
+}
+
+
+#define HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES 4
+#define HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE 8
+#define HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE 10
+#define HYPERBOWL_MODE2_8_24 15
+
+/* HCRX specific boot-time initialization */
+static void __init
+SETUP_HCRX(struct stifb_info *fb)
+{
+ int hyperbowl;
+ int nFreeFifoSlots = 0;
+
+ if (fb->id != S9000_ID_HCRX)
+ return;
+
+ /* Initialize Hyperbowl registers */
+ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
+
+ if (IS_24_DEVICE(fb)) {
+ hyperbowl = (fb->info.var.bits_per_pixel == 32) ?
+ HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE :
+ HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE;
+
+ /* First write to Hyperbowl must happen twice (bug) */
+ WRITE_WORD(hyperbowl, fb, REG_40);
+ WRITE_WORD(hyperbowl, fb, REG_40);
+
+ WRITE_WORD(HYPERBOWL_MODE2_8_24, fb, REG_39);
+
+ WRITE_WORD(0x014c0148, fb, REG_42); /* Set lut 0 to be the direct color */
+ WRITE_WORD(0x404c4048, fb, REG_43);
+ WRITE_WORD(0x034c0348, fb, REG_44);
+ WRITE_WORD(0x444c4448, fb, REG_45);
+ } else {
+ hyperbowl = HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES;
+
+ /* First write to Hyperbowl must happen twice (bug) */
+ WRITE_WORD(hyperbowl, fb, REG_40);
+ WRITE_WORD(hyperbowl, fb, REG_40);
+
+ WRITE_WORD(0x00000000, fb, REG_42);
+ WRITE_WORD(0x00000000, fb, REG_43);
+ WRITE_WORD(0x00000000, fb, REG_44);
+ WRITE_WORD(0x444c4048, fb, REG_45);
+ }
}
+
+/* ------------------- driver specific functions --------------------------- */
+
+
static int
-sti_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp, struct fb_info *info)
+stifb_setcolreg(u_int regno, u_int red, u_int green,
+ u_int blue, u_int transp, struct fb_info *info)
{
+ struct stifb_info *fb = (struct stifb_info *) info;
+ u32 color;
+
+ if (regno >= 256) /* no. of hw registers */
+ return 1;
+
+ START_IMAGE_COLORMAP_ACCESS(fb);
+
+ if (fb->info.var.grayscale) {
+ /* gray = 0.30*R + 0.59*G + 0.11*B */
+ color = ((red * 77) +
+ (green * 151) +
+ (blue * 28)) >> 8;
+ } else {
+ color = ((red << 16) |
+ (green << 8) |
+ (blue));
+ }
+
+ WRITE_IMAGE_COLOR(fb, regno, color);
+
+ if (fb->id == S9000_ID_HCRX) {
+ NgleLutBltCtl lutBltCtl;
+
+ lutBltCtl = setHyperLutBltCtl(fb,
+ 0, /* Offset w/i LUT */
+ 256); /* Load entire LUT */
+ NGLE_BINC_SET_SRCADDR(fb,
+ NGLE_LONG_FB_ADDRESS(0, 0x100, 0));
+ /* 0x100 is same as used in WRITE_IMAGE_COLOR() */
+ START_COLORMAPLOAD(fb, lutBltCtl.all);
+ SETUP_FB(fb);
+ } else {
+ /* cleanup colormap hardware */
+ FINISH_IMAGE_COLORMAP_ACCESS(fb);
+ }
+
return 0;
}
+#if 0
static void
-sti_set_disp(const void *par, struct display *disp,
- struct fb_info_gen *info)
+stifb_loadcmap(struct stifb_info *fb)
{
- disp->dispsw = &fbcon_sti;
+ u32 color;
+ int i;
+
+ if (!fb->cmap_reload)
+ return;
+
+ START_IMAGE_COLORMAP_ACCESS(fb);
+ for (i = 0; i < 256; i++) {
+ if (fb->info.var.bits_per_pixel > 8) {
+ color = (i << 16) | (i << 8) | i;
+ } else {
+ if (fb->info.var.grayscale) {
+ /* gray = 0.30*R + 0.59*G + 0.11*B */
+ color = ((fb->palette[i].red * 77) +
+ (fb->palette[i].green * 151) +
+ (fb->palette[i].blue * 28)) >> 8;
+ } else {
+ color = ((fb->palette[i].red << 16) |
+ (fb->palette[i].green << 8) |
+ (fb->palette[i].blue));
+ }
+ }
+ WRITE_IMAGE_COLOR(fb, i, color);
+ }
+ if (fb->id == S9000_ID_HCRX) {
+ NgleLutBltCtl lutBltCtl;
+
+ lutBltCtl = setHyperLutBltCtl(fb,
+ 0, /* Offset w/i LUT */
+ 256); /* Load entire LUT */
+ NGLE_BINC_SET_SRCADDR(fb,
+ NGLE_LONG_FB_ADDRESS(0, 0x100, 0));
+ /* 0x100 is same as used in WRITE_IMAGE_COLOR() */
+ START_COLORMAPLOAD(fb, lutBltCtl.all);
+ SETUP_FB(fb);
+ } else {
+ /* cleanup colormap hardware */
+ FINISH_IMAGE_COLORMAP_ACCESS(fb);
+ }
+ fb->cmap_reload = 0;
}
+#endif
-static void
-sti_detect(void)
+static int
+stifb_blank(int blank_mode, struct fb_info *info)
{
+ struct stifb_info *fb = (struct stifb_info *) info;
+ int enable = (blank_mode == 0) ? ENABLE : DISABLE;
+
+ switch (fb->id) {
+ case S9000_ID_A1439A:
+ CRX24_ENABLE_DISABLE_DISPLAY(fb, enable);
+ break;
+ case CRT_ID_VISUALIZE_EG:
+ case S9000_ID_ARTIST:
+ ARTIST_ENABLE_DISABLE_DISPLAY(fb, enable);
+ break;
+ case S9000_ID_HCRX:
+ HYPER_ENABLE_DISABLE_DISPLAY(fb, enable);
+ break;
+ case S9000_ID_A1659A:; /* fall through */
+ case S9000_ID_TIMBER:;
+ case CRX24_OVERLAY_PLANES:;
+ default:
+ ENABLE_DISABLE_DISPLAY(fb, enable);
+ break;
+ }
+
+ SETUP_FB(fb);
+ return 0;
+}
+
+static void __init
+stifb_init_display(struct stifb_info *fb)
+{
+ int id = fb->id;
+
+ SETUP_FB(fb);
+
+ /* HCRX specific initialization */
+ SETUP_HCRX(fb);
+
+ /*
+ if (id == S9000_ID_HCRX)
+ hyperInitSprite(fb);
+ else
+ ngleInitSprite(fb);
+ */
+
+ /* Initialize the image planes. */
+ switch (id) {
+ case S9000_ID_HCRX:
+ hyperResetPlanes(fb, ENABLE);
+ break;
+ case S9000_ID_A1439A:
+ rattlerSetupPlanes(fb);
+ break;
+ case S9000_ID_A1659A:
+ case S9000_ID_ARTIST:
+ case CRT_ID_VISUALIZE_EG:
+ elkSetupPlanes(fb);
+ break;
+ }
+
+ /* Clear attribute planes on non HCRX devices. */
+ switch (id) {
+ case S9000_ID_A1659A:
+ case S9000_ID_A1439A:
+ if (fb->info.var.bits_per_pixel == 32)
+ ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
+ else {
+ ngleSetupAttrPlanes(fb, BUFF1_CMAP0);
+ }
+ if (id == S9000_ID_A1439A)
+ ngleClearOverlayPlanes(fb, 0xff, 0);
+ break;
+ case S9000_ID_ARTIST:
+ case CRT_ID_VISUALIZE_EG:
+ if (fb->info.var.bits_per_pixel == 32)
+ ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
+ else {
+ ngleSetupAttrPlanes(fb, ARTIST_CMAP0);
+ }
+ break;
+ }
+ stifb_blank(0, (struct fb_info *)fb); /* 0=enable screen */
+
+ SETUP_FB(fb);
}
+
/* ------------ Interfaces to hardware functions ------------ */
-struct fbgen_hwswitch sti_switch = {
- .detect = sti_detect,
- .encode_fix = sti_encode_fix,
- .decode_var = sti_decode_var,
- .encode_var = sti_encode_var,
- .get_par = sti_get_par,
- .set_par = sti_set_par,
- .getcolreg = sti_getcolreg,
- .set_disp = sti_set_disp
-};
+static struct fb_ops stifb_ops = {
+ .owner = THIS_MODULE,
+ .fb_set_var = gen_set_var,
+ .fb_get_cmap = gen_get_cmap,
+ .fb_set_cmap = gen_set_cmap,
+ .fb_setcolreg = stifb_setcolreg,
+ /* .fb_pan_display = stifb_pan_display, */
+ .fb_blank = stifb_blank,
+ /*
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ */
+};
-/* ------------ Hardware Independent Functions ------------ */
/*
* Initialization
*/
int __init
-stifb_init(void)
+stifb_init_fb(struct sti_struct *sti, int force_bpp)
{
- printk("searching for word mode STI ROMs\n");
- /* XXX: in the future this will return a list of ROMs */
- if ((fb_info.sti = sti_init_roms()) == NULL)
- return -ENXIO;
-
- fb_info.gen.info.node = NODEV;
- fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
- fb_info.gen.info.fbops = &stifb_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;
- strcpy(fb_info.gen.info.modename, "STI Generic");
- fb_info.gen.fbhw = &sti_switch;
- fb_info.gen.fbhw->detect();
- fb_info.gen.info.screen_base =
- (void *) PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
- /* This should give a reasonable default video mode */
- fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
- fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
- fbgen_set_disp(-1, &fb_info.gen);
- do_install_cmap(0, &fb_info.gen);
- pdc_console_die();
- if (register_framebuffer(&fb_info.gen.info) < 0)
- return -EINVAL;
-
- printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename);
+ struct fb_fix_screeninfo *fix;
+ struct fb_var_screeninfo *var;
+ struct display *disp;
+ struct display_switch *dispsw;
+ struct stifb_info *fb;
+ struct fb_info *info;
+ unsigned long sti_rom_address;
+ char *dev_name;
+ int bpp, xres, yres;
+
+ fb = kmalloc(sizeof(*fb), GFP_ATOMIC);
+ if (!fb) {
+ printk(KERN_ERR "stifb: Could not allocate stifb structure\n");
+ return -ENODEV;
+ }
+
+ info = &fb->info;
+
+ /* set struct to a known state */
+ memset(fb, 0, sizeof(*fb));
+ fix = &info->fix;
+ var = &info->var;
+ disp = &fb->disp;
+ info->disp = &fb->disp;
+
+ fb->sti = sti;
+ /* store upper 32bits of the graphics id */
+ fb->id = fb->sti->graphics_id[0];
+
+ /* only supported cards are allowed */
+ switch (fb->id) {
+ case S9000_ID_ARTIST:
+ case S9000_ID_HCRX:
+ case S9000_ID_TIMBER:
+ case S9000_ID_A1659A:
+ case S9000_ID_A1439A:
+ case CRT_ID_VISUALIZE_EG:
+ break;
+ default:
+ printk(KERN_WARNING "stifb: Unsupported gfx card id 0x%08x\n",
+ fb->id);
+ goto out_err1;
+ }
+
+ /* default to 8 bpp on most graphic chips */
+ bpp = 8;
+ xres = sti_onscreen_x(fb->sti);
+ yres = sti_onscreen_y(fb->sti);
+
+ ngleGetDeviceRomData(fb);
+
+ /* get (virtual) io region base addr */
+ fix->mmio_start = REGION_BASE(fb,2);
+ fix->mmio_len = 0x400000;
+
+ /* Reject any device not in the NGLE family */
+ switch (fb->id) {
+ case S9000_ID_A1659A: /* CRX/A1659A */
+ break;
+ case S9000_ID_ELM: /* GRX, grayscale but else same as A1659A */
+ var->grayscale = 1;
+ fb->id = S9000_ID_A1659A;
+ break;
+ case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */
+ dev_name = fb->sti->outptr.dev_name;
+ if (strstr(dev_name, "GRAYSCALE") ||
+ strstr(dev_name, "Grayscale") ||
+ strstr(dev_name, "grayscale"))
+ var->grayscale = 1;
+ break;
+ case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */
+ /* FIXME: TomCat supports two heads:
+ * fb.iobase = REGION_BASE(fb_info,3);
+ * fb.screen_base = (void*) REGION_BASE(fb_info,2);
+ * for now we only support the left one ! */
+ xres = fb->ngle_rom.x_size_visible;
+ yres = fb->ngle_rom.y_size_visible;
+ fb->id = S9000_ID_A1659A;
+ break;
+ case S9000_ID_A1439A: /* CRX24/A1439A */
+ bpp = 32;
+ break;
+ case S9000_ID_HCRX: /* Hyperdrive/HCRX */
+ memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom));
+ if ((fb->sti->regions_phys[0] & 0xfc000000) ==
+ (fb->sti->regions_phys[2] & 0xfc000000))
+ sti_rom_address = fb->sti->regions_phys[0];
+ else
+ sti_rom_address = fb->sti->regions_phys[1];
+#ifdef __LP64__
+ sti_rom_address |= 0xffffffff00000000;
+#endif
+ fb->deviceSpecificConfig = __raw_readl(sti_rom_address);
+ if (IS_24_DEVICE(fb)) {
+ if (force_bpp == 8 || force_bpp == 32)
+ bpp = force_bpp;
+ else
+ bpp = 32;
+ } else
+ bpp = 8;
+ READ_WORD(fb, REG_15);
+ SETUP_HW(fb);
+ break;
+ case CRT_ID_VISUALIZE_EG:
+ case S9000_ID_ARTIST: /* Artist */
+ break;
+ default:
+#ifdef FALLBACK_TO_1BPP
+ printk(KERN_WARNING
+ "stifb: Unsupported graphics card (id=0x%08x) "
+ "- now trying 1bpp mode instead\n",
+ fb->id);
+ bpp = 1; /* default to 1 bpp */
+ break;
+#else
+ printk(KERN_WARNING
+ "stifb: Unsupported graphics card (id=0x%08x) "
+ "- skipping.\n",
+ fb->id);
+ goto out_err1;
+#endif
+ }
+
+
+ /* get framebuffer pysical and virtual base addr & len (64bit ready) */
+ fix->smem_start = fb->sti->regions_phys[1] | 0xffffffff00000000;
+ fix->smem_len = fb->sti->regions[1].region_desc.length * 4096;
+
+ fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
+ if (!fix->line_length)
+ fix->line_length = 2048; /* default */
+ fix->accel = FB_ACCEL_NONE;
+
+ switch (bpp) {
+ case 1:
+ fix->type = FB_TYPE_PLANES; /* well, sort of */
+ fix->visual = FB_VISUAL_MONO10;
+ dispsw = &fbcon_sti;
+ break;
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ dispsw = &fbcon_cfb8;
+ var->red.length = var->green.length = var->blue.length = 8;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ dispsw = &fbcon_cfb32;
+ var->red.length = var->green.length = var->blue.length = var->transp.length = 8;
+ var->blue.offset = 0;
+ var->green.offset = 8;
+ var->red.offset = 16;
+ var->transp.offset = 24;
+ break;
+#endif
+ default:
+ dispsw = &fbcon_dummy;
+ break;
+ }
+
+ var->xres = var->xres_virtual = xres;
+ var->yres = var->yres_virtual = yres;
+ var->bits_per_pixel = bpp;
+
+ strcpy(info->modename, "stifb");
+ info->node = NODEV;
+ info->fbops = &stifb_ops;
+ info->screen_base = (void*) REGION_BASE(fb,1);
+ info->disp = disp;
+ info->changevar = NULL;
+ info->switch_con = gen_switch;
+ info->updatevar = &gen_update_var;
+ info->flags = FBINFO_FLAG_DEFAULT;
+ info->currcon = -1;
+
+ /* This has to been done !!! */
+ fb_alloc_cmap(&info->cmap, 256, 0);
+ stifb_init_display(fb);
+ gen_set_disp(-1, info);
+ disp->dispsw = dispsw;
+
+ if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb")) {
+ printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",
+ fix->smem_start, fix->smem_start+fix->smem_len);
+ goto out_err1;
+ }
+
+ if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {
+ printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",
+ fix->mmio_start, fix->mmio_start+fix->mmio_len);
+ goto out_err2;
+ }
+
+ if (register_framebuffer(&fb->info) < 0)
+ goto out_err3;
+
+ printk(KERN_INFO
+ "fb%d: %s %dx%d-%d frame buffer device, id: %04x, mmio: 0x%04lx\n",
+ minor(fb->info.node),
+ fb->info.modename,
+ disp->var.xres,
+ disp->var.yres,
+ disp->var.bits_per_pixel,
+ fb->id,
+ fix->mmio_start);
return 0;
-}
- /*
- * Cleanup
- */
+out_err3:
+ release_mem_region(fix->mmio_start, fix->mmio_len);
+out_err2:
+ release_mem_region(fix->smem_start, fix->smem_len);
+out_err1:
+ kfree(fb);
+ return -ENXIO;
+}
-void
-stifb_cleanup(struct fb_info *info)
+int __init
+stifb_init(void)
{
- printk("stifb_cleanup: you're on crack\n");
+ struct sti_struct *sti;
+ int i;
+
+
+ if (sti_init_roms() == NULL)
+ return -ENXIO; /* no STI cards available */
+
+ for (i = 0; i < MAX_STI_ROMS; i++) {
+ sti = sti_get_rom(i);
+ if (sti)
+ stifb_init_fb(sti, stifb_force_bpp[i]);
+ else
+ break;
+ }
+ return 0;
}
+/*
+ * Cleanup
+ */
+
+static void __exit
+stifb_cleanup(void)
+{
+ // unregister_framebuffer();
+}
int __init
stifb_setup(char *options)
{
- /* XXX: we should take the resolution, bpp as command line arguments. */
+ int i;
+
+ if (!options || !*options)
+ return 0;
+
+ if (strncmp(options, "bpp", 3) == 0) {
+ options += 3;
+ for (i = 0; i < MAX_STI_ROMS; i++) {
+ if (*options++ == ':')
+ stifb_force_bpp[i] = simple_strtoul(options, &options, 10);
+ else
+ break;
+ }
+ }
return 0;
}
+__setup("stifb=", stifb_setup);
-/* ------------------------------------------------------------------------- */
+#ifdef MODULE
+module_init(stifb_init);
+#endif
+module_exit(stifb_cleanup);
+MODULE_AUTHOR("Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
+MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(bpp, "i");
+MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)");
-static struct fb_ops stifb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = fbgen_get_fix,
- .fb_get_var = fbgen_get_var,
- .fb_set_var = fbgen_set_var,
- .fb_get_cmap = fbgen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_pan_display =fbgen_pan_display,
- .fb_blank = fbgen_blank,
-};
diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c
index a278639af752..57b37fa4084b 100644
--- a/drivers/video/sun3fb.c
+++ b/drivers/video/sun3fb.c
@@ -646,7 +646,7 @@ sizechange:
kfree(fb);
return -EINVAL;
}
- printk("fb%d: %s\n", GET_FB_IDX(fb->info.node), p);
+ printk("fb%d: %s\n", minor(fb->info.node), p);
return 0;
}
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index bde930eb65f3..7a828918c948 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -77,7 +77,6 @@
#include <linux/spinlock.h>
#include <video/tdfx.h>
-#include <video/fbcon.h>
#undef TDFXFB_DEBUG
#ifdef TDFXFB_DEBUG
@@ -143,10 +142,10 @@ static struct pci_device_id tdfxfb_id_table[] __devinitdata = {
};
static struct pci_driver tdfxfb_driver = {
- .name = "tdfxfb",
- .id_table = tdfxfb_id_table,
- .probe = tdfxfb_probe,
- .remove = __devexit_p(tdfxfb_remove),
+ .name = "tdfxfb",
+ .id_table = tdfxfb_id_table,
+ .probe = tdfxfb_probe,
+ .remove = __devexit_p(tdfxfb_remove),
};
MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
@@ -162,16 +161,14 @@ static int tdfxfb_set_par(struct fb_info *info);
static int tdfxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
static int tdfxfb_blank(int blank, struct fb_info *info);
-static int tdfxfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *image);
+static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
static struct fb_ops tdfxfb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_check_var = tdfxfb_check_var,
.fb_set_par = tdfxfb_set_par,
.fb_setcolreg = tdfxfb_setcolreg,
@@ -180,20 +177,20 @@ static struct fb_ops tdfxfb_ops = {
.fb_fillrect = tdfxfb_fillrect,
.fb_copyarea = tdfxfb_copyarea,
.fb_imageblit = tdfxfb_imageblit,
+ .fb_sync = banshee_wait_idle,
+ .fb_cursor = soft_cursor,
};
/*
* do_xxx: Hardware-specific functions
*/
static u32 do_calc_pll(int freq, int *freq_out);
-static void do_write_regs(struct banshee_reg *reg);
-static unsigned long do_lfb_size(unsigned short);
+static void do_write_regs(struct fb_info *info, struct banshee_reg *reg);
+static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short);
/*
* Driver data
*/
-static struct tdfx_par default_par;
-
static int nopan = 0;
static int nowrap = 1; // not implemented (yet)
static int inverse = 0;
@@ -204,132 +201,133 @@ static char *mode_option __initdata = NULL;
* ------------------------------------------------------------------------- */
#ifdef VGA_REG_IO
-static inline u8 vga_inb(u32 reg) { return inb(reg); }
-static inline u16 vga_inw(u32 reg) { return inw(reg); }
-static inline u16 vga_inl(u32 reg) { return inl(reg); }
+static inline u8 vga_inb(struct tdfx_par *par, u32 reg) { return inb(reg); }
+static inline u16 vga_inw(struct tdfx_par *par, u32 reg) { return inw(reg); }
+static inline u16 vga_inl(struct tdfx_par *par, u32 reg) { return inl(reg); }
-static inline void vga_outb(u32 reg, u8 val) { outb(val, reg); }
-static inline void vga_outw(u32 reg, u16 val) { outw(val, reg); }
-static inline void vga_outl(u32 reg, u32 val) { outl(val, reg); }
+static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) { outb(val, reg); }
+static inline void vga_outw(struct tdfx_par *par, u32 reg, u16 val) { outw(val, reg); }
+static inline void vga_outl(struct tdfx_par *par, u32 reg, u32 val) { outl(val, reg); }
#else
-static inline u8 vga_inb(u32 reg) {
- return inb(default_par.iobase + reg - 0x300);
+static inline u8 vga_inb(struct tdfx_par *par, u32 reg) {
+ return inb(par->iobase + reg - 0x300);
}
-static inline u16 vga_inw(u32 reg) {
- return inw(default_par.iobase + reg - 0x300);
+static inline u16 vga_inw(struct tdfx_par *par, u32 reg) {
+ return inw(par->iobase + reg - 0x300);
}
-static inline u16 vga_inl(u32 reg) {
- return inl(default_par.iobase + reg - 0x300);
+static inline u16 vga_inl(struct tdfx_par *par, u32 reg) {
+ return inl(par->iobase + reg - 0x300);
}
-static inline void vga_outb(u32 reg, u8 val) {
- outb(val, default_par.iobase + reg - 0x300);
+static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) {
+ outb(val, par->iobase + reg - 0x300);
}
-static inline void vga_outw(u32 reg, u16 val) {
- outw(val, default_par.iobase + reg - 0x300);
+static inline void vga_outw(struct tdfx_par *par, u32 reg, u16 val) {
+ outw(val, par->iobase + reg - 0x300);
}
-static inline void vga_outl(u32 reg, u32 val) {
- outl(val, default_par.iobase + reg - 0x300);
+static inline void vga_outl(struct tdfx_par *par, u32 reg, u32 val) {
+ outl(val, par->iobase + reg - 0x300);
}
#endif
-static inline void gra_outb(u32 idx, u8 val) {
- vga_outb(GRA_I, idx); vga_outb(GRA_D, val);
+static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) {
+ vga_outb(par, GRA_I, idx); vga_outb(par, GRA_D, val);
}
-static inline u8 gra_inb(u32 idx) {
- vga_outb(GRA_I, idx); return vga_inb(GRA_D);
+static inline u8 gra_inb(struct tdfx_par *par, u32 idx) {
+ vga_outb(par, GRA_I, idx); return vga_inb(par, GRA_D);
}
-static inline void seq_outb(u32 idx, u8 val) {
- vga_outb(SEQ_I, idx); vga_outb(SEQ_D, val);
+static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) {
+ vga_outb(par, SEQ_I, idx); vga_outb(par, SEQ_D, val);
}
-static inline u8 seq_inb(u32 idx) {
- vga_outb(SEQ_I, idx); return vga_inb(SEQ_D);
+static inline u8 seq_inb(struct tdfx_par *par, u32 idx) {
+ vga_outb(par, SEQ_I, idx); return vga_inb(par, SEQ_D);
}
-static inline void crt_outb(u32 idx, u8 val) {
- vga_outb(CRT_I, idx); vga_outb(CRT_D, val);
+static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val) {
+ vga_outb(par, CRT_I, idx); vga_outb(par, CRT_D, val);
}
-static inline u8 crt_inb(u32 idx) {
- vga_outb(CRT_I, idx); return vga_inb(CRT_D);
+static inline u8 crt_inb(struct tdfx_par *par, u32 idx) {
+ vga_outb(par, CRT_I, idx); return vga_inb(par, CRT_D);
}
-static inline void att_outb(u32 idx, u8 val)
+static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val)
{
unsigned char tmp;
- tmp = vga_inb(IS1_R);
- vga_outb(ATT_IW, idx);
- vga_outb(ATT_IW, val);
+ tmp = vga_inb(par, IS1_R);
+ vga_outb(par, ATT_IW, idx);
+ vga_outb(par, ATT_IW, val);
}
-static inline u8 att_inb(u32 idx)
+static inline u8 att_inb(struct tdfx_par *par, u32 idx)
{
unsigned char tmp;
- tmp = vga_inb(IS1_R);
- vga_outb(ATT_IW, idx);
- return vga_inb(ATT_IW);
+ tmp = vga_inb(par, IS1_R);
+ vga_outb(par, ATT_IW, idx);
+ return vga_inb(par, ATT_IW);
}
-static inline void vga_disable_video(void)
+static inline void vga_disable_video(struct tdfx_par *par)
{
unsigned char s;
- s = seq_inb(0x01) | 0x20;
- seq_outb(0x00, 0x01);
- seq_outb(0x01, s);
- seq_outb(0x00, 0x03);
+ s = seq_inb(par, 0x01) | 0x20;
+ seq_outb(par, 0x00, 0x01);
+ seq_outb(par, 0x01, s);
+ seq_outb(par, 0x00, 0x03);
}
-static inline void vga_enable_video(void)
+static inline void vga_enable_video(struct tdfx_par *par)
{
unsigned char s;
- s = seq_inb(0x01) & 0xdf;
- seq_outb(0x00, 0x01);
- seq_outb(0x01, s);
- seq_outb(0x00, 0x03);
+ s = seq_inb(par, 0x01) & 0xdf;
+ seq_outb(par, 0x00, 0x01);
+ seq_outb(par, 0x01, s);
+ seq_outb(par, 0x00, 0x03);
}
-static inline void vga_disable_palette(void)
+static inline void vga_disable_palette(struct tdfx_par *par)
{
- vga_inb(IS1_R);
- vga_outb(ATT_IW, 0x00);
+ vga_inb(par, IS1_R);
+ vga_outb(par, ATT_IW, 0x00);
}
-static inline void vga_enable_palette(void)
+static inline void vga_enable_palette(struct tdfx_par *par)
{
- vga_inb(IS1_R);
- vga_outb(ATT_IW, 0x20);
+ vga_inb(par, IS1_R);
+ vga_outb(par, ATT_IW, 0x20);
}
-static inline u32 tdfx_inl(unsigned int reg)
+static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg)
{
- return readl(default_par.regbase_virt + reg);
+ return readl(par->regbase_virt + reg);
}
-static inline void tdfx_outl(unsigned int reg, u32 val)
+static inline void tdfx_outl(struct tdfx_par *par, unsigned int reg, u32 val)
{
- writel(val, default_par.regbase_virt + reg);
+ writel(val, par->regbase_virt + reg);
}
-static inline void banshee_make_room(int size)
+static inline void banshee_make_room(struct tdfx_par *par, int size)
{
- while((tdfx_inl(STATUS) & 0x1f) < size);
+ while((tdfx_inl(par, STATUS) & 0x1f) < size);
}
-static inline void banshee_wait_idle(void)
+static inline void banshee_wait_idle(struct fb_info *info)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
int i = 0;
- banshee_make_room(1);
- tdfx_outl(COMMAND_3D, COMMAND_3D_NOP);
+ banshee_make_room(par, 1);
+ tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP);
while(1) {
- i = (tdfx_inl(STATUS) & STATUS_BUSY) ? 0 : i + 1;
+ i = (tdfx_inl(par, STATUS) & STATUS_BUSY) ? 0 : i + 1;
if(i == 3) break;
}
}
@@ -337,11 +335,11 @@ static inline void banshee_wait_idle(void)
/*
* Set the color of a palette entry in 8bpp mode
*/
-static inline void do_setpalentry(unsigned regno, u32 c)
+static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
{
- banshee_make_room(2);
- tdfx_outl(DACADDR, regno);
- tdfx_outl(DACDATA, c);
+ banshee_make_room(par, 2);
+ tdfx_outl(par, DACADDR, regno);
+ tdfx_outl(par, DACDATA, c);
}
static u32 do_calc_pll(int freq, int* freq_out)
@@ -373,71 +371,72 @@ static u32 do_calc_pll(int freq, int* freq_out)
return (n << 8) | (m << 2) | k;
}
-static void do_write_regs(struct banshee_reg* reg)
+static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
int i;
- banshee_wait_idle();
+ banshee_wait_idle(info);
- tdfx_outl(MISCINIT1, tdfx_inl(MISCINIT1) | 0x01);
+ tdfx_outl(par, MISCINIT1, tdfx_inl(par, MISCINIT1) | 0x01);
- crt_outb(0x11, crt_inb(0x11) & 0x7f); /* CRT unprotect */
+ crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */
- banshee_make_room(3);
- tdfx_outl(VGAINIT1, reg->vgainit1 & 0x001FFFFF);
- tdfx_outl(VIDPROCCFG, reg->vidcfg & ~0x00000001);
+ banshee_make_room(par, 3);
+ tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF);
+ tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001);
#if 0
- tdfx_outl(PLLCTRL1, reg->mempll);
- tdfx_outl(PLLCTRL2, reg->gfxpll);
+ tdfx_outl(par, PLLCTRL1, reg->mempll);
+ tdfx_outl(par, PLLCTRL2, reg->gfxpll);
#endif
- tdfx_outl(PLLCTRL0, reg->vidpll);
+ tdfx_outl(par, PLLCTRL0, reg->vidpll);
- vga_outb(MISC_W, reg->misc[0x00] | 0x01);
+ vga_outb(par, MISC_W, reg->misc[0x00] | 0x01);
for (i = 0; i < 5; i++)
- seq_outb(i, reg->seq[i]);
+ seq_outb(par, i, reg->seq[i]);
for (i = 0; i < 25; i++)
- crt_outb(i, reg->crt[i]);
+ crt_outb(par, i, reg->crt[i]);
for (i = 0; i < 9; i++)
- gra_outb(i, reg->gra[i]);
+ gra_outb(par, i, reg->gra[i]);
for (i = 0; i < 21; i++)
- att_outb(i, reg->att[i]);
+ att_outb(par, i, reg->att[i]);
- crt_outb(0x1a, reg->ext[0]);
- crt_outb(0x1b, reg->ext[1]);
+ crt_outb(par, 0x1a, reg->ext[0]);
+ crt_outb(par, 0x1b, reg->ext[1]);
- vga_enable_palette();
- vga_enable_video();
+ vga_enable_palette(par);
+ vga_enable_video(par);
- banshee_make_room(11);
- tdfx_outl(VGAINIT0, reg->vgainit0);
- tdfx_outl(DACMODE, reg->dacmode);
- tdfx_outl(VIDDESKSTRIDE, reg->stride);
- tdfx_outl(HWCURPATADDR, 0);
+ banshee_make_room(par, 11);
+ tdfx_outl(par, VGAINIT0, reg->vgainit0);
+ tdfx_outl(par, DACMODE, reg->dacmode);
+ tdfx_outl(par, VIDDESKSTRIDE, reg->stride);
+ tdfx_outl(par, HWCURPATADDR, 0);
- tdfx_outl(VIDSCREENSIZE,reg->screensize);
- tdfx_outl(VIDDESKSTART, reg->startaddr);
- tdfx_outl(VIDPROCCFG, reg->vidcfg);
- tdfx_outl(VGAINIT1, reg->vgainit1);
- tdfx_outl(MISCINIT0, reg->miscinit0);
-
- banshee_make_room(8);
- tdfx_outl(SRCBASE, reg->srcbase);
- tdfx_outl(DSTBASE, reg->dstbase);
- tdfx_outl(COMMANDEXTRA_2D, 0);
- tdfx_outl(CLIP0MIN, 0);
- tdfx_outl(CLIP0MAX, 0x0fff0fff);
- tdfx_outl(CLIP1MIN, 0);
- tdfx_outl(CLIP1MAX, 0x0fff0fff);
- tdfx_outl(SRCXY, 0);
-
- banshee_wait_idle();
+ tdfx_outl(par, VIDSCREENSIZE,reg->screensize);
+ tdfx_outl(par, VIDDESKSTART, reg->startaddr);
+ tdfx_outl(par, VIDPROCCFG, reg->vidcfg);
+ tdfx_outl(par, VGAINIT1, reg->vgainit1);
+ tdfx_outl(par, MISCINIT0, reg->miscinit0);
+
+ banshee_make_room(par, 8);
+ tdfx_outl(par, SRCBASE, reg->srcbase);
+ tdfx_outl(par, DSTBASE, reg->dstbase);
+ tdfx_outl(par, COMMANDEXTRA_2D, 0);
+ tdfx_outl(par, CLIP0MIN, 0);
+ tdfx_outl(par, CLIP0MAX, 0x0fff0fff);
+ tdfx_outl(par, CLIP1MIN, 0);
+ tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
+ tdfx_outl(par, SRCXY, 0);
+
+ banshee_wait_idle(info);
}
-static unsigned long do_lfb_size(unsigned short dev_id)
+static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
{
u32 draminit0 = 0;
u32 draminit1 = 0;
@@ -445,8 +444,8 @@ static unsigned long do_lfb_size(unsigned short dev_id)
u32 lfbsize = 0;
int sgram_p = 0;
- draminit0 = tdfx_inl(DRAMINIT0);
- draminit1 = tdfx_inl(DRAMINIT1);
+ draminit0 = tdfx_inl(par, DRAMINIT0);
+ draminit1 = tdfx_inl(par, DRAMINIT1);
if ((dev_id == PCI_DEVICE_ID_3DFX_BANSHEE) ||
(dev_id == PCI_DEVICE_ID_3DFX_VOODOO3)) {
@@ -467,12 +466,12 @@ static unsigned long do_lfb_size(unsigned short dev_id)
lfbsize <<= 20;
}
/* disable block writes for SDRAM (why?) */
- miscinit1 = tdfx_inl(MISCINIT1);
+ miscinit1 = tdfx_inl(par, MISCINIT1);
miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS;
miscinit1 |= MISCINIT1_CLUT_INV;
- banshee_make_room(1);
- tdfx_outl(MISCINIT1, miscinit1);
+ banshee_make_room(par, 1);
+ tdfx_outl(par, MISCINIT1, miscinit1);
return lfbsize;
}
@@ -710,7 +709,7 @@ static int tdfxfb_set_par(struct fb_info *info)
VGAINIT0_WAKEUP_3C3 |
VGAINIT0_ALT_READBACK |
VGAINIT0_EXTSHIFTOUT;
- reg.vgainit1 = tdfx_inl(VGAINIT1) & 0x1fffff;
+ reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff;
reg.cursloc = 0;
@@ -740,7 +739,7 @@ static int tdfxfb_set_par(struct fb_info *info)
reg.screensize = info->var.xres | (info->var.yres << 12);
reg.vidcfg &= ~VIDCFG_HALF_MODE;
- reg.miscinit0 = tdfx_inl(MISCINIT0);
+ reg.miscinit0 = tdfx_inl(par, MISCINIT0);
#if defined(__BIG_ENDIAN)
switch (info->var.bits_per_pixel) {
@@ -758,8 +757,8 @@ static int tdfxfb_set_par(struct fb_info *info)
reg.miscinit0 &= ~(1 << 31);
break;
}
-#endif
- do_write_regs(&reg);
+#endif
+ do_write_regs(par, &reg);
/* Now change fb_fix_screeninfo according to changes in par */
info->fix.line_length = info->var.xres * ((info->var.bits_per_pixel + 7)>>3);
@@ -773,6 +772,7 @@ static int tdfxfb_set_par(struct fb_info *info)
static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue,unsigned transp,struct fb_info *info)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
u32 rgbcol;
if (regno >= info->cmap.len) return 1;
@@ -782,7 +782,7 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
rgbcol =(((u32)red & 0xff00) << 8) |
(((u32)green & 0xff00) << 0) |
(((u32)blue & 0xff00) >> 8);
- do_setpalentry(regno, rgbcol);
+ do_setpalentry(par, regno, rgbcol);
break;
/* Truecolor has no hardware color palettes. */
case FB_VISUAL_TRUECOLOR:
@@ -805,9 +805,10 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
static int tdfxfb_blank(int blank, struct fb_info *info)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
u32 dacmode, state = 0, vgablank = 0;
- dacmode = tdfx_inl(DACMODE);
+ dacmode = tdfx_inl(par, DACMODE);
switch (blank) {
case 0: /* Screen: On; HSync: On, VSync: On */
@@ -834,21 +835,22 @@ static int tdfxfb_blank(int blank, struct fb_info *info)
dacmode &= ~(BIT(1) | BIT(3));
dacmode |= state;
- banshee_make_room(1);
- tdfx_outl(DACMODE, dacmode);
+ banshee_make_room(par, 1);
+ tdfx_outl(par, DACMODE, dacmode);
if (vgablank)
- vga_disable_video();
+ vga_disable_video(par);
else
- vga_enable_video();
+ vga_enable_video(par);
return 0;
}
/*
* Set the starting position of the visible screen to var->yoffset
*/
-static int tdfxfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
u32 addr;
if (nopan || var->xoffset || (var->yoffset > var->yres_virtual))
@@ -857,8 +859,8 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var, int con,
return -EINVAL;
addr = var->yoffset * info->fix.line_length;
- banshee_make_room(1);
- tdfx_outl(VIDDESKSTART, addr);
+ banshee_make_room(par, 1);
+ tdfx_outl(par, VIDDESKSTART, addr);
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
@@ -870,6 +872,7 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var, int con,
*/
static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
u32 bpp = info->var.bits_per_pixel;
u32 stride = info->fix.line_length;
u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13);
@@ -880,13 +883,13 @@ static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
else
tdfx_rop = TDFX_ROP_XOR;
- banshee_make_room(5);
- tdfx_outl(DSTFORMAT, fmt);
- tdfx_outl(COLORFORE, rect->color);
- tdfx_outl(COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
- tdfx_outl(DSTSIZE, rect->width | (rect->height << 16));
- tdfx_outl(LAUNCH_2D, rect->dx | (rect->dy << 16));
- banshee_wait_idle();
+ banshee_make_room(par, 5);
+ tdfx_outl(par, DSTFORMAT, fmt);
+ tdfx_outl(par, COLORFORE, rect->color);
+ tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
+ tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
+ tdfx_outl(par, LAUNCH_2D, rect->dx | (rect->dy << 16));
+ banshee_wait_idle(info);
}
/*
@@ -894,6 +897,7 @@ static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
*/
static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
u32 bpp = info->var.bits_per_pixel;
u32 stride = info->fix.line_length;
u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
@@ -912,19 +916,20 @@ static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
area->dy += area->height - 1;
}
- banshee_make_room(6);
-
- tdfx_outl(SRCFORMAT, fmt);
- tdfx_outl(DSTFORMAT, fmt);
- tdfx_outl(COMMAND_2D, blitcmd);
- tdfx_outl(DSTSIZE, area->width | (area->height << 16));
- tdfx_outl(DSTXY, area->dx | (area->dy << 16));
- tdfx_outl(LAUNCH_2D, area->sx | (area->sy << 16));
- banshee_wait_idle();
+ banshee_make_room(par, 6);
+
+ tdfx_outl(par, SRCFORMAT, fmt);
+ tdfx_outl(par, DSTFORMAT, fmt);
+ tdfx_outl(par, COMMAND_2D, blitcmd);
+ tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
+ tdfx_outl(par, DSTXY, area->dx | (area->dy << 16));
+ tdfx_outl(par, LAUNCH_2D, area->sx | (area->sy << 16));
+ banshee_wait_idle(info);
}
static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
int size = pixmap->height*((pixmap->width*pixmap->depth + 7)>>3);
int i, stride = info->fix.line_length;
u32 bpp = info->var.bits_per_pixel;
@@ -933,25 +938,25 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
u32 srcfmt;
if (pixmap->depth == 1) {
- banshee_make_room(8 + ((size + 3) >> 2));
- tdfx_outl(COLORFORE, pixmap->fg_color);
- tdfx_outl(COLORBACK, pixmap->bg_color);
+ banshee_make_room(par, 8 + ((size + 3) >> 2));
+ tdfx_outl(par, COLORFORE, pixmap->fg_color);
+ tdfx_outl(par, COLORBACK, pixmap->bg_color);
srcfmt = 0x400000;
} else {
- banshee_make_room(6 + ((size + 3) >> 2));
- srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
+ //banshee_make_room(par, 6 + ((size + 3) >> 2));
+ //srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
}
- tdfx_outl(SRCXY, 0);
- tdfx_outl(DSTXY, pixmap->dx | (pixmap->dy << 16));
- tdfx_outl(COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
- tdfx_outl(SRCFORMAT, srcfmt);
- tdfx_outl(DSTFORMAT, dstfmt);
- tdfx_outl(DSTSIZE, pixmap->width | (pixmap->height << 16));
+ tdfx_outl(par, SRCXY, 0);
+ tdfx_outl(par, DSTXY, pixmap->dx | (pixmap->dy << 16));
+ tdfx_outl(par, COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
+ tdfx_outl(par, SRCFORMAT, srcfmt);
+ tdfx_outl(par, DSTFORMAT, dstfmt);
+ tdfx_outl(par, DSTSIZE, pixmap->width | (pixmap->height << 16));
/* Send four bytes at a time of data */
for (i = (size >> 2) ; i > 0; i--) {
- tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+ tdfx_outl(par, LAUNCH_2D,*(u32*)chardata);
chardata += 4;
}
@@ -959,11 +964,148 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
i = size%4;
switch (i) {
case 0: break;
- case 1: tdfx_outl(LAUNCH_2D,*chardata); break;
- case 2: tdfx_outl(LAUNCH_2D,*(u16*)chardata); break;
- case 3: tdfx_outl(LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
+ case 1: tdfx_outl(par, LAUNCH_2D,*chardata); break;
+ case 2: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata); break;
+ case 3: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
}
- banshee_wait_idle();
+ banshee_wait_idle(info);
+}
+
+static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ struct tdfx_par *par = (struct tdfx_par *) info->par;
+ unsigned long flags;
+
+ /*
+ * If the cursor is not be changed this means either we want the
+ * current cursor state (if enable is set) or we want to query what
+ * we can do with the cursor (if enable is not set)
+ */
+ if (!cursor->set) return 0;
+
+ /* Too large of a cursor :-( */
+ if (cursor->image.width > 64 || cursor->image.height > 64)
+ return -ENXIO;
+
+ /*
+ * If we are going to be changing things we should disable
+ * the cursor first
+ */
+ if (info->cursor.enable) {
+ spin_lock_irqsave(&par->DAClock, flags);
+ info->cursor.enable = 0;
+ del_timer(&(par->hwcursor.timer));
+ tdfx_outl(par, VIDPROCCFG, par->hwcursor.disable);
+ spin_unlock_irqrestore(&par->DAClock, flags);
+ }
+
+ /* Disable the Cursor */
+ if ((cursor->set && FB_CUR_SETCUR) && !cursor->enable)
+ return 0;
+
+ /* fix cursor color - XFree86 forgets to restore it properly */
+ if (cursor->set && FB_CUR_SETCMAP) {
+ struct fb_cmap cmap = cursor->image.cmap;
+ unsigned long bg_color, fg_color;
+
+ cmap.len = 2;/* Voodoo 3+ only support 2 color cursors*/
+ fg_color = ((cmap.red[cmap.start] << 16) |
+ (cmap.green[cmap.start] << 8) |
+ (cmap.blue[cmap.start]));
+ bg_color = ((cmap.red[cmap.start+1] << 16) |
+ (cmap.green[cmap.start+1] << 8) |
+ (cmap.blue[cmap.start+1]));
+ fb_copy_cmap(&cmap, &info->cursor.image.cmap, 0);
+ spin_lock_irqsave(&par->DAClock, flags);
+ banshee_make_room(par, 2);
+ tdfx_outl(par, HWCURC0, bg_color);
+ tdfx_outl(par, HWCURC1, fg_color);
+ spin_unlock_irqrestore(&par->DAClock, flags);
+ }
+
+ if (cursor->set && FB_CUR_SETPOS) {
+ int x, y;
+
+ x = cursor->image.dx;
+ y = cursor->image.dy;
+ y -= info->var.yoffset;
+ info->cursor.image.dx = x;
+ info->cursor.image.dy = y;
+ x += 63;
+ y += 63;
+ spin_lock_irqsave(&par->DAClock, flags);
+ banshee_make_room(par, 1);
+ tdfx_outl(par, HWCURLOC, (y << 16) + x);
+ spin_unlock_irqrestore(&par->DAClock, flags);
+ }
+
+ /* Not supported so we fake it */
+ if (cursor->set && FB_CUR_SETHOT) {
+ info->cursor.hot.x = cursor->hot.x;
+ info->cursor.hot.y = cursor->hot.y;
+ }
+
+ if (cursor->set && FB_CUR_SETSHAPE) {
+ /*
+ * Voodoo 3 and above cards use 2 monochrome cursor patterns.
+ * The reason is so the card can fetch 8 words at a time
+ * and are stored on chip for use for the next 8 scanlines.
+ * This reduces the number of times for access to draw the
+ * cursor for each screen refresh.
+ * Each pattern is a bitmap of 64 bit wide and 64 bit high
+ * (total of 8192 bits or 1024 Kbytes). The two patterns are
+ * stored in such a way that pattern 0 always resides in the
+ * lower half (least significant 64 bits) of a 128 bit word
+ * and pattern 1 the upper half. If you examine the data of
+ * the cursor image the graphics card uses then from the
+ * begining you see line one of pattern 0, line one of
+ * pattern 1, line two of pattern 0, line two of pattern 1,
+ * etc etc. The linear stride for the cursor is always 16 bytes
+ * (128 bits) which is the maximum cursor width times two for
+ * the two monochrome patterns.
+ */
+ u8 *cursorbase = (u8 *) info->cursor.image.data;
+ char *bitmap = cursor->image.data;
+ char *mask = cursor->mask;
+ int i, j, k, h = 0;
+
+ for (i = 0; i < 64; i++) {
+ if (i < cursor->image.height) {
+ j = (cursor->image.width + 7) >> 3;
+ k = 8 - j;
+
+ for (;j > 0; j--) {
+ /* Pattern 0. Copy the cursor bitmap to it */
+ fb_writeb(*bitmap, cursorbase + h);
+ bitmap++;
+ /* Pattern 1. Copy the cursor mask to it */
+ fb_writeb(*mask, cursorbase + h + 8);
+ mask++;
+ h++;
+ }
+ for (;k > 0; k--) {
+ fb_writeb(0, cursorbase + h);
+ fb_writeb(~0, cursorbase + h + 8);
+ h++;
+ }
+ } else {
+ fb_writel(0, cursorbase + h);
+ fb_writel(0, cursorbase + h + 4);
+ fb_writel(~0, cursorbase + h + 8);
+ fb_writel(~0, cursorbase + h + 12);
+ h += 16;
+ }
+ }
+ }
+ /* Turn the cursor on */
+ cursor->enable = 1;
+ info->cursor = *cursor;
+ mod_timer(&par->hwcursor.timer, jiffies+HZ/2);
+ spin_lock_irqsave(&par->DAClock, flags);
+ banshee_make_room(par, 1);
+ tdfx_outl(par, VIDPROCCFG, par->hwcursor.enable);
+ spin_unlock_irqrestore(&par->DAClock, flags);
+ return 0;
}
/**
@@ -978,6 +1120,7 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
static int __devinit tdfxfb_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
+ struct tdfx_par *default_par;
struct fb_info *info;
int size, err;
@@ -986,33 +1129,36 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
return err;
}
- info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
- sizeof(u32) * 16, GFP_KERNEL);
+ size = sizeof(struct fb_info)+sizeof(struct tdfx_par)+16*sizeof(u32);
+
+ info = kmalloc(size, GFP_KERNEL);
if (!info) return -ENOMEM;
- memset(info, 0, sizeof(info) + sizeof(struct display) + sizeof(u32) * 16);
-
+ memset(info, 0, size);
+
+ default_par = (struct tdfx_par *) (info + 1);
+
/* Configure the default fb_fix_screeninfo first */
switch (pdev->device) {
case PCI_DEVICE_ID_3DFX_BANSHEE:
strcat(tdfx_fix.id, " Banshee");
- default_par.max_pixclock = BANSHEE_MAX_PIXCLOCK;
+ default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
break;
case PCI_DEVICE_ID_3DFX_VOODOO3:
strcat(tdfx_fix.id, " Voodoo3");
- default_par.max_pixclock = VOODOO3_MAX_PIXCLOCK;
+ default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
break;
case PCI_DEVICE_ID_3DFX_VOODOO5:
strcat(tdfx_fix.id, " Voodoo5");
- default_par.max_pixclock = VOODOO5_MAX_PIXCLOCK;
+ default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
break;
}
tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
- default_par.regbase_virt = ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
- if (!default_par.regbase_virt) {
+ default_par->regbase_virt = ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+ if (!default_par->regbase_virt) {
printk("fb: Can't remap %s register area.\n", tdfx_fix.id);
goto out_err;
}
@@ -1024,7 +1170,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
}
tdfx_fix.smem_start = pci_resource_start(pdev, 1);
- if (!(tdfx_fix.smem_len = do_lfb_size(pdev->device))) {
+ if (!(tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device))) {
printk("fb: Can't count %s memory.\n", tdfx_fix.id);
release_mem_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
@@ -1050,7 +1196,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
goto out_err;
}
- default_par.iobase = pci_resource_start(pdev, 2);
+ default_par->iobase = pci_resource_start(pdev, 2);
if (!request_region(pci_resource_start(pdev, 2),
pci_resource_len(pdev, 2), "tdfx iobase")) {
@@ -1073,17 +1219,10 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
info->node = NODEV;
info->fbops = &tdfxfb_ops;
info->fix = tdfx_fix;
- info->par = &default_par;
- info->disp = (struct display *)(info + 1);
- info->pseudo_palette = (void *)(info->disp + 1);
+ info->par = default_par;
+ info->pseudo_palette = (void *)(default_par + 1);
info->flags = FBINFO_FLAG_DEFAULT;
- /* The below feilds will go away !!!! */
- strcpy(info->modename, info->fix.id);
- info->currcon = -1;
- info->switch_con = gen_switch;
- info->updatevar = gen_update_var;
-
if (!mode_option)
mode_option = "640x480@60";
@@ -1094,8 +1233,6 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
size = (info->var.bits_per_pixel == 8) ? 256 : 16;
fb_alloc_cmap(&info->cmap, size, 0);
- gen_set_var(&info->var, -1, info);
-
if (register_framebuffer(info) < 0) {
printk("tdfxfb: can't register framebuffer\n");
goto out_err;
@@ -1110,8 +1247,8 @@ out_err:
/*
* Cleanup after anything that was remapped/allocated.
*/
- if (default_par.regbase_virt)
- iounmap(default_par.regbase_virt);
+ if (default_par->regbase_virt)
+ iounmap(default_par->regbase_virt);
if (info->screen_base)
iounmap(info->screen_base);
kfree(info);
@@ -1160,8 +1297,6 @@ static void __exit tdfxfb_exit(void)
MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
MODULE_DESCRIPTION("3Dfx framebuffer device driver");
MODULE_LICENSE("GPL");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel, "Disable hardware acceleration (1 = disabled), enabled by default.");
#ifdef MODULE
module_init(tdfxfb_init);
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 3fcbcc1de024..427ce6364e7d 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -982,7 +982,7 @@ int __init tgafb_init(void)
if (register_framebuffer(&fb_info.gen.info) < 0)
return -EINVAL;
printk(KERN_INFO "fb%d: %s frame buffer device at 0x%lx\n",
- GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename,
+ minor(fb_info.gen.info.node), fb_info.gen.info.modename,
pdev->resource[0].start);
return 0;
}
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 2e53e6d53287..6ed9c651892b 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1235,7 +1235,7 @@ int __init tridentfb_init(void)
}
output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
- GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename,default_var.xres,
+ minor(fb_info.gen.info.node), fb_info.gen.info.modename,default_var.xres,
default_var.yres,default_var.bits_per_pixel);
return 0;
}
diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
index d395664206ec..bcdf2e61f240 100644
--- a/drivers/video/tx3912fb.c
+++ b/drivers/video/tx3912fb.c
@@ -21,7 +21,6 @@
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/fb.h>
-#include <video/fbcon.h>
#include <asm/io.h>
#include <asm/bootinfo.h>
#include <asm/uaccess.h>
@@ -33,7 +32,6 @@
*/
static struct fb_info fb_info;
static u32 cfb8[16];
-static struct display disp;
static struct fb_fix_screeninfo tx3912fb_fix __initdata = {
.id = "tx3912fb",
@@ -96,13 +94,11 @@ static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green,
*/
static struct fb_ops tx3912fb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = tx3912fb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -215,6 +211,7 @@ static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green,
int __init tx3912fb_init(void)
{
u_long tx3912fb_paddr = 0;
+ int size = (info->var.bits_per_pixel == 8) ? 256 : 16;
/* Disable the video logic */
outl(inl(TX3912_VIDEO_CTRL1) &
@@ -295,17 +292,11 @@ int __init tx3912fb_init(void)
if ((tx3912fb_fix.line_length * tx3912fb_var.yres_virtual) > tx3912fb_fix.smem_len)
return -ENOMEM;
- strcpy(fb_info.modename, tx3912fb_fix.id);
- fb_info.changevar = NULL;
fb_info.node = NODEV;
- fb_info.currcon = -1;
fb_info.fbops = &tx3912fb_ops;
fb_info.var = tx3912fb_var;
fb_info.fix = tx3912fb_fix;
fb_info.pseudo_palette = pseudo_palette;
- fb_info.disp = &disp;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_info.flags = FBINFO_FLAG_DEFAULT;
/* Clear the framebuffer */
@@ -313,17 +304,16 @@ int __init tx3912fb_init(void)
udelay(200);
fb_alloc_cmap(&info->cmap, size, 0);
- gen_set_disp(-1, &disp);
if (register_framebuffer(&fb_info) < 0)
return -1;
printk(KERN_INFO "fb%d: TX3912 frame buffer using %uKB.\n",
- GET_FB_IDX(fb_info.node), (u_int) (fb_info.fix.smem_len >> 10));
+ minor(fb_info.node), (u_int) (fb_info.fix.smem_len >> 10));
return 0;
}
-void __init tx3912fb_setup(char *options)
+int __init tx3912fb_setup(char *options)
{
char *this_opt;
@@ -334,6 +324,7 @@ void __init tx3912fb_setup(char *options)
if (!strncmp(options, "bpp:", 4))
tx3912fb_var.bits_per_pixel = simple_strtoul(options+4, NULL, 0);
}
+ return 0;
}
MODULE_LICENSE("GPL");
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index a6e4e367a1b2..e447ab48969d 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -127,10 +127,6 @@ struct fb_info_valkyrie {
int valkyriefb_init(void);
int valkyriefb_setup(char*);
-static int valkyrie_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int valkyrie_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
static int valkyrie_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
static int valkyrie_get_cmap(struct fb_cmap *cmap, int kspc, int con,
@@ -157,8 +153,6 @@ static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valk
static struct fb_ops valkyriefb_ops = {
.owner = THIS_MODULE,
- .fb_get_fix = valkyrie_get_fix,
- .fb_get_var = valkyrie_get_var,
.fb_set_var = valkyrie_set_var,
.fb_get_cmap = valkyrie_get_cmap,
.fb_set_cmap = gen_set_cmap,
@@ -169,24 +163,6 @@ static struct fb_ops valkyriefb_ops = {
static int valkyriefb_getcolreg(u_int regno, u_int *red, u_int *green,
u_int *blue, u_int *transp, struct fb_info *info);
-static int valkyrie_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct fb_info_valkyrie *cp = (struct fb_info_valkyrie *) info;
-
- *fix = cp->fix;
- return 0;
-}
-
-static int valkyrie_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct fb_info_valkyrie *cp = (struct fb_info_valkyrie *) info;
-
- *var = cp->var;
- return 0;
-}
-
/* Sets everything according to var */
static int valkyrie_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
@@ -705,7 +681,6 @@ static void valkyrie_par_to_fix(struct fb_par_valkyrie *par,
static void valkyrie_init_display(struct display *disp)
{
memset(disp, 0, sizeof(*disp));
- disp->type = /* fix->type */ FB_TYPE_PACKED_PIXELS;
disp->can_soft_blank = can_soft_blank;
disp->scrollmode = SCROLL_YREDRAW;
}
@@ -714,8 +689,6 @@ static void valkyrie_par_to_display(struct fb_par_valkyrie *par,
struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p)
{
disp->var = p->var;
- disp->visual = fix->visual;
- disp->line_length = fix->line_length;
if(disp->scrollmode != SCROLL_YREDRAW) {
printk(KERN_ERR "Scroll mode not YREDRAW in valkyrie_par_to_display\n");
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 1326c71bd697..1f64653ece3d 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -17,16 +17,12 @@
#include <linux/slab.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 <asm/mtrr.h>
-#include <video/fbcon.h>
-
#define dac_reg (0x3c8)
#define dac_val (0x3c9)
@@ -49,7 +45,6 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
.accel = FB_ACCEL_NONE,
};
-static struct display disp;
static struct fb_info fb_info;
static u32 pseudo_palette[17];
@@ -64,7 +59,7 @@ static void (*pmi_pal)(void);
/* --------------------------------------------------------------------- */
-static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vesafb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
int offset;
@@ -175,22 +170,18 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
static struct fb_ops vesafb_ops = {
.owner = THIS_MODULE,
- .fb_set_var = gen_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
.fb_setcolreg = vesafb_setcolreg,
.fb_pan_display = vesafb_pan_display,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
};
int __init vesafb_setup(char *options)
{
char *this_opt;
- fb_info.fontname[0] = '\0';
-
if (!options || !*options)
return 0;
@@ -211,8 +202,6 @@ int __init vesafb_setup(char *options)
pmi_setpal=1;
else if (! strcmp(this_opt, "mtrr"))
mtrr=1;
- else if (!strncmp(this_opt, "font:", 5))
- strcpy(fb_info.fontname, this_opt+5);
}
return 0;
}
@@ -351,27 +340,20 @@ int __init vesafb_init(void)
}
}
- strcpy(fb_info.modename, vesafb_fix.id);
- fb_info.changevar = NULL;
fb_info.node = NODEV;
fb_info.fbops = &vesafb_ops;
fb_info.var = vesafb_defined;
fb_info.fix = vesafb_fix;
- fb_info.currcon = -1;
- fb_info.disp = &disp;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
fb_info.pseudo_palette = pseudo_palette;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
- gen_set_disp(-1, &fb_info);
if (register_framebuffer(&fb_info)<0)
return -EINVAL;
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(fb_info.node), fb_info.fix.id);
+ minor(fb_info.node), fb_info.fix.id);
return 0;
}
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 5ed50a49b234..2963d032b054 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -24,8 +24,6 @@
#include <linux/fb.h>
#include <linux/init.h>
-#include <video/fbcon.h>
-
/*
* RAM we reserve for the frame buffer. This defines the maximum screen
* size
@@ -42,7 +40,6 @@ static const char *mode_option __initdata = NULL;
static struct fb_info fb_info;
static u32 vfb_pseudo_palette[17];
-static struct display disp;
static struct fb_var_screeninfo vfb_default __initdata = {
.xres = 640,
@@ -90,23 +87,21 @@ static int vfb_check_var(struct fb_var_screeninfo *var,
static int vfb_set_par(struct fb_info *info);
static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
-static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
static int vfb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma);
static struct fb_ops vfb_ops = {
- .fb_set_var gen_set_var,
- .fb_get_cmap gen_set_cmap,
- .fb_set_cmap gen_set_cmap,
- .fb_check_var vfb_check_var,
- .fb_set_par vfb_set_par,
- .fb_setcolreg vfb_setcolreg,
- .fb_pan_display vfb_pan_display,
- .fb_fillrect cfb_fillrect,
- .fb_copyarea cfb_copyarea,
- .fb_imageblit cfb_imageblit,
- .fb_mmap vfb_mmap,
+ .fb_check_var = vfb_check_var,
+ .fb_set_par = vfb_set_par,
+ .fb_setcolreg = vfb_setcolreg,
+ .fb_pan_display = vfb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
+ .fb_mmap = vfb_mmap,
};
/*
@@ -356,7 +351,7 @@ static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
*/
-static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
if (var->vmode & FB_VMODE_YWRAP) {
@@ -444,13 +439,6 @@ int __init vfb_init(void)
fb_info.pseudo_palette = &vfb_pseudo_palette;
fb_info.flags = FBINFO_FLAG_DEFAULT;
- strcpy(fb_info.modename, vfb_fix.id);
- fb_info.changevar = NULL;
- fb_info.currcon = -1;
- fb_info.disp = &disp;
- fb_info.switch_con = gen_switch;
- fb_info.updatevar = gen_update_var;
-
fb_alloc_cmap(&fb_info.cmap, 256, 0);
if (register_framebuffer(&fb_info) < 0) {
@@ -460,7 +448,7 @@ int __init vfb_init(void)
printk(KERN_INFO
"fb%d: Virtual frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.node), videomemorysize >> 10);
+ minor(fb_info.node), videomemorysize >> 10);
return 0;
}
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index a80ecae5e07f..7a38893b34b0 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -7,7 +7,8 @@
*
* 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. */
+ * archive for more details.
+ */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -18,35 +19,41 @@
#include <linux/slab.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 <linux/interrupt.h>
#include <asm/io.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-vga-planes.h>
#include "vga.h"
-#define dac_reg (0x3c8)
-#define dac_val (0x3c9)
+#define GRAPHICS_ADDR_REG VGA_GFX_I /* Graphics address register. */
+#define GRAPHICS_DATA_REG VGA_GFX_D /* Graphics data register. */
+
+#define SET_RESET_INDEX VGA_GFX_SR_VALUE /* Set/Reset Register index. */
+#define ENABLE_SET_RESET_INDEX VGA_GFX_SR_ENABLE /* Enable Set/Reset Register index. */
+#define DATA_ROTATE_INDEX VGA_GFX_DATA_ROTATE /* Data Rotate Register index. */
+#define GRAPHICS_MODE_INDEX VGA_GFX_MODE /* Graphics Mode Register index. */
+#define BIT_MASK_INDEX VGA_GFX_BIT_MASK /* Bit Mask Register index. */
+
+#define dac_reg (VGA_PEL_IW)
+#define dac_val (VGA_PEL_D)
#define VGA_FB_PHYS 0xA0000
#define VGA_FB_PHYS_LEN 65536
+#define MODE_SKIP4 1
+#define MODE_8BPP 2
+#define MODE_CFB 4
+#define MODE_TEXT 8
+
/* --------------------------------------------------------------------- */
/*
* card parameters
*/
-static struct vga16fb_info {
- struct fb_info fb_info;
- char *video_vbase; /* 0xa0000 map address */
- int isVGA;
-
+static struct fb_info vga16fb;
+
+static struct vga16fb_par {
/* structure holding original VGA register settings when the
screen is blanked */
struct {
@@ -63,109 +70,200 @@ static struct vga16fb_info {
unsigned char ModeControl; /* CRT-Controller:17h */
unsigned char ClockingMode; /* Seq-Controller:01h */
} vga_state;
-
- int palette_blanked;
- int vesa_blanked;
-} vga16fb;
-
-
-struct vga16fb_par {
+ struct fb_vgastate state;
+ atomic_t ref_count;
+ int palette_blanked, vesa_blanked, mode, isVGA;
+ u8 misc, pel_msk, vss, clkdiv;
u8 crtc[VGA_CRT_C];
- u8 atc[VGA_ATT_C];
- u8 gdc[VGA_GFX_C];
- u8 seq[VGA_SEQ_C];
- u8 misc;
- u8 vss;
- struct fb_var_screeninfo var;
-};
+} vga16_par;
/* --------------------------------------------------------------------- */
static struct fb_var_screeninfo vga16fb_defined = {
- .xres = 640,
- .yres = 480,
- .xres_virtual = 640,
- .yres_virtual = 480,
- .bits_per_pixel = 4,
- .activate = FB_ACTIVATE_NOW,
- .height = -1,
- .width = -1,
- .pixclock = 39721,
- .left_margin = 48,
- .right_margin = 16,
- .upper_margin = 39,
- .lower_margin = 8,
- .hsync_len = 96,
- .vsync_len = 2,
- .vmode = FB_VMODE_NONINTERLACED,
+ .xres = 640,
+ .yres = 480,
+ .xres_virtual = 640,
+ .yres_virtual = 480,
+ .bits_per_pixel = 4,
+ .activate = FB_ACTIVATE_TEST,
+ .height = -1,
+ .width = -1,
+ .pixclock = 39721,
+ .left_margin = 48,
+ .right_margin = 16,
+ .upper_margin = 39,
+ .lower_margin = 8,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .vmode = FB_VMODE_NONINTERLACED,
};
+/* name should not depend on EGA/VGA */
static struct fb_fix_screeninfo vga16fb_fix __initdata = {
- .id = "VGA16 VGA",
- .smem_start = VGA_FB_PHYS,
- .smem_len = VGA_FB_PHYS_LEN,
- .type = FB_TYPE_VGA_PLANES,
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .xpanstep = 8,
- .ypanstep = 1,
- .line_length = 640 / 8,
+ .id = "VGA16 VGA",
+ .smem_start = VGA_FB_PHYS,
+ .smem_len = VGA_FB_PHYS_LEN,
+ .type = FB_TYPE_VGA_PLANES,
+ .type_aux = FB_AUX_VGA_PLANES_VGA4,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 8,
+ .ypanstep = 1,
+ .line_length = 640/8,
+ .accel = FB_ACCEL_NONE
};
-static struct display disp;
-static struct { u_short blue, green, red, pad; } palette[256];
+/* The VGA's weird architecture often requires that we read a byte and
+ write a byte to the same location. It doesn't matter *what* byte
+ we write, however. This is because all the action goes on behind
+ the scenes in the VGA's 32-bit latch register, and reading and writing
+ video memory just invokes latch behavior.
+
+ To avoid race conditions (is this necessary?), reading and writing
+ the memory byte should be done with a single instruction. One
+ suitable instruction is the x86 bitwise OR. The following
+ read-modify-write routine should optimize to one such bitwise
+ OR. */
+static inline void rmw(volatile char *p)
+{
+ readb(p);
+ writeb(1, p);
+}
-/* --------------------------------------------------------------------- */
+/* Set the Graphics Mode Register, and return its previous value.
+ Bits 0-1 are write mode, bit 3 is read mode. */
+static inline int setmode(int mode)
+{
+ int oldmode;
+
+ vga_io_w(GRAPHICS_ADDR_REG, GRAPHICS_MODE_INDEX);
+ oldmode = vga_io_r(GRAPHICS_DATA_REG);
+ vga_io_w(GRAPHICS_DATA_REG, mode);
+ return oldmode;
+}
-static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var)
-{
- u32 pos = (var->xres_virtual * var->yoffset + var->xoffset) >> 3;
- outb(VGA_CRTC_START_HI, VGA_CRT_IC);
- outb(pos >> 8, VGA_CRT_DC);
- outb(VGA_CRTC_START_LO, VGA_CRT_IC);
- outb(pos & 0xFF, VGA_CRT_DC);
-#if 0
- /* if someone supports xoffset in bit resolution */
- inb(VGA_IS1_RC); /* reset flip-flop */
- outb(VGA_ATC_PEL, VGA_ATT_IW);
- outb(xoffset & 7, VGA_ATT_IW);
- inb(VGA_IS1_RC);
- outb(0x20, VGA_ATT_IW);
-#endif
+/* Select the Bit Mask Register and return its value. */
+static inline int selectmask(void)
+{
+ return vga_io_rgfx(BIT_MASK_INDEX);
}
-static void vga16fb_set_disp(int con, struct vga16fb_info *info)
+/* Set the value of the Bit Mask Register. It must already have been
+ selected with selectmask(). */
+static inline void setmask(int mask)
{
- struct display *display = (con < 0) ? info->fb_info.disp : (fb_display + con);
+ vga_io_w(GRAPHICS_DATA_REG, mask);
+}
- display->can_soft_blank = 1;
- display->dispsw_data = NULL;
- display->var = info->fb_info.var;
- display->inverse = 0;
+/* Set the Data Rotate Register and return its old value.
+ Bits 0-2 are rotate count, bits 3-4 are logical operation
+ (0=NOP, 1=AND, 2=OR, 3=XOR). */
+static inline int setop(int op)
+{
+ int oldop;
+
+ vga_io_w(GRAPHICS_ADDR_REG, DATA_ROTATE_INDEX);
+ oldop = vga_io_r(GRAPHICS_DATA_REG);
+ vga_io_w(GRAPHICS_DATA_REG, op);
+ return oldop;
+}
+
+/* Set the Enable Set/Reset Register and return its old value.
+ The code here always uses value 0xf for thsi register. */
+static inline int setsr(int sr)
+{
+ int oldsr;
+
+ vga_io_w(GRAPHICS_ADDR_REG, ENABLE_SET_RESET_INDEX);
+ oldsr = vga_io_r(GRAPHICS_DATA_REG);
+ vga_io_w(GRAPHICS_DATA_REG, sr);
+ return oldsr;
+}
- /*
- * If we are setting all the virtual consoles, also set
- * the defaults used to create new consoles.
- */
- if (con < 0 || info->fb_info.var.activate & FB_ACTIVATE_ALL)
- info->fb_info.disp->var = info->fb_info.var;
+/* Set the Set/Reset Register and return its old value. */
+static inline int setcolor(int color)
+{
+ int oldcolor;
+
+ vga_io_w(GRAPHICS_ADDR_REG, SET_RESET_INDEX);
+ oldcolor = vga_io_r(GRAPHICS_DATA_REG);
+ vga_io_w(GRAPHICS_DATA_REG, color);
+ return oldcolor;
+}
+
+/* Return the value in the Graphics Address Register. */
+static inline int getindex(void)
+{
+ return vga_io_r(GRAPHICS_ADDR_REG);
+}
- if (info->isVGA)
- display->dispsw = &fbcon_vga_planes;
+/* Set the value in the Graphics Address Register. */
+static inline void setindex(int index)
+{
+ vga_io_w(GRAPHICS_ADDR_REG, index);
+}
+
+static void vga16fb_pan_var(struct fb_info *info,
+ struct fb_var_screeninfo *var)
+{
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ u32 xoffset, pos;
+
+ xoffset = var->xoffset;
+ if (info->var.bits_per_pixel == 8) {
+ pos = (info->var.xres_virtual * var->yoffset + xoffset) >> 2;
+ } else if (par->mode & MODE_TEXT) {
+ int fh = 16; // FIXME !!! font height. Fugde for now.
+ pos = (info->var.xres_virtual * (var->yoffset / fh) + xoffset) >> 3;
+ } else {
+ if (info->var.nonstd)
+ xoffset--;
+ pos = (info->var.xres_virtual * var->yoffset + xoffset) >> 3;
+ }
+ vga_io_wcrt(VGA_CRTC_START_HI, pos >> 8);
+ vga_io_wcrt(VGA_CRTC_START_LO, pos & 0xFF);
+ /* if we support CFB4, then we must! support xoffset with pixel
+ * granularity if someone supports xoffset in bit resolution */
+ vga_io_r(VGA_IS1_RC); /* reset flip-flop */
+ vga_io_w(VGA_ATT_IW, VGA_ATC_PEL);
+ if (var->bits_per_pixel == 8)
+ vga_io_w(VGA_ATT_IW, (xoffset & 3) << 1);
else
- display->dispsw = &fbcon_ega_planes;
- display->scrollmode = SCROLL_YREDRAW;
+ vga_io_w(VGA_ATT_IW, xoffset & 7);
+ vga_io_r(VGA_IS1_RC);
+ vga_io_w(VGA_ATT_IW, 0x20);
}
-static void vga16fb_encode_var(struct fb_var_screeninfo *var,
- const struct vga16fb_par *par,
- const struct vga16fb_info *info)
+static void vga16fb_update_fix(struct fb_info *info)
{
- *var = par->var;
+ if (info->var.bits_per_pixel == 4) {
+ if (info->var.nonstd) {
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.line_length = info->var.xres_virtual / 2;
+ } else {
+ info->fix.type = FB_TYPE_VGA_PLANES;
+ info->fix.type_aux = FB_AUX_VGA_PLANES_VGA4;
+ info->fix.line_length = info->var.xres_virtual / 8;
+ }
+ } else if (info->var.bits_per_pixel == 0) {
+ info->fix.type = FB_TYPE_TEXT;
+ info->fix.type_aux = FB_AUX_TEXT_CGA;
+ info->fix.line_length = info->var.xres_virtual / 4;
+ } else { /* 8bpp */
+ if (info->var.nonstd) {
+ info->fix.type = FB_TYPE_VGA_PLANES;
+ info->fix.type_aux = FB_AUX_VGA_PLANES_CFB8;
+ info->fix.line_length = info->var.xres_virtual / 4;
+ } else {
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.line_length = info->var.xres_virtual;
+ }
+ }
}
static void vga16fb_clock_chip(struct vga16fb_par *par,
unsigned int pixclock,
- const struct vga16fb_info *info)
+ const struct fb_info *info,
+ int mul, int div)
{
static struct {
u32 pixclock;
@@ -179,6 +277,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
{ 0 /* bad */, 0x00, 0x00}};
int err;
+ pixclock = (pixclock * mul) / div;
best = vgaclocks;
err = pixclock - best->pixclock;
if (err < 0) err = -err;
@@ -193,25 +292,98 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
}
}
par->misc |= best->misc;
- par->seq[VGA_SEQ_CLOCK_MODE] |= best->seq_clock_mode;
- par->var.pixclock = best->pixclock;
+ par->clkdiv = best->seq_clock_mode;
+ pixclock = (best->pixclock * div) / mul;
}
#define FAIL(X) return -EINVAL
-static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
- struct vga16fb_par *par,
- const struct vga16fb_info *info)
+static int vga16fb_open(struct fb_info *info, int user)
+{
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ int cnt = atomic_read(&par->ref_count);
+
+ if (!cnt) {
+ memset(&par->state, 0, sizeof(struct fb_vgastate));
+ par->state.flags = 8;
+ fb_save_vga(&par->state);
+ }
+ atomic_inc(&par->ref_count);
+ return 0;
+}
+
+static int vga16fb_release(struct fb_info *info, int user)
+{
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ int cnt = atomic_read(&par->ref_count);
+
+ if (!cnt)
+ return -EINVAL;
+ if (cnt == 1)
+ fb_restore_vga(&par->state);
+ atomic_dec(&par->ref_count);
+
+ return 0;
+}
+
+static int vga16fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
+#ifdef FBCON_HAS_VGA
+ struct display *p = (info->currcon < 0) ? info->disp : (fb_display + info->currcon);
+#endif
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
u32 xres, right, hslen, left, xtotal;
u32 yres, lower, vslen, upper, ytotal;
u32 vxres, xoffset, vyres, yoffset;
u32 pos;
u8 r7, rMode;
- int i;
-
- if (var->bits_per_pixel != 4)
+ int shift;
+ int mode;
+ u32 maxmem;
+
+ par->pel_msk = 0xFF;
+
+ if (var->bits_per_pixel == 4) {
+ if (var->nonstd) {
+ if (!par->isVGA)
+ return -EINVAL;
+ shift = 3;
+ mode = MODE_SKIP4 | MODE_CFB;
+ maxmem = 16384;
+ par->pel_msk = 0x0F;
+ } else {
+ shift = 3;
+ mode = 0;
+ maxmem = 65536;
+ }
+ } else if (var->bits_per_pixel == 8) {
+ if (!par->isVGA)
+ return -EINVAL; /* no support on EGA */
+ shift = 2;
+ if (var->nonstd) {
+ mode = MODE_8BPP | MODE_CFB;
+ maxmem = 65536;
+ } else {
+ mode = MODE_SKIP4 | MODE_8BPP | MODE_CFB;
+ maxmem = 16384;
+ }
+ }
+#ifdef FBCON_HAS_VGA
+ else if (var->bits_per_pixel == 0) {
+ int fh;
+
+ shift = 3;
+ mode = MODE_TEXT;
+ fh = fontheight(p);
+ if (!fh)
+ fh = 16;
+ maxmem = 32768 * fh;
+ }
+#endif
+ else
return -EINVAL;
+
xres = (var->xres + 7) & ~7;
vxres = (var->xres_virtual + 0xF) & ~0xF;
xoffset = (var->xoffset + 7) & ~7;
@@ -224,18 +396,18 @@ static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
if (xres + xoffset > vxres)
xoffset = vxres - xres;
- par->var.xres = xres;
- par->var.right_margin = right;
- par->var.hsync_len = hslen;
- par->var.left_margin = left;
- par->var.xres_virtual = vxres;
- par->var.xoffset = xoffset;
-
- xres >>= 3;
- right >>= 3;
- hslen >>= 3;
- left >>= 3;
- vxres >>= 3;
+ var->xres = xres;
+ var->right_margin = right;
+ var->hsync_len = hslen;
+ var->left_margin = left;
+ var->xres_virtual = vxres;
+ var->xoffset = xoffset;
+
+ xres >>= shift;
+ right >>= shift;
+ hslen >>= shift;
+ left >>= shift;
+ vxres >>= shift;
xtotal = xres + right + hslen + left;
if (xtotal >= 256)
FAIL("xtotal too big");
@@ -264,19 +436,19 @@ static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
if (yres > vyres)
vyres = yres;
- if (vxres * vyres > 65536) {
- vyres = 65536 / vxres;
+ if (vxres * vyres > maxmem) {
+ vyres = maxmem / vxres;
if (vyres < yres)
return -ENOMEM;
}
if (yoffset + yres > vyres)
yoffset = vyres - yres;
- par->var.yres = yres;
- par->var.lower_margin = lower;
- par->var.vsync_len = vslen;
- par->var.upper_margin = upper;
- par->var.yres_virtual = vyres;
- par->var.yoffset = yoffset;
+ var->yres = yres;
+ var->lower_margin = lower;
+ var->vsync_len = vslen;
+ var->upper_margin = upper;
+ var->yres_virtual = vyres;
+ var->yoffset = yoffset;
if (var->vmode & FB_VMODE_DOUBLE) {
yres <<= 1;
@@ -304,12 +476,13 @@ static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
if (ytotal & 0x200) r7 |= 0x20;
par->crtc[VGA_CRTC_PRESET_ROW] = 0;
par->crtc[VGA_CRTC_MAX_SCAN] = 0x40; /* 1 scanline, no linecmp */
- par->var.vmode = var->vmode;
if (var->vmode & FB_VMODE_DOUBLE)
par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
par->crtc[VGA_CRTC_CURSOR_START] = 0x20;
par->crtc[VGA_CRTC_CURSOR_END] = 0x00;
- pos = yoffset * vxres + (xoffset >> 3);
+ if ((mode & (MODE_CFB | MODE_8BPP)) == MODE_CFB)
+ xoffset--;
+ pos = yoffset * vxres + (xoffset >> shift);
par->crtc[VGA_CRTC_START_HI] = pos >> 8;
par->crtc[VGA_CRTC_START_LO] = pos & 0xFF;
par->crtc[VGA_CRTC_CURSOR_HI] = 0x00;
@@ -337,166 +510,199 @@ static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
if (vxres >= 512)
FAIL("vxres too long");
par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
- par->crtc[VGA_CRTC_UNDERLINE] = 0x1F;
- par->crtc[VGA_CRTC_MODE] = rMode | 0xE3;
+ if (mode & MODE_SKIP4)
+ par->crtc[VGA_CRTC_UNDERLINE] = 0x5F; /* 256, cfb8 */
+ else
+ par->crtc[VGA_CRTC_UNDERLINE] = 0x1F; /* 16, vgap */
+ par->crtc[VGA_CRTC_MODE] = rMode | ((mode & MODE_TEXT) ? 0xA3 : 0xE3);
par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
par->crtc[VGA_CRTC_OVERFLOW] = r7;
par->vss = 0x00; /* 3DA */
- for (i = 0x00; i < 0x10; i++)
- par->atc[i] = i;
- par->atc[VGA_ATC_MODE] = 0x81;
- par->atc[VGA_ATC_OVERSCAN] = 0x00; /* 0 for EGA, 0xFF for VGA */
- par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
- par->atc[VGA_ATC_PEL] = xoffset & 7;
- par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
-
- par->misc = 0xC3; /* enable CPU, ports 0x3Dx, positive sync */
- par->var.sync = var->sync;
+ par->misc = 0xE3; /* enable CPU, ports 0x3Dx, positive sync */
if (var->sync & FB_SYNC_HOR_HIGH_ACT)
par->misc &= ~0x40;
if (var->sync & FB_SYNC_VERT_HIGH_ACT)
par->misc &= ~0x80;
- par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
- par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
- par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
- par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
-
- par->gdc[VGA_GFX_SR_VALUE] = 0x00;
- par->gdc[VGA_GFX_SR_ENABLE] = 0x0F;
- par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
- par->gdc[VGA_GFX_DATA_ROTATE] = 0x20;
- par->gdc[VGA_GFX_PLANE_READ] = 0;
- par->gdc[VGA_GFX_MODE] = 0x00;
- par->gdc[VGA_GFX_MISC] = 0x05;
- par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
- par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
-
- vga16fb_clock_chip(par, var->pixclock, info);
-
- par->var.bits_per_pixel = 4;
- par->var.grayscale = var->grayscale;
- par->var.red.offset = par->var.green.offset = par->var.blue.offset =
- par->var.transp.offset = 0;
- par->var.red.length = par->var.green.length = par->var.blue.length =
- (info->isVGA) ? 6 : 2;
- par->var.transp.length = 0;
- par->var.nonstd = 0;
- par->var.activate = FB_ACTIVATE_NOW;
- par->var.height = -1;
- par->var.width = -1;
- par->var.accel_flags = 0;
+ par->mode = mode;
+
+ if (mode & MODE_8BPP)
+ /* pixel clock == vga clock / 2 */
+ vga16fb_clock_chip(par, var->pixclock, info, 1, 2);
+ else
+ /* pixel clock == vga clock */
+ vga16fb_clock_chip(par, var->pixclock, info, 1, 1);
+ var->red.offset = var->green.offset = var->blue.offset =
+ var->transp.offset = 0;
+ var->red.length = var->green.length = var->blue.length =
+ (par->isVGA) ? 6 : 2;
+ var->transp.length = 0;
+ var->activate = FB_ACTIVATE_NOW;
+ var->height = -1;
+ var->width = -1;
+ var->accel_flags = 0;
return 0;
}
#undef FAIL
-static int vga16fb_set_par(const struct vga16fb_par *par,
- struct vga16fb_info *info)
+#ifdef FBCON_HAS_VGA
+static void vga16fb_load_font(struct display* p)
{
- int i;
+ int chars;
+ unsigned char* font;
+ unsigned char* dest;
+ int chars;
+
+ if (!p || !p->fontdata)
+ return;
+ chars = 256;
+ font = p->fontdata;
+ dest = vga16fb.screen_base;
+
+ vga_io_wseq(0x00, 0x01);
+ vga_io_wseq(VGA_SEQ_PLANE_WRITE, 0x04);
+ vga_io_wseq(VGA_SEQ_MEMORY_MODE, 0x07);
+ vga_io_wseq(0x00, 0x03);
+ vga_io_wgfx(VGA_GFX_MODE, 0x00);
+ vga_io_wgfx(VGA_GFX_MISC, 0x04);
+ while (chars--) {
+ int i;
+
+ for (i = fontheight(p); i > 0; i--)
+ writeb(*font++, dest++);
+ dest += 32 - fontheight(p);
+ }
+ vga_io_wseq(0x00, 0x01);
+ vga_io_wseq(VGA_SEQ_PLANE_WRITE, 0x03);
+ vga_io_wseq(VGA_SEQ_MEMORY_MODE, 0x03);
+ vga_io_wseq(0x00, 0x03);
+ vga_io_wgfx(VGA_GFX_MODE, 0x10);
+ vga_io_wgfx(VGA_GFX_MISC, 0x06);
+}
+#endif
- outb(inb(VGA_MIS_R) | 0x01, VGA_MIS_W);
+static int vga16fb_set_par(struct fb_info *info)
+{
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ u8 gdc[VGA_GFX_C];
+ u8 seq[VGA_SEQ_C];
+ u8 atc[VGA_ATT_C];
+ int fh, i;
+
+ seq[VGA_SEQ_CLOCK_MODE] = 0x01 | par->clkdiv;
+ if (par->mode & MODE_TEXT)
+ seq[VGA_SEQ_PLANE_WRITE] = 0x03;
+ else
+ seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+ seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+ if (par->mode & MODE_TEXT)
+ seq[VGA_SEQ_MEMORY_MODE] = 0x03;
+ else if (par->mode & MODE_SKIP4)
+ seq[VGA_SEQ_MEMORY_MODE] = 0x0E;
+ else
+ seq[VGA_SEQ_MEMORY_MODE] = 0x06;
+
+ gdc[VGA_GFX_SR_VALUE] = 0x00;
+ gdc[VGA_GFX_SR_ENABLE] = 0x00;
+ gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+ gdc[VGA_GFX_DATA_ROTATE] = 0x00;
+ gdc[VGA_GFX_PLANE_READ] = 0;
+ if (par->mode & MODE_TEXT) {
+ gdc[VGA_GFX_MODE] = 0x10;
+ gdc[VGA_GFX_MISC] = 0x06;
+ } else {
+ if (par->mode & MODE_CFB)
+ gdc[VGA_GFX_MODE] = 0x40;
+ else
+ gdc[VGA_GFX_MODE] = 0x00;
+ gdc[VGA_GFX_MISC] = 0x05;
+ }
+ gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+ gdc[VGA_GFX_BIT_MASK] = 0xFF;
+
+ for (i = 0x00; i < 0x10; i++)
+ atc[i] = i;
+ if (par->mode & MODE_TEXT)
+ atc[VGA_ATC_MODE] = 0x04;
+ else if (par->mode & MODE_8BPP)
+ atc[VGA_ATC_MODE] = 0x41;
+ else
+ atc[VGA_ATC_MODE] = 0x81;
+ atc[VGA_ATC_OVERSCAN] = 0x00; /* 0 for EGA, 0xFF for VGA */
+ atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+ if (par->mode & MODE_8BPP)
+ atc[VGA_ATC_PEL] = (info->var.xoffset & 3) << 1;
+ else
+ atc[VGA_ATC_PEL] = info->var.xoffset & 7;
+ atc[VGA_ATC_COLOR_PAGE] = 0x00;
+
+ if (par->mode & MODE_TEXT) {
+ fh = 16; // FIXME !!! Fudge font height.
+ par->crtc[VGA_CRTC_MAX_SCAN] = (par->crtc[VGA_CRTC_MAX_SCAN]
+ & ~0x1F) | (fh - 1);
+ }
+
+ vga_io_w(VGA_MIS_W, vga_io_r(VGA_MIS_R) | 0x01);
/* Enable graphics register modification */
- if (!info->isVGA) {
- outb(0x00, EGA_GFX_E0);
- outb(0x01, EGA_GFX_E1);
+ if (!par->isVGA) {
+ vga_io_w(EGA_GFX_E0, 0x00);
+ vga_io_w(EGA_GFX_E1, 0x01);
}
/* update misc output register */
- outb(par->misc, VGA_MIS_W);
+ vga_io_w(VGA_MIS_W, par->misc);
/* synchronous reset on */
- outb(0x00, VGA_SEQ_I);
- outb(0x01, VGA_SEQ_D);
-
+ vga_io_wseq(0x00, 0x01);
+
+ if (par->isVGA)
+ vga_io_w(VGA_PEL_MSK, par->pel_msk);
+
/* write sequencer registers */
- outb(1, VGA_SEQ_I);
- outb(par->seq[1] | 0x20, VGA_SEQ_D);
+ vga_io_wseq(VGA_SEQ_CLOCK_MODE, seq[VGA_SEQ_CLOCK_MODE] | 0x20);
for (i = 2; i < VGA_SEQ_C; i++) {
- outb(i, VGA_SEQ_I);
- outb(par->seq[i], VGA_SEQ_D);
+ vga_io_wseq(i, seq[i]);
}
/* synchronous reset off */
- outb(0x00, VGA_SEQ_I);
- outb(0x03, VGA_SEQ_D);
-
+ vga_io_wseq(0x00, 0x03);
+
/* deprotect CRT registers 0-7 */
- outb(0x11, VGA_CRT_IC);
- outb(par->crtc[0x11], VGA_CRT_DC);
+ vga_io_wcrt(VGA_CRTC_V_SYNC_END, par->crtc[VGA_CRTC_V_SYNC_END]);
/* write CRT registers */
- for (i = 0; i < VGA_CRT_C; i++) {
- outb(i, VGA_CRT_IC);
- outb(par->crtc[i], VGA_CRT_DC);
+ for (i = 0; i < VGA_CRTC_REGS; i++) {
+ vga_io_wcrt(i, par->crtc[i]);
}
/* write graphics controller registers */
for (i = 0; i < VGA_GFX_C; i++) {
- outb(i, VGA_GFX_I);
- outb(par->gdc[i], VGA_GFX_D);
+ vga_io_wgfx(i, gdc[i]);
}
/* write attribute controller registers */
for (i = 0; i < VGA_ATT_C; i++) {
- inb_p(VGA_IS1_RC); /* reset flip-flop */
- outb_p(i, VGA_ATT_IW);
- outb_p(par->atc[i], VGA_ATT_IW);
+ vga_io_r(VGA_IS1_RC); /* reset flip-flop */
+ vga_io_wattr(i, atc[i]);
}
+#ifdef FBCON_HAS_VGA
+ if (par->mode & MODE_TEXT)
+ vga16fb_load_font(p);
+#endif
/* Wait for screen to stabilize. */
mdelay(50);
- outb(0x01, VGA_SEQ_I);
- outb(par->seq[1], VGA_SEQ_D);
-
- inb(VGA_IS1_RC);
- outb(0x20, VGA_ATT_IW);
-
- return 0;
-}
-
-static int vga16fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb)
-{
- struct vga16fb_info *info = (struct vga16fb_info*)fb;
- struct vga16fb_par par;
- struct display *display = (con < 0) ? fb->disp : (fb_display + con);
- int err;
-
- if ((err = vga16fb_decode_var(var, &par, info)) != 0)
- return err;
- vga16fb_encode_var(var, &par, info);
-
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
- return 0;
-
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
- u32 oldxres, oldyres, oldvxres, oldvyres, oldbpp;
-
- oldxres = display->var.xres;
- oldyres = display->var.yres;
- oldvxres = display->var.xres_virtual;
- oldvyres = display->var.yres_virtual;
- oldbpp = display->var.bits_per_pixel;
+ vga_io_wseq(VGA_SEQ_CLOCK_MODE, seq[VGA_SEQ_CLOCK_MODE]);
- display->var = *var;
-
- if (oldxres != var->xres || oldyres != var->yres ||
- oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel) {
- vga16fb_set_disp(con, info);
- if (info->fb_info.changevar)
- info->fb_info.changevar(con);
- }
- if (con == info->fb_info.currcon)
- vga16fb_set_par(&par, info);
- }
+ vga_io_r(VGA_IS1_RC);
+ vga_io_w(VGA_ATT_IW, 0x20);
+ vga16fb_update_fix(info);
return 0;
}
@@ -505,12 +711,13 @@ static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned b
static unsigned char map[] = { 000, 001, 010, 011 };
int val;
+ if (regno >= 16)
+ return;
val = map[red>>14] | ((map[green>>14]) << 1) | ((map[blue>>14]) << 2);
- inb_p(0x3DA); /* ! 0x3BA */
- outb_p(regno, 0x3C0);
- outb_p(val, 0x3C0);
- inb_p(0x3DA); /* some clones need it */
- outb_p(0x20, 0x3C0); /* unblank screen */
+ vga_io_r(VGA_IS1_RC); /* ! 0x3BA */
+ vga_io_wattr(regno, val);
+ vga_io_r(VGA_IS1_RC); /* some clones need it */
+ vga_io_w(VGA_ATT_IW, 0x20); /* unblank screen */
}
static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
@@ -523,8 +730,9 @@ static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned b
static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
- struct fb_info *fb_info)
+ struct fb_info *info)
{
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
int gray;
/*
@@ -534,40 +742,34 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
* != 0 for invalid regno.
*/
- if (regno >= 16)
+ if (regno >= 256)
return 1;
- palette[regno].red = red;
- palette[regno].green = green;
- palette[regno].blue = blue;
+ gray = info->var.grayscale;
- if (fb_info->currcon < 0)
- gray = disp.var.grayscale;
- else
- gray = fb_display[fb_info->currcon].var.grayscale;
if (gray) {
/* gray = 0.30*R + 0.59*G + 0.11*B */
red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
}
- if (((struct vga16fb_info *) fb_info)->isVGA)
+ if (par->isVGA)
vga16_setpalette(regno,red,green,blue);
else
ega16_setpalette(regno,red,green,blue);
-
return 0;
}
-static int vga16fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vga16fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
- var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+ if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+ var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
- if (con == info->currcon)
- vga16fb_pan_var(info, var);
- fb_display[con].var.xoffset = var->xoffset;
- fb_display[con].var.yoffset = var->yoffset;
- fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+
+ vga16fb_pan_var(info, var);
+
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
+ info->var.vmode &= ~FB_VMODE_YWRAP;
return 0;
}
@@ -575,59 +777,49 @@ static int vga16fb_pan_display(struct fb_var_screeninfo *var, int con,
blanking code was originally by Huang shi chao, and modified by
Christoph Rimek (chrimek@toppoint.de) and todd j. derr
(tjd@barefoot.org) for Linux. */
-#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
-#define vga_video_port_reg 0x3d4
-#define vga_video_port_val 0x3d5
-
-static void vga_vesa_blank(struct vga16fb_info *info, int mode)
+#define attrib_port VGA_ATC_IW
+#define seq_port_reg VGA_SEQ_I
+#define seq_port_val VGA_SEQ_D
+#define gr_port_reg VGA_GFX_I
+#define gr_port_val VGA_GFX_D
+#define video_misc_rd VGA_MIS_R
+#define video_misc_wr VGA_MIS_W
+#define vga_video_port_reg VGA_CRT_IC
+#define vga_video_port_val VGA_CRT_DC
+
+static void vga_vesa_blank(struct vga16fb_par *par, int mode)
{
unsigned char SeqCtrlIndex;
unsigned char CrtCtrlIndex;
- cli();
- SeqCtrlIndex = inb_p(seq_port_reg);
- CrtCtrlIndex = inb_p(vga_video_port_reg);
+ //cli();
+ SeqCtrlIndex = vga_io_r(seq_port_reg);
+ CrtCtrlIndex = vga_io_r(vga_video_port_reg);
/* save original values of VGA controller registers */
- if(!info->vesa_blanked) {
- info->vga_state.CrtMiscIO = inb_p(video_misc_rd);
- sti();
-
- outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
- info->vga_state.HorizontalTotal = inb_p(vga_video_port_val);
- outb_p(0x01,vga_video_port_reg); /* HorizDisplayEnd */
- info->vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
- outb_p(0x04,vga_video_port_reg); /* StartHorizRetrace */
- info->vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
- outb_p(0x05,vga_video_port_reg); /* EndHorizRetrace */
- info->vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
- outb_p(0x07,vga_video_port_reg); /* Overflow */
- info->vga_state.Overflow = inb_p(vga_video_port_val);
- outb_p(0x10,vga_video_port_reg); /* StartVertRetrace */
- info->vga_state.StartVertRetrace = inb_p(vga_video_port_val);
- outb_p(0x11,vga_video_port_reg); /* EndVertRetrace */
- info->vga_state.EndVertRetrace = inb_p(vga_video_port_val);
- outb_p(0x17,vga_video_port_reg); /* ModeControl */
- info->vga_state.ModeControl = inb_p(vga_video_port_val);
- outb_p(0x01,seq_port_reg); /* ClockingMode */
- info->vga_state.ClockingMode = inb_p(seq_port_val);
+ if(!par->vesa_blanked) {
+ par->vga_state.CrtMiscIO = vga_io_r(video_misc_rd);
+ //sti();
+
+ par->vga_state.HorizontalTotal = vga_io_rcrt(0x00); /* HorizontalTotal */
+ par->vga_state.HorizDisplayEnd = vga_io_rcrt(0x01); /* HorizDisplayEnd */
+ par->vga_state.StartHorizRetrace = vga_io_rcrt(0x04); /* StartHorizRetrace */
+ par->vga_state.EndHorizRetrace = vga_io_rcrt(0x05); /* EndHorizRetrace */
+ par->vga_state.Overflow = vga_io_rcrt(0x07); /* Overflow */
+ par->vga_state.StartVertRetrace = vga_io_rcrt(0x10); /* StartVertRetrace */
+ par->vga_state.EndVertRetrace = vga_io_rcrt(0x11); /* EndVertRetrace */
+ par->vga_state.ModeControl = vga_io_rcrt(0x17); /* ModeControl */
+ par->vga_state.ClockingMode = vga_io_rseq(0x01); /* ClockingMode */
}
/* assure that video is enabled */
/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
- cli();
- outb_p(0x01,seq_port_reg);
- outb_p(info->vga_state.ClockingMode | 0x20,seq_port_val);
+ //cli();
+ vga_io_wseq(0x01, par->vga_state.ClockingMode | 0x20);
/* test for vertical retrace in process.... */
- if ((info->vga_state.CrtMiscIO & 0x80) == 0x80)
- outb_p(info->vga_state.CrtMiscIO & 0xef,video_misc_wr);
+ if ((par->vga_state.CrtMiscIO & 0x80) == 0x80)
+ vga_io_w(video_misc_wr, par->vga_state.CrtMiscIO & 0xef);
/*
* Set <End of vertical retrace> to minimum (0) and
@@ -640,7 +832,7 @@ static void vga_vesa_blank(struct vga16fb_info *info, int mode)
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(info->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
+ outb_p(par->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
}
if (mode & VESA_HSYNC_SUSPEND) {
@@ -658,44 +850,44 @@ static void vga_vesa_blank(struct vga16fb_info *info, int mode)
/* restore both index registers */
outb_p(SeqCtrlIndex,seq_port_reg);
outb_p(CrtCtrlIndex,vga_video_port_reg);
- sti();
+ //sti();
}
-static void vga_vesa_unblank(struct vga16fb_info *info)
+static void vga_vesa_unblank(struct vga16fb_par *par)
{
unsigned char SeqCtrlIndex;
unsigned char CrtCtrlIndex;
- cli();
- SeqCtrlIndex = inb_p(seq_port_reg);
- CrtCtrlIndex = inb_p(vga_video_port_reg);
+ //cli();
+ SeqCtrlIndex = vga_io_r(seq_port_reg);
+ CrtCtrlIndex = vga_io_r(vga_video_port_reg);
/* restore original values of VGA controller registers */
- outb_p(info->vga_state.CrtMiscIO,video_misc_wr);
-
- outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
- outb_p(info->vga_state.HorizontalTotal,vga_video_port_val);
- outb_p(0x01,vga_video_port_reg); /* HorizDisplayEnd */
- outb_p(info->vga_state.HorizDisplayEnd,vga_video_port_val);
- outb_p(0x04,vga_video_port_reg); /* StartHorizRetrace */
- outb_p(info->vga_state.StartHorizRetrace,vga_video_port_val);
- outb_p(0x05,vga_video_port_reg); /* EndHorizRetrace */
- outb_p(info->vga_state.EndHorizRetrace,vga_video_port_val);
- outb_p(0x07,vga_video_port_reg); /* Overflow */
- outb_p(info->vga_state.Overflow,vga_video_port_val);
- outb_p(0x10,vga_video_port_reg); /* StartVertRetrace */
- outb_p(info->vga_state.StartVertRetrace,vga_video_port_val);
- outb_p(0x11,vga_video_port_reg); /* EndVertRetrace */
- outb_p(info->vga_state.EndVertRetrace,vga_video_port_val);
- outb_p(0x17,vga_video_port_reg); /* ModeControl */
- outb_p(info->vga_state.ModeControl,vga_video_port_val);
- outb_p(0x01,seq_port_reg); /* ClockingMode */
- outb_p(info->vga_state.ClockingMode,seq_port_val);
+ vga_io_w(video_misc_wr, par->vga_state.CrtMiscIO);
+
+ /* HorizontalTotal */
+ vga_io_wcrt(0x00, par->vga_state.HorizontalTotal);
+ /* HorizDisplayEnd */
+ vga_io_wcrt(0x01, par->vga_state.HorizDisplayEnd);
+ /* StartHorizRetrace */
+ vga_io_wcrt(0x04, par->vga_state.StartHorizRetrace);
+ /* EndHorizRetrace */
+ vga_io_wcrt(0x05, par->vga_state.EndHorizRetrace);
+ /* Overflow */
+ vga_io_wcrt(0x07, par->vga_state.Overflow);
+ /* StartVertRetrace */
+ vga_io_wcrt(0x10, par->vga_state.StartVertRetrace);
+ /* EndVertRetrace */
+ vga_io_wcrt(0x11, par->vga_state.EndVertRetrace);
+ /* ModeControl */
+ vga_io_wcrt(0x17, par->vga_state.ModeControl);
+ /* ClockingMode */
+ vga_io_wseq(0x01, par->vga_state.ClockingMode);
/* restore index/control registers */
- outb_p(SeqCtrlIndex,seq_port_reg);
- outb_p(CrtCtrlIndex,vga_video_port_reg);
- sti();
+ vga_io_w(seq_port_reg, SeqCtrlIndex);
+ vga_io_w(vga_video_port_reg, CrtCtrlIndex);
+ //sti();
}
static void vga_pal_blank(void)
@@ -711,127 +903,562 @@ static void vga_pal_blank(void)
}
/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
-static int vga16fb_blank(int blank, struct fb_info *fb_info)
+static int vga16fb_blank(int blank, struct fb_info *info)
{
- struct vga16fb_info *info = (struct vga16fb_info*)fb_info;
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
switch (blank) {
case 0: /* Unblank */
- if (info->vesa_blanked) {
- vga_vesa_unblank(info);
- info->vesa_blanked = 0;
+ if (par->vesa_blanked) {
+ vga_vesa_unblank(par);
+ par->vesa_blanked = 0;
}
- if (info->palette_blanked) {
- do_install_cmap(fb_info->currcon, fb_info);
- info->palette_blanked = 0;
+ if (par->palette_blanked) {
+ //do_install_cmap(info->currcon, info);
+ par->palette_blanked = 0;
}
break;
case 1: /* blank */
vga_pal_blank();
- info->palette_blanked = 1;
+ par->palette_blanked = 1;
break;
default: /* VESA blanking */
- vga_vesa_blank(info, blank-1);
- info->vesa_blanked = 1;
+ vga_vesa_blank(par, blank-1);
+ par->vesa_blanked = 1;
break;
}
return 0;
}
+void vga_8planes_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+ char oldindex = getindex();
+ char oldmode = setmode(0x40);
+ char oldmask = selectmask();
+ int line_ofs, height;
+ char oldop, oldsr;
+ char *where;
+
+ rect->dx /= 4;
+ where = info->screen_base + rect->dx + rect->dy * info->fix.line_length;
+
+ if (rect->rop == ROP_COPY) {
+ oldop = setop(0);
+ oldsr = setsr(0);
+
+ rect->width /= 4;
+ line_ofs = info->fix.line_length - rect->width;
+ setmask(0xff);
+
+ height = rect->height;
+
+ while (height--) {
+ int x;
+
+ /* we can do memset... */
+ for (x = rect->width; x > 0; --x) {
+ writeb(rect->color, where);
+ where++;
+ }
+ where += line_ofs;
+ }
+ } else {
+ char oldcolor = setcolor(0xf);
+ int y;
+
+ oldop = setop(0x18);
+ oldsr = setsr(0xf);
+ setmask(0x0F);
+ for (y = 0; y < rect->height; y++) {
+ rmw(where);
+ rmw(where+1);
+ where += info->fix.line_length;
+ }
+ setcolor(oldcolor);
+ }
+ setmask(oldmask);
+ setsr(oldsr);
+ setop(oldop);
+ setmode(oldmode);
+ setindex(oldindex);
+}
+
+void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+ int x, x2, y2, vxres, vyres, width, height, line_ofs;
+ char *dst;
+
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+
+ if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)
+ return;
+
+ /* We could use hardware clipping but on many cards you get around
+ * hardware clipping by writing to framebuffer directly. */
+
+ x2 = rect->dx + rect->width;
+ y2 = rect->dy + rect->height;
+ x2 = x2 < vxres ? x2 : vxres;
+ y2 = y2 < vyres ? y2 : vyres;
+ rect->width = x2 - rect->dx;
+
+ switch (info->fix.type) {
+ case FB_TYPE_VGA_PLANES:
+ if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
+
+ height = y2 - rect->dy;
+ width = rect->width/8;
+
+ line_ofs = info->fix.line_length - width;
+ dst = info->screen_base + (rect->dx/8) + rect->dy * info->fix.line_length;
+
+ switch (rect->rop) {
+ case ROP_COPY:
+ setmode(0);
+ setop(0);
+ setsr(0xf);
+ setcolor(rect->color);
+ selectmask();
+
+ setmask(0xff);
+
+ while (height--) {
+ for (x = 0; x < width; x++) {
+ writeb(0, dst);
+ dst++;
+ }
+ dst += line_ofs;
+ }
+ break;
+ case ROP_XOR:
+ setmode(0);
+ setop(0x18);
+ setsr(0xf);
+ setcolor(0xf);
+ selectmask();
+
+ setmask(0xff);
+ while (height--) {
+ for (x = 0; x < width; x++) {
+ rmw(dst);
+ dst++;
+ }
+ dst += line_ofs;
+ }
+ break;
+ }
+ } else
+ vga_8planes_fillrect(info, rect);
+ break;
+#ifdef FBCON_HAS_VGA
+ case FB_TYPE_TEXT:
+ break;
+#endif
+ case FB_TYPE_PACKED_PIXELS:
+ default:
+ cfb_fillrect(info, rect);
+ break;
+ }
+}
+
+void vga_8planes_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+ int height, line_ofs, x;
+ char oldindex = getindex();
+ char oldmode = setmode(0x41);
+ char oldop = setop(0);
+ char oldsr = setsr(0xf);
+ char *dest, *src;
+
+ height = area->height;
+
+ area->sx = area->sx / 4;
+ area->dx = area->dx / 4;
+ area->width = area->width / 4;
+
+ if (area->dy < area->sy || (area->dy == area->sy && area->dx < area->sx)) {
+ line_ofs = info->fix.line_length - area->width;
+ dest = info->screen_base + area->dx + area->dy * info->fix.line_length;
+ src = info->screen_base + area->sx + area->sy * info->fix.line_length;
+ while (height--) {
+ for (x = 0; x < area->width; x++) {
+ readb(src);
+ writeb(0, dest);
+ src++;
+ dest++;
+ }
+ src += line_ofs;
+ dest += line_ofs;
+ }
+ } else {
+ line_ofs = info->fix.line_length - area->width;
+ dest = info->screen_base + area->dx + area->width +
+ (area->dy + height - 1) * info->fix.line_length;
+ src = info->screen_base + area->sx + area->width +
+ (area->sy + height - 1) * info->fix.line_length;
+ while (height--) {
+ for (x = 0; x < area->width; x++) {
+ --src;
+ --dest;
+ readb(src);
+ writeb(0, dest);
+ }
+ src -= line_ofs;
+ dest -= line_ofs;
+ }
+ }
+
+ setsr(oldsr);
+ setop(oldop);
+ setmode(oldmode);
+ setindex(oldindex);
+}
+
+void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+ int x, x2, y2, old_dx, old_dy, vxres, vyres;
+ int height, width, line_ofs;
+ char *dst = NULL, *src = NULL;
+
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+
+ if (area->dx > vxres || area->sx > vxres || area->dy > vyres ||
+ area->sy > vyres)
+ return;
+
+ /* clip the destination */
+ old_dx = area->dx;
+ old_dy = area->dy;
+
+ /*
+ * We could use hardware clipping but on many cards you get around
+ * hardware clipping by writing to framebuffer directly.
+ */
+ x2 = area->dx + area->width;
+ y2 = area->dy + area->height;
+ area->dx = area->dx > 0 ? area->dx : 0;
+ area->dy = area->dy > 0 ? area->dy : 0;
+ x2 = x2 < vxres ? x2 : vxres;
+ y2 = y2 < vyres ? y2 : vyres;
+ area->width = x2 - area->dx;
+ area->height = y2 - area->dy;
+
+ /* update sx1,sy1 */
+ area->sx += (area->dx - old_dx);
+ area->sy += (area->dy - old_dy);
+
+ /* the source must be completely inside the virtual screen */
+ if (area->sx < 0 || area->sy < 0 ||
+ (area->sx + area->width) > vxres ||
+ (area->sy + area->height) > vyres)
+ return;
+
+ switch (info->fix.type) {
+ case FB_TYPE_VGA_PLANES:
+ if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
+ width = area->width/8;
+ height = area->height;
+ line_ofs = info->fix.line_length - width;
+
+ setmode(1);
+ setop(0);
+ setsr(0xf);
+
+ if (area->dy < area->sy || (area->dy == area->sy && area->dx < area->sx)) {
+ dst = info->screen_base + (area->dx/8) + area->dy * info->fix.line_length;
+ src = info->screen_base + (area->sx/8) + area->sy * info->fix.line_length;
+ while (height--) {
+ for (x = 0; x < width; x++) {
+ readb(src);
+ writeb(0, dst);
+ dst++;
+ src++;
+ }
+ src += line_ofs;
+ dst += line_ofs;
+ }
+ } else {
+ dst = info->screen_base + (area->dx/8) + width +
+ (area->dy + height - 1) * info->fix.line_length;
+ src = info->screen_base + (area->sx/8) + width +
+ (area->sy + height - 1) * info->fix.line_length;
+ while (height--) {
+ for (x = 0; x < width; x++) {
+ dst--;
+ src--;
+ readb(src);
+ writeb(0, dst);
+ }
+ src -= line_ofs;
+ dst -= line_ofs;
+ }
+ }
+ } else
+ vga_8planes_copyarea(info, area);
+ break;
+#ifdef FBCON_HAS_VGA
+ case FB_TYPE_TEXT:
+ break;
+#endif
+ case FB_TYPE_PACKED_PIXELS:
+ default:
+ cfb_copyarea(info, area);
+ break;
+ }
+}
+
+#ifdef __LITTLE_ENDIAN
+static unsigned int transl_l[] =
+{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
+static unsigned int transl_h[] =
+{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
+ 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
+#else
+#ifdef __BIG_ENDIAN
+static unsigned int transl_h[] =
+{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
+static unsigned int transl_l[] =
+{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
+ 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
+#else
+#error "Only __BIG_ENDIAN and __LITTLE_ENDIAN are supported in vga-planes"
+#endif
+#endif
+
+void vga_8planes_imageblit(struct fb_info *info, struct fb_image *image)
+{
+ char oldindex = getindex();
+ char oldmode = setmode(0x40);
+ char oldop = setop(0);
+ char oldsr = setsr(0);
+ char oldmask = selectmask();
+ u8 *cdat = image->data;
+ char *where;
+ int y;
+
+ image->dx /= 4;
+ where = info->screen_base + image->dx + image->dy * info->fix.line_length;
+
+ setmask(0xff);
+ writeb(image->bg_color, where);
+ readb(where);
+ selectmask();
+ setmask(image->fg_color ^ image->bg_color);
+ setmode(0x42);
+ setop(0x18);
+ for (y = 0; y < image->height; y++, where += info->fix.line_length)
+ writew(transl_h[cdat[y]&0xF] | transl_l[cdat[y] >> 4], where);
+ setmask(oldmask);
+ setsr(oldsr);
+ setop(oldop);
+ setmode(oldmode);
+ setindex(oldindex);
+}
+
+void vga_imageblit_expand(struct fb_info *info, struct fb_image *image)
+{
+ char *where = info->screen_base + (image->dx/8) +
+ image->dy * info->fix.line_length;
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ u8 *cdat = image->data, *dst;
+ int x, y;
+
+ switch (info->fix.type) {
+ case FB_TYPE_VGA_PLANES:
+ if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
+ if (par->isVGA) {
+ setmode(2);
+ setop(0);
+ setsr(0xf);
+ setcolor(image->fg_color);
+ selectmask();
+
+ setmask(0xff);
+ writeb(image->bg_color, where);
+ rmb();
+ readb(where); /* fill latches */
+ setmode(3);
+ wmb();
+ for (y = 0; y < image->height; y++) {
+ dst = where;
+ for (x = image->width/8; x--;)
+ writeb(*cdat++, dst++);
+ where += info->fix.line_length;
+ }
+ wmb();
+ } else {
+ setmode(0);
+ setop(0);
+ setsr(0xf);
+ setcolor(image->bg_color);
+ selectmask();
+
+ setmask(0xff);
+ for (y = 0; y < image->height; y++) {
+ dst = where;
+ for (x=image->width/8; x--;){
+ rmw(dst);
+ setcolor(image->fg_color);
+ selectmask();
+ if (*cdat) {
+ setmask(*cdat++);
+ rmw(dst++);
+ }
+ }
+ where += info->fix.line_length;
+ }
+ }
+ } else
+ vga_8planes_imageblit(info, image);
+ break;
+#ifdef FBCON_HAS_VGA
+ case FB_TYPE_TEXT:
+ break;
+#endif
+ case FB_TYPE_PACKED_PIXELS:
+ default:
+ cfb_imageblit(info, image);
+ break;
+ }
+}
+
+void vga_imageblit_color(struct fb_info *info, struct fb_image *image)
+{
+ /*
+ * Draw logo
+ */
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ char *where = info->screen_base + image->dy * info->fix.line_length +
+ image->dx/8;
+ char *cdat = image->data, *dst;
+ int x, y;
+
+ switch (info->fix.type) {
+ case FB_TYPE_VGA_PLANES:
+ if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4 &&
+ par->isVGA) {
+ setsr(0xf);
+ setop(0);
+ setmode(0);
+
+ for (y = 0; y < image->height; y++) {
+ for (x = 0; x < image->width; x++) {
+ dst = where + x/8;
+
+ setcolor(*cdat);
+ selectmask();
+ setmask(1 << (7 - (x % 8)));
+ fb_readb(dst);
+ fb_writeb(0, dst);
+
+ cdat++;
+ }
+ where += info->fix.line_length;
+ }
+ }
+ break;
+ case FB_TYPE_PACKED_PIXELS:
+ cfb_imageblit(info, image);
+ break;
+ default:
+ break;
+ }
+}
+
+void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+ if (image->depth == 1)
+ vga_imageblit_expand(info, image);
+ else if (image->depth == info->var.bits_per_pixel)
+ vga_imageblit_color(info, image);
+}
+
static struct fb_ops vga16fb_ops = {
- .owner = THIS_MODULE,
- .fb_set_var = vga16fb_set_var,
- .fb_get_cmap = gen_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = vga16fb_setcolreg,
- .fb_pan_display =vga16fb_pan_display,
- .fb_blank = vga16fb_blank,
+ .owner = THIS_MODULE,
+ .fb_open = vga16fb_open,
+ .fb_release = vga16fb_release,
+ .fb_check_var = vga16fb_check_var,
+ .fb_set_par = vga16fb_set_par,
+ .fb_setcolreg = vga16fb_setcolreg,
+ .fb_pan_display = vga16fb_pan_display,
+ .fb_blank = vga16fb_blank,
+ .fb_fillrect = vga16fb_fillrect,
+ .fb_copyarea = vga16fb_copyarea,
+ .fb_imageblit = vga16fb_imageblit,
+ .fb_cursor = soft_cursor,
};
int vga16fb_setup(char *options)
{
char *this_opt;
- vga16fb.fb_info.fontname[0] = '\0';
-
if (!options || !*options)
return 0;
while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt) continue;
-
- if (!strncmp(this_opt, "font:", 5))
- strcpy(vga16fb.fb_info.fontname, this_opt+5);
}
return 0;
}
int __init vga16fb_init(void)
{
- int i,j;
+ int i;
printk(KERN_DEBUG "vga16fb: initializing\n");
- /* XXX share VGA_FB_PHYS region with vgacon */
+ /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
- vga16fb.video_vbase = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
- if (!vga16fb.video_vbase) {
+ vga16fb.screen_base = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
+ if (!vga16fb.screen_base) {
printk(KERN_ERR "vga16fb: unable to map device\n");
return -ENOMEM;
}
- printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);
+ printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
- vga16fb.isVGA = ORIG_VIDEO_ISVGA;
- vga16fb.palette_blanked = 0;
- vga16fb.vesa_blanked = 0;
+ vga16_par.isVGA = ORIG_VIDEO_ISVGA;
+ vga16_par.palette_blanked = 0;
+ vga16_par.vesa_blanked = 0;
- i = vga16fb.isVGA? 6 : 2;
+ i = vga16_par.isVGA? 6 : 2;
vga16fb_defined.red.length = i;
vga16fb_defined.green.length = i;
vga16fb_defined.blue.length = i;
- 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];
- }
- /* XXX share VGA I/O region with vgacon and others */
+ /* name should not depend on EGA/VGA */
+ vga16fb.node = NODEV;
+ vga16fb.fbops = &vga16fb_ops;
+ vga16fb.var = vga16fb_defined;
+ vga16fb.fix = vga16fb_fix;
+ vga16fb.par = &vga16_par;
+ vga16fb.flags = FBINFO_FLAG_DEFAULT;
- disp.var = vga16fb_defined;
+ i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
+ fb_alloc_cmap(&vga16fb.cmap, i, 0);
- strcpy(vga16fb.fb_info.modename, vga16fb_fix.id);
- vga16fb.fb_info.changevar = NULL;
- vga16fb.fb_info.node = NODEV;
- vga16fb.fb_info.var = vga16fb_defined;
- vga16fb.fb_info.fix = vga16fb_fix;
- vga16fb.fb_info.fbops = &vga16fb_ops;
- vga16fb.fb_info.screen_base = vga16fb.video_vbase;
- vga16fb.fb_info.disp=&disp;
- vga16fb.fb_info.currcon = -1;
- vga16fb.fb_info.switch_con=&gen_switch;
- vga16fb.fb_info.updatevar=&gen_update_var;
- vga16fb.fb_info.flags=FBINFO_FLAG_DEFAULT;
- vga16fb_set_disp(-1, &vga16fb);
+ if (vga16fb_check_var(&vga16fb.var, &vga16fb))
+ return -EINVAL;
- fb_alloc_cmap(&vga16fb.fb_info.cmap, 16, 0);
+ vga16fb_update_fix(&vga16fb);
- if (register_framebuffer(&vga16fb.fb_info)<0) {
- iounmap(vga16fb.video_vbase);
+ if (register_framebuffer(&vga16fb) < 0) {
+ iounmap(vga16fb.screen_base);
return -EINVAL;
}
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(vga16fb.fb_info.node), vga16fb.fb_info.modename);
+ minor(vga16fb.node), vga16fb.fix.id);
return 0;
}
static void __exit vga16fb_exit(void)
{
- unregister_framebuffer(&vga16fb.fb_info);
- iounmap(vga16fb.video_vbase);
+ unregister_framebuffer(&vga16fb);
+ iounmap(vga16fb.screen_base);
/* XXX unshare VGA regions */
}
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
new file mode 100644
index 000000000000..2b6fc7dea40e
--- /dev/null
+++ b/drivers/video/vgastate.c
@@ -0,0 +1,438 @@
+/*
+ * linux/include/video/vgastate.c -- VGA state save/restore
+ *
+ * Copyright 2002 James Simmons
+ *
+ * Copyright history from vga16fb.c:
+ * Copyright 1999 Ben Pfaff and Petr Vandrovec
+ * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
+ * Based on VESA framebuffer (c) 1998 Gerd Knorr
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+
+#include "vga.h"
+
+static inline unsigned char vga_rcrtcs(caddr_t regbase, unsigned short iobase,
+ unsigned char reg)
+{
+ vga_w(regbase, iobase + 0x4, reg);
+ return vga_r(regbase, iobase + 0x5);
+}
+
+static inline void vga_wcrtcs(caddr_t regbase, unsigned short iobase,
+ unsigned char reg, unsigned char val)
+{
+ vga_w(regbase, iobase + 0x4, reg);
+ vga_w(regbase, iobase + 0x5, val);
+}
+
+static void save_vga_text(struct fb_vgastate *state)
+{
+ int i;
+ u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4;
+
+ /* if in graphics mode, no need to save */
+ attr10 = vga_rattr(state->vgabase, 0x10);
+ if (attr10 & 1)
+ return;
+
+ /* save regs */
+ misc = vga_r(state->vgabase, VGA_MIS_R);
+ gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
+ gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE);
+ gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
+ seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
+ seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
+
+ /* force graphics mode */
+ vga_w(state->vgabase, VGA_MIS_W, misc | 1);
+
+ /* blank screen */
+ seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 | 1 << 5);
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+ /* save font 0 */
+ if (state->flags & VGA_SAVE_FONT0) {
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 8 * 8192; i++)
+ state->vga_font0[i] = vga_r(state->fbbase, i);
+ }
+ /* save font 1 */
+ if (state->flags & VGA_SAVE_FONT1) {
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x8);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 8 * 8192; i++)
+ state->vga_font1[i] = vga_r(state->fbbase, i);
+ }
+ /* save font 2 */
+ if (state->flags & VGA_SAVE_TEXT) {
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 2 * 8192; i++)
+ state->vga_text[i] = vga_r(state->fbbase, i);
+
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 2 * 8192; i++)
+ state->vga_text[i] = vga_r(state->fbbase +
+ 2 * 8192, i);
+ }
+
+ /* restore regs */
+ vga_wattr(state->vgabase, 0x10, attr10);
+
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
+
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6);
+ vga_w(state->vgabase, VGA_MIS_W, misc);
+
+ /* unblank screen */
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 & ~(1 << 5));
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1);
+}
+
+static void restore_vga_text(struct fb_vgastate *state)
+{
+ int i;
+ u8 misc, gr1, gr3, gr4, gr5, gr6, gr8;
+ u8 seq1, seq2, seq4;
+
+ /* save regs */
+ misc = vga_r(state->vgabase, VGA_MIS_R);
+ gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE);
+ gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE);
+ gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
+ gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE);
+ gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
+ gr8 = vga_rgfx(state->vgabase, VGA_GFX_BIT_MASK);
+ seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
+ seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
+
+ /* force graphics mode */
+ vga_w(state->vgabase, VGA_MIS_W, misc | 1);
+
+ /* blank screen */
+ seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 | 1 << 5);
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+ if (state->depth == 4) {
+ vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, 0xff);
+ vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, 0x00);
+ }
+ /* restore font 0 */
+ if (state->flags & VGA_SAVE_FONT0) {
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 8 * 8192; i++)
+ vga_w(state->fbbase, i, state->vga_font0[i]);
+ }
+ /* restore font 1 */
+ if (state->flags & VGA_SAVE_FONT1) {
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x8);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 8 * 8192; i++)
+ vga_w(state->fbbase, i, state->vga_font1[i]);
+ }
+ /* restore font 2 */
+ if (state->flags & VGA_SAVE_TEXT) {
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 2 * 8192; i++)
+ vga_w(state->fbbase, i, state->vga_text[i]);
+
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+ for (i = 0; i < 2 * 8192; i++)
+ vga_w(state->fbbase + 2 * 8192, i,
+ state->vga_text[i]);
+ }
+ /* unblank screen */
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 & ~(1 << 5));
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+ /* restore regs */
+ vga_w(state->vgabase, VGA_MIS_W, misc);
+
+ vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1);
+ vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3);
+ vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
+ vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5);
+ vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6);
+ vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, gr8);
+
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1);
+ vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
+ vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
+}
+
+static void save_vga_mode(struct fb_vgastate *state)
+{
+ unsigned short iobase;
+ int i;
+
+ state->misc = vga_r(state->vgabase, VGA_MIS_R);
+ if (state->misc & 1)
+ iobase = 0x3d0;
+ else
+ iobase = 0x3b0;
+
+ for (i = 0; i < state->num_crtc; i++)
+ state->crtc[i] = vga_rcrtcs(state->vgabase, iobase, i);
+
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x00);
+ for (i = 0; i < state->num_attr; i++) {
+ vga_r(state->vgabase, iobase + 0xa);
+ state->attr[i] = vga_rattr(state->vgabase, i);
+ }
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x20);
+
+ for (i = 0; i < state->num_gfx; i++)
+ state->gfx[i] = vga_rgfx(state->vgabase, i);
+
+ for (i = 0; i < state->num_seq; i++)
+ state->seq[i] = vga_rseq(state->vgabase, i);
+}
+
+static void restore_vga_mode(struct fb_vgastate *state)
+{
+ unsigned short iobase;
+ int i;
+
+ vga_w(state->vgabase, VGA_MIS_W, state->misc);
+
+ if (state->misc & 1)
+ iobase = 0x3d0;
+ else
+ iobase = 0x3b0;
+
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01);
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE,
+ state->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
+
+ for (i = 2; i < state->num_seq; i++)
+ vga_wseq(state->vgabase, i, state->seq[i]);
+
+ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
+
+ /* unprotect vga regs */
+ vga_wcrtcs(state->vgabase, iobase, 17, state->crtc[17] & ~0x80);
+ for (i = 0; i < state->num_crtc; i++)
+ vga_wcrtcs(state->vgabase, iobase, i, state->crtc[i]);
+
+ for (i = 0; i < state->num_gfx; i++)
+ vga_wgfx(state->vgabase, i, state->gfx[i]);
+
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x00);
+ for (i = 0; i < state->num_attr; i++) {
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_wattr(state->vgabase, i, state->attr[i]);
+ }
+
+ vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE,
+ state->seq[VGA_SEQ_CLOCK_MODE]);
+
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x20);
+}
+
+static void save_vga_cmap(struct fb_vgastate *state)
+{
+ int i;
+
+ vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
+
+ /* assumes DAC is readable and writable */
+ vga_w(state->vgabase, VGA_PEL_IR, 0x00);
+ for (i = 0; i < 768; i++)
+ state->vga_cmap[i] = vga_r(state->vgabase, VGA_PEL_D);
+}
+
+static void restore_vga_cmap(struct fb_vgastate *state)
+{
+ int i;
+
+ vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
+
+ vga_w(state->vgabase, VGA_PEL_IW, 0x00);
+ for (i = 0; i < 768; i++)
+ vga_w(state->vgabase, VGA_PEL_D, state->vga_cmap[i]);
+}
+
+static void vga_cleanup(struct fb_vgastate *state)
+{
+ if (state->vga_font0)
+ kfree(state->vga_font0);
+ if (state->vga_font1)
+ kfree(state->vga_font1);
+ if (state->vga_text)
+ kfree(state->vga_text);
+ if (state->fbbase)
+ iounmap(state->fbbase);
+ if (state->vga_cmap)
+ kfree(state->vga_cmap);
+ if (state->attr)
+ kfree(state->attr);
+ if (state->crtc)
+ kfree(state->crtc);
+ if (state->gfx)
+ kfree(state->gfx);
+ if (state->seq)
+ kfree(state->seq);
+}
+
+int fb_save_vga(struct fb_vgastate *state)
+{
+ state->vga_font0 = NULL;
+ state->vga_font1 = NULL;
+ state->vga_text = NULL;
+ state->vga_cmap = NULL;
+ state->attr = NULL;
+ state->crtc = NULL;
+ state->gfx = NULL;
+ state->seq = NULL;
+
+ if (state->flags & VGA_SAVE_CMAP) {
+ state->vga_cmap = kmalloc(768, GFP_KERNEL);
+ if (!state->vga_cmap) {
+ vga_cleanup(state);
+ return 1;
+ }
+ save_vga_cmap(state);
+ }
+
+ if (state->flags & VGA_SAVE_MODE) {
+ if (state->num_attr < 21)
+ state->num_attr = 21;
+ if (state->num_crtc < 25)
+ state->num_crtc = 25;
+ if (state->num_gfx < 9)
+ state->num_gfx = 9;
+ if (state->num_seq < 5)
+ state->num_seq = 5;
+ state->attr = kmalloc(state->num_attr, GFP_KERNEL);
+ state->crtc = kmalloc(state->num_crtc, GFP_KERNEL);
+ state->gfx = kmalloc(state->num_gfx, GFP_KERNEL);
+ state->seq = kmalloc(state->num_seq, GFP_KERNEL);
+ if (!state->attr || !state->crtc || !state->gfx ||
+ !state->seq) {
+ vga_cleanup(state);
+ return 1;
+ }
+ save_vga_mode(state);
+ }
+
+ if (state->flags & VGA_SAVE_FONT0) {
+ state->vga_font0 = kmalloc(8192 * 8, GFP_KERNEL);
+ if (!state->vga_font0) {
+ vga_cleanup(state);
+ return 1;
+ }
+ }
+ if (state->flags & VGA_SAVE_FONT1) {
+ state->vga_font1 = kmalloc(8192 * 8, GFP_KERNEL);
+ if (!state->vga_font1) {
+ vga_cleanup(state);
+ return 1;
+ }
+ }
+ if (state->flags & VGA_SAVE_TEXT) {
+ state->vga_text = kmalloc(8192 * 4, GFP_KERNEL);
+ if (!state->vga_text) {
+ vga_cleanup(state);
+ return 1;
+ }
+ }
+ if (state->flags & VGA_SAVE_FONTS) {
+ state->fbbase = ioremap(0xA0000, 8 * 8192);
+ if (!state->fbbase) {
+ vga_cleanup(state);
+ return 1;
+ }
+ save_vga_text(state);
+ iounmap(state->fbbase);
+ state->fbbase = NULL;
+ }
+ return 0;
+}
+
+int fb_restore_vga (struct fb_vgastate *state)
+{
+ if (state->flags & VGA_SAVE_MODE)
+ restore_vga_mode(state);
+
+ if (state->flags & VGA_SAVE_FONTS) {
+ state->fbbase = ioremap(0xA0000, 8 * 8192);
+ if (!state->fbbase) {
+ vga_cleanup(state);
+ return 1;
+ }
+ restore_vga_text(state);
+ }
+
+ if (state->flags & VGA_SAVE_CMAP)
+ restore_vga_cmap(state);
+
+ vga_cleanup(state);
+ return 0;
+}
+
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
+
+EXPORT_SYMBOL(fb_save_vga);
+EXPORT_SYMBOL(fb_restore_vga);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("VGA State Save/Restore");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index 72039504e9e7..e9a54e973e04 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -1806,7 +1806,7 @@ int __init virgefb_init(void)
}
printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.node), fb_info.modename, v_ram_size>>10);
+ minor(fb_info.node), fb_info.modename, v_ram_size>>10);
/* TODO: This driver cannot be unloaded yet */
diff --git a/include/linux/console.h b/include/linux/console.h
index 646e0eaa9fb3..37b441e6dfd8 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -40,6 +40,7 @@ struct consw {
int (*con_switch)(struct vc_data *);
int (*con_blank)(struct vc_data *, int);
int (*con_font_op)(struct vc_data *, struct console_font_op *);
+ int (*con_resize)(struct vc_data *, unsigned int, unsigned int);
int (*con_set_palette)(struct vc_data *, unsigned char *);
int (*con_scrolldelta)(struct vc_data *, int);
int (*con_set_origin)(struct vc_data *);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index d86c16e96d11..153f71db1f38 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -27,6 +27,7 @@ struct vc_data {
unsigned char vc_halfcolor; /* Color for half intensity mode */
unsigned short vc_complement_mask; /* [#] Xor mask for mouse pointer */
unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */
+ struct console_font_op vc_font; /* Current VC font set */
unsigned short vc_video_erase_char; /* Background erase character */
unsigned short vc_s_complement_mask; /* Saved mouse pointer mask */
unsigned int vc_x, vc_y; /* Cursor position */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index cda1c818f68c..a3031b2a13c4 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -3,6 +3,7 @@
#include <linux/tty.h>
#include <asm/types.h>
+#include <asm/io.h>
/* Definitions of frame buffers */
@@ -17,6 +18,7 @@
#define FBIOGETCMAP 0x4604
#define FBIOPUTCMAP 0x4605
#define FBIOPAN_DISPLAY 0x4606
+#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor)
/* 0x4607-0x460B are defined below */
/* #define FBIOGET_MONITORSPEC 0x460C */
/* #define FBIOPUT_MONITORSPEC 0x460D */
@@ -208,7 +210,8 @@ struct fb_var_screeninfo {
__u32 vsync_len; /* length of vertical sync */
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
- __u32 reserved[6]; /* Reserved for future compatibility */
+ __u32 rotate; /* angle we rotate counter clockwise */
+ __u32 reserved[5]; /* Reserved for future compatibility */
};
struct fb_cmap {
@@ -262,12 +265,12 @@ struct fb_vblank {
#define ROP_XOR 1
struct fb_copyarea {
- __u32 sx; /* screen-relative */
- __u32 sy;
- __u32 width;
- __u32 height;
__u32 dx;
__u32 dy;
+ __u32 width;
+ __u32 height;
+ __u32 sx;
+ __u32 sy;
};
struct fb_fillrect {
@@ -280,23 +283,76 @@ struct fb_fillrect {
};
struct fb_image {
- __u32 width; /* Size of image */
+ __u32 dx; /* Where to place image */
+ __u32 dy;
+ __u32 width; /* Size of image */
__u32 height;
- __u16 dx; /* Where to place image */
- __u16 dy;
- __u32 fg_color; /* Only used when a mono bitmap */
+ __u32 fg_color; /* Only used when a mono bitmap */
__u32 bg_color;
- __u8 depth; /* Dpeth of the image */
- char *data; /* Pointer to image data */
+ __u8 depth; /* Depth of the image */
+ char *data; /* Pointer to image data */
+ struct fb_cmap cmap; /* color map info */
};
-#ifdef __KERNEL__
+/*
+ * hardware cursor control
+ */
-#if 1 /* to go away in 2.5.0 */
-extern int GET_FB_IDX(kdev_t rdev);
-#else
-#define GET_FB_IDX(node) (minor(node))
-#endif
+#define FB_CUR_SETCUR 0x01
+#define FB_CUR_SETPOS 0x02
+#define FB_CUR_SETHOT 0x04
+#define FB_CUR_SETCMAP 0x08
+#define FB_CUR_SETSHAPE 0x10
+#define FB_CUR_SETDEST 0x20
+#define FB_CUR_SETSIZE 0x40
+#define FB_CUR_SETALL 0xFF
+
+struct fbcurpos {
+ __u16 x, y;
+};
+
+struct fb_cursor {
+ __u16 set; /* what to set */
+ __u16 enable; /* cursor on/off */
+ __u16 rop; /* bitop operation */
+ char *mask; /* cursor mask bits */
+ char *dest; /* destination */
+ struct fbcurpos hot; /* cursor hot spot */
+ struct fb_image image; /* Cursor image */
+};
+
+/* VGA State Save and Restore */
+#define VGA_SAVE_FONT0 1 /* save/restore plane 2 fonts */
+#define VGA_SAVE_FONT1 2 /* save/restore plane 3 fonts */
+#define VGA_SAVE_TEXT 4 /* save/restore plane 0/1 fonts */
+#define VGA_SAVE_FONTS 7 /* save/restore all fonts */
+#define VGA_SAVE_MODE 8 /* save/restore video mode */
+#define VGA_SAVE_CMAP 16 /* save/restore color map/DAC */
+
+struct fb_vgastate {
+ caddr_t vgabase; /* mmio base, if supported */
+ __u32 flags; /* what state/s to save (see VGA_SAVE_*) */
+ __u32 depth; /* current fb depth, not important */
+ __u32 num_attr; /* number of att registers, 0 for default */
+ __u32 num_crtc; /* number of crt registers, 0 for default */
+ __u32 num_gfx; /* number of gfx registers, 0 for default */
+ __u32 num_seq; /* number of seq registers, 0 for default */
+ caddr_t fbbase; /* -- DO NOT ALTER STARTING HERE -- */
+ __u8 *vga_font0;
+ __u8 *vga_font1;
+ __u8 *vga_text;
+ __u8 *vga_cmap;
+ __u8 *attr;
+ __u8 *crtc;
+ __u8 *gfx;
+ __u8 *seq;
+ __u8 misc;
+};
+
+extern int fb_save_vga(struct fb_vgastate *state);
+extern int fb_restore_vga(struct fb_vgastate *state);
+
+#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/poll.h>
@@ -316,15 +372,9 @@ struct fb_ops {
struct module *owner;
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
- /* set settable parameters */
- int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
- /* get colormap */
- int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
- /* set colormap */
- int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
+ /* For framebuffers with strange non linear layouts */
+ ssize_t (*fb_read)(struct file *file, char *buf, size_t count, loff_t *ppos);
+ ssize_t (*fb_write)(struct file *file, const char *buf, size_t count, loff_t *ppos);
/* checks var and creates a par based on it */
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
/* set the video mode according to par */
@@ -335,26 +385,29 @@ struct fb_ops {
/* blank display */
int (*fb_blank)(int blank, struct fb_info *info);
/* pan display */
- int (*fb_pan_display)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+ int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
/* draws a rectangle */
void (*fb_fillrect)(struct fb_info *info, struct fb_fillrect *rect);
/* Copy data from area to another */
void (*fb_copyarea)(struct fb_info *info, struct fb_copyarea *region);
/* Draws a image to the display */
void (*fb_imageblit)(struct fb_info *info, struct fb_image *image);
+ /* Draws cursor */
+ int (*fb_cursor)(struct fb_info *info, struct fb_cursor *cursor);
+ /* Rotates the display */
+ void (*fb_rotate)(struct fb_info *info, int angle);
/* perform polling on fb device */
int (*fb_poll)(struct fb_info *info, poll_table *wait);
+ /* wait for blit idle, optional */
+ int (*fb_sync)(struct fb_info *info);
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, int con, struct fb_info *info);
+ unsigned long arg, struct fb_info *info);
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
- /* switch to/from raster image mode */
- int (*fb_rasterimg)(struct fb_info *info, int start);
};
struct fb_info {
- char modename[40]; /* default video mode */
kdev_t node;
int flags;
int open; /* Has this been open already ? */
@@ -362,18 +415,12 @@ struct fb_info {
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
+ struct fb_cursor cursor; /* Current cursor */
struct fb_cmap cmap; /* Current cmap */
struct fb_ops *fbops;
char *screen_base; /* Virtual address */
- struct display *disp; /* initial display variable */
struct vc_data *display_fg; /* Console visible on this display */
int currcon; /* Current VC. */
- char fontname[40]; /* default font name */
- int (*changevar)(int); /* tell console var has changed */
- int (*switch_con)(int, struct fb_info*);
- /* tell fb to switch consoles */
- int (*updatevar)(int, struct fb_info*);
- /* tell fb to update the vars */
void *pseudo_palette; /* Fake palette of 16 colors and
the cursor's color for non
palette mode */
@@ -387,31 +434,53 @@ struct fb_info {
#define FBINFO_FLAG_DEFAULT 0
#endif
- /*
- * `Generic' versions of the frame buffer device operations
- */
+#if defined(__sparc__)
-extern int gen_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-extern int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-extern int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-extern int fb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-extern void cfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
-extern void cfb_copyarea(struct fb_info *info, struct fb_copyarea *region);
-extern void cfb_imageblit(struct fb_info *info, struct fb_image *image);
+/* We map all of our framebuffers such that big-endian accesses
+ * are what we want, so the following is sufficient.
+ */
+
+#define fb_readb sbus_readb
+#define fb_readw sbus_readw
+#define fb_readl sbus_readl
+#define fb_writeb sbus_writeb
+#define fb_writew sbus_writew
+#define fb_writel sbus_writel
+#define fb_memset sbus_memset_io
+
+#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__)
+
+#define fb_readb __raw_readb
+#define fb_readw __raw_readw
+#define fb_readl __raw_readl
+#define fb_writeb __raw_writeb
+#define fb_writew __raw_writew
+#define fb_writel __raw_writel
+#define fb_memset memset_io
+
+#else
+
+#define fb_readb(addr) (*(volatile u8 *) (addr))
+#define fb_readw(addr) (*(volatile u16 *) (addr))
+#define fb_readl(addr) (*(volatile u32 *) (addr))
+#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
+#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
+#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
+#define fb_memset memset
+
+#endif
/*
- * Helper functions
+ * `Generic' versions of the frame buffer device operations
*/
-extern void do_install_cmap(int con, struct fb_info *info);
-extern int gen_update_var(int con, struct fb_info *info);
+extern int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info);
+extern int fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
extern int fb_blank(int blank, struct fb_info *info);
-extern int gen_switch(int con, struct fb_info *info);
-extern void gen_set_disp(int con, struct fb_info *info);
+extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
+extern void cfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
+extern void cfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
+extern void cfb_imageblit(struct fb_info *info, struct fb_image *image);
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
@@ -427,12 +496,9 @@ extern int fbmon_dpms(const struct fb_info *fb_info);
/* drivers/video/fbcmap.c */
extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+extern void fb_dealloc_cmap(struct fb_cmap *cmap);
extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to,
int fsfromto);
-extern int fb_get_cmap(struct fb_cmap *cmap, int kspc,
- int (*getcolreg)(u_int, u_int *, u_int *, u_int *,
- u_int *, struct fb_info *),
- struct fb_info *fb_info);
extern int fb_set_cmap(struct fb_cmap *cmap, int kspc, struct fb_info *fb_info);
extern struct fb_cmap *fb_default_cmap(int len);
extern void fb_invert_cmaps(void);
@@ -491,54 +557,4 @@ extern int __init fb_find_mode(struct fb_var_screeninfo *var,
#endif /* __KERNEL__ */
-#if 1
-
-#define FBCMD_GET_CURRENTPAR 0xDEAD0005
-#define FBCMD_SET_CURRENTPAR 0xDEAD8005
-
-#endif
-
-
-#if 1 /* Preliminary */
-
- /*
- * Hardware Cursor
- */
-
-#define FBIOGET_FCURSORINFO 0x4607
-#define FBIOGET_VCURSORINFO 0x4608
-#define FBIOPUT_VCURSORINFO 0x4609
-#define FBIOGET_CURSORSTATE 0x460A
-#define FBIOPUT_CURSORSTATE 0x460B
-
-
-struct fb_fix_cursorinfo {
- __u16 crsr_width; /* width and height of the cursor in */
- __u16 crsr_height; /* pixels (zero if no cursor) */
- __u16 crsr_xsize; /* cursor size in display pixels */
- __u16 crsr_ysize;
- __u16 crsr_color1; /* colormap entry for cursor color1 */
- __u16 crsr_color2; /* colormap entry for cursor color2 */
-};
-
-struct fb_var_cursorinfo {
- __u16 width;
- __u16 height;
- __u16 xspot;
- __u16 yspot;
- __u8 data[1]; /* field with [height][width] */
-};
-
-struct fb_cursorstate {
- __s16 xoffset;
- __s16 yoffset;
- __u16 mode;
-};
-
-#define FB_CURSOR_OFF 0
-#define FB_CURSOR_ON 1
-#define FB_CURSOR_FLASH 2
-
-#endif /* Preliminary */
-
#endif /* _LINUX_FB_H */
diff --git a/include/linux/radeonfb.h b/include/linux/radeonfb.h
new file mode 100644
index 000000000000..99bdf91bbc5d
--- /dev/null
+++ b/include/linux/radeonfb.h
@@ -0,0 +1,15 @@
+#ifndef __LINUX_RADEONFB_H__
+#define __LINUX_RADEONFB_H__
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+#define ATY_RADEON_LCD_ON 0x00000001
+#define ATY_RADEON_CRT_ON 0x00000002
+
+
+#define FBIO_RADEON_GET_MIRROR _IOR('@', 3, sizeof(__u32*))
+#define FBIO_RADEON_SET_MIRROR _IOW('@', 4, sizeof(__u32*))
+
+#endif
+
diff --git a/include/linux/sisfb.h b/include/linux/sisfb.h
index 4d12567013ba..f45257643986 100644
--- a/include/linux/sisfb.h
+++ b/include/linux/sisfb.h
@@ -1,6 +1,11 @@
#ifndef _LINUX_SISFB
#define _LINUX_SISFB
+#include <linux/spinlock.h>
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
#define DISPTYPE_CRT1 0x00000008L
#define DISPTYPE_CRT2 0x00000004L
#define DISPTYPE_LCD 0x00000002L
@@ -20,6 +25,7 @@
#define HASVB_303 0x40
#define HASVB_CHRONTEL 0x80
+/* TW: *Never* change the order of the following enum */
typedef enum _SIS_CHIP_TYPE {
SIS_VGALegacy = 0,
SIS_300,
@@ -32,10 +38,17 @@ typedef enum _SIS_CHIP_TYPE {
SIS_315PRO,
SIS_640,
SIS_740,
- SIS_330,
+ SIS_650,
+ SIS_330,
MAX_SIS_CHIP
} SIS_CHIP_TYPE;
+typedef enum _VGA_ENGINE {
+ UNKNOWN_VGA = 0,
+ SIS_300_VGA,
+ SIS_315_VGA,
+} VGA_ENGINE;
+
typedef enum _TVTYPE {
TVMODE_NTSC = 0,
TVMODE_PAL,
@@ -81,21 +94,25 @@ struct ap_data {
};
struct video_info {
- int chip_id;
+ int chip_id;
unsigned int video_size;
unsigned long video_base;
- char *video_vbase;
+ char * video_vbase;
unsigned long mmio_base;
- char *mmio_vbase;
+ char * mmio_vbase;
unsigned long vga_base;
+ unsigned long mtrr;
+ unsigned long heapstart;
int video_bpp;
+ int video_cmap_len;
int video_width;
int video_height;
int video_vwidth;
int video_vheight;
int org_x;
int org_y;
+ int video_linelength;
unsigned int refresh_rate;
unsigned long disp_state;
@@ -106,9 +123,42 @@ struct video_info {
SIS_CHIP_TYPE chip;
unsigned char revision_id;
+ unsigned short DstColor; /* TW: For 2d acceleration */
+ unsigned long SiS310_AccelDepth;
+ unsigned long CommandReg;
+
+ spinlock_t lockaccel;
+
char reserved[256];
};
+
+/* TW: Addtional IOCTL for communication sisfb <> X driver */
+/* If changing this, vgatypes.h must also be changed (for X driver) */
+
+/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO _IOR('n',0xF8,sizeof(__u32))
+
+/* TW: Structure argument for SISFB_GET_INFO ioctl */
+typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
+
+struct _SISFB_INFO {
+ unsigned long sisfb_id; /* for identifying sisfb */
+#ifndef SISFB_ID
+#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
+#endif
+ int chip_id; /* PCI ID of detected chip */
+ int memory; /* video memory in KB which sisfb manages */
+ int heapstart; /* heap start (= sisfb "mem" argument) in KB */
+ unsigned char fbvidmode; /* current sisfb mode */
+
+ unsigned char sisfb_version;
+ unsigned char sisfb_revision;
+ unsigned char sisfb_patchlevel;
+
+ char reserved[253]; /* for future use */
+};
+
#ifdef __KERNEL__
extern struct video_info ivideo;
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 6d0b234f5a61..d611200c749d 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -10,6 +10,7 @@
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/tty.h>
+#include <linux/console_struct.h>
/*
* Presently, a lot of graphics programs do not restore the contents of
@@ -37,14 +38,9 @@ extern int kbd_rate(struct kbd_repeat *rep);
/* console.c */
-struct console_font_op;
-
int vc_allocate(unsigned int console);
int vc_cons_allocated(unsigned int console);
-int vc_resize(unsigned int lines, unsigned int cols,
- unsigned int first, unsigned int last);
-#define vc_resize_all(l, c) vc_resize(l, c, 0, MAX_NR_CONSOLES-1)
-#define vc_resize_con(l, c, x) vc_resize(l, c, x, x)
+int vc_resize(int currcons, unsigned int cols, unsigned int lines);
void vc_disallocate(unsigned int console);
void reset_palette(int currcons);
void set_palette(int currcons);
diff --git a/include/video/fbcon-afb.h b/include/video/fbcon-afb.h
deleted file mode 100644
index cbbcf0019ad9..000000000000
--- a/include/video/fbcon-afb.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Amiga bitplanes (afb)
- */
-
-#ifndef _VIDEO_FBCON_AFB_H
-#define _VIDEO_FBCON_AFB_H
-
-#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,
- int height, int width);
-extern void fbcon_afb_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_afb_revc(struct display *p, int xx, int yy);
-
-#endif
diff --git a/include/video/fbcon-cfb16.h b/include/video/fbcon-cfb16.h
deleted file mode 100644
index 3ccc7d7cd535..000000000000
--- a/include/video/fbcon-cfb16.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * FBcon low-level driver for 16 bpp packed pixel (cfb16)
- */
-
-#ifndef _VIDEO_FBCON_CFB16_H
-#define _VIDEO_FBCON_CFB16_H
-
-#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 void fbcon_cfb16_setup(struct display *p);
-extern void fbcon_cfb16_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width);
-extern void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 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,
- int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB16_H */
diff --git a/include/video/fbcon-cfb2.h b/include/video/fbcon-cfb2.h
deleted file mode 100644
index 5ba68a5f0a4f..000000000000
--- a/include/video/fbcon-cfb2.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for 2 bpp packed pixel (cfb2)
- */
-
-#ifndef _VIDEO_FBCON_CFB2_H
-#define _VIDEO_FBCON_CFB2_H
-
-#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,
- int height, int width);
-extern void fbcon_cfb2_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb2_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_CFB2_H */
diff --git a/include/video/fbcon-cfb24.h b/include/video/fbcon-cfb24.h
deleted file mode 100644
index 77442e22d2af..000000000000
--- a/include/video/fbcon-cfb24.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * FBcon low-level driver for 24 bpp packed pixel (cfb24)
- */
-
-#ifndef _VIDEO_FBCON_CFB24_H
-#define _VIDEO_FBCON_CFB24_H
-
-#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 void fbcon_cfb24_setup(struct display *p);
-extern void fbcon_cfb24_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width);
-extern void fbcon_cfb24_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 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,
- int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB24_H */
diff --git a/include/video/fbcon-cfb32.h b/include/video/fbcon-cfb32.h
deleted file mode 100644
index abac3baa2f37..000000000000
--- a/include/video/fbcon-cfb32.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * FBcon low-level driver for 32 bpp packed pixel (cfb32)
- */
-
-#ifndef _VIDEO_FBCON_CFB32_H
-#define _VIDEO_FBCON_CFB32_H
-
-#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 void fbcon_cfb32_setup(struct display *p);
-extern void fbcon_cfb32_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width);
-extern void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 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,
- int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB32_H */
diff --git a/include/video/fbcon-cfb4.h b/include/video/fbcon-cfb4.h
deleted file mode 100644
index 963befe5ca1e..000000000000
--- a/include/video/fbcon-cfb4.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for 4 bpp packed pixel (cfb4)
- */
-
-#ifndef _VIDEO_FBCON_CFB4_H
-#define _VIDEO_FBCON_CFB4_H
-
-#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,
- int height, int width);
-extern void fbcon_cfb4_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb4_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_CFB4_H */
diff --git a/include/video/fbcon-cfb8.h b/include/video/fbcon-cfb8.h
deleted file mode 100644
index 96189d0acd27..000000000000
--- a/include/video/fbcon-cfb8.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * FBcon low-level driver for 8 bpp packed pixel (cfb8)
- */
-
-#ifndef _VIDEO_FBCON_CFB8_H
-#define _VIDEO_FBCON_CFB8_H
-
-#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,
- int height, int width);
-extern void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 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,
- int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB8_H */
diff --git a/include/video/fbcon-hga.h b/include/video/fbcon-hga.h
deleted file mode 100644
index 695ab443f2a4..000000000000
--- a/include/video/fbcon-hga.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Hercules Graphics Adaptor (hga)
- */
-
-#ifndef _VIDEO_FBCON_HGA_H
-#define _VIDEO_FBCON_HGA_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_HGA) || defined(CONFIG_FBCON_HGA_MODULE)
-#define FBCON_HAS_HGA
-#endif
-#else
-#if defined(CONFIG_FBCON_HGA)
-#define FBCON_HAS_HGA
-#endif
-#endif
-
-extern struct display_switch fbcon_hga;
-extern void fbcon_hga_setup(struct display *p);
-extern void fbcon_hga_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width);
-extern void fbcon_hga_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-extern void fbcon_hga_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx);
-extern void fbcon_hga_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_hga_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_HGA_H */
diff --git a/include/video/fbcon-ilbm.h b/include/video/fbcon-ilbm.h
deleted file mode 100644
index 80f9707f679d..000000000000
--- a/include/video/fbcon-ilbm.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Amiga interleaved bitplanes (ilbm)
- */
-
-#ifndef _VIDEO_FBCON_ILBM_H
-#define _VIDEO_FBCON_ILBM_H
-
-#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,
- int height, int width);
-extern void fbcon_ilbm_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_ilbm_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_ILBM_H */
diff --git a/include/video/fbcon-iplan2p2.h b/include/video/fbcon-iplan2p2.h
deleted file mode 100644
index b72868035317..000000000000
--- a/include/video/fbcon-iplan2p2.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Atari interleaved bitplanes (2 planes) (iplan2p2)
- */
-
-#ifndef _VIDEO_FBCON_IPLAN2P2_H
-#define _VIDEO_FBCON_IPLAN2P2_H
-
-#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,
- int dx, int height, int width);
-extern void fbcon_iplan2p2_clear(struct vc_data *conp, struct display *p,
- int sy, int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_iplan2p2_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_IPLAN2P2_H */
diff --git a/include/video/fbcon-iplan2p4.h b/include/video/fbcon-iplan2p4.h
deleted file mode 100644
index a7012020421c..000000000000
--- a/include/video/fbcon-iplan2p4.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Atari interleaved bitplanes (4 planes) (iplan2p4)
- */
-
-#ifndef _VIDEO_FBCON_IPLAN2P4_H
-#define _VIDEO_FBCON_IPLAN2P4_H
-
-#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,
- int dx, int height, int width);
-extern void fbcon_iplan2p4_clear(struct vc_data *conp, struct display *p,
- int sy, int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_iplan2p4_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_IPLAN2P4_H */
diff --git a/include/video/fbcon-iplan2p8.h b/include/video/fbcon-iplan2p8.h
deleted file mode 100644
index 6691e18d6e26..000000000000
--- a/include/video/fbcon-iplan2p8.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Atari interleaved bitplanes (8 planes) (iplan2p8)
- */
-
-#ifndef _VIDEO_FBCON_IPLAN2P8_H
-#define _VIDEO_FBCON_IPLAN2P8_H
-
-#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,
- int dx, int height, int width);
-extern void fbcon_iplan2p8_clear(struct vc_data *conp, struct display *p,
- int sy, int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_iplan2p8_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_IPLAN2P8_H */
diff --git a/include/video/fbcon-mac.h b/include/video/fbcon-mac.h
deleted file mode 100644
index b275ff91b824..000000000000
--- a/include/video/fbcon-mac.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Mac variable bpp packed pixels (mac)
- */
-
-#ifndef _VIDEO_FBCON_MAC_H
-#define _VIDEO_FBCON_MAC_H
-
-#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,
- int height, int width);
-extern void fbcon_mac_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_mac_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_MAC_H */
diff --git a/include/video/fbcon-mfb.h b/include/video/fbcon-mfb.h
deleted file mode 100644
index f74e63da22a9..000000000000
--- a/include/video/fbcon-mfb.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for Monochrome (mfb)
- */
-
-#ifndef _VIDEO_FBCON_MFB_H
-#define _VIDEO_FBCON_MFB_H
-
-#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,
- int height, int width);
-extern void fbcon_mfb_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-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 unsigned short *s, int count, int yy, int xx);
-extern void fbcon_mfb_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_MFB_H */
diff --git a/include/video/fbcon-vga-planes.h b/include/video/fbcon-vga-planes.h
deleted file mode 100644
index 31578d41c58f..000000000000
--- a/include/video/fbcon-vga-planes.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * FBcon low-level driver for VGA 4-plane modes
- */
-
-#ifndef _VIDEO_FBCON_VGA_PLANES_H
-#define _VIDEO_FBCON_VGA_PLANES_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_VGA_PLANES) || defined(CONFIG_FBCON_VGA_PLANES_MODULE)
-#define FBCON_HAS_VGA_PLANES
-#endif
-#else
-#if defined(CONFIG_FBCON_VGA_PLANES)
-#define FBCON_HAS_VGA_PLANES
-#endif
-#endif
-
-extern struct display_switch fbcon_vga_planes;
-extern struct display_switch fbcon_ega_planes;
-extern void fbcon_vga_planes_setup(struct display *p);
-extern void fbcon_vga_planes_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width);
-extern void fbcon_vga_planes_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width);
-extern void fbcon_vga_planes_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx);
-extern void fbcon_ega_planes_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx);
-extern void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_vga_planes_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_VGA_PLANES_H */
diff --git a/include/video/fbcon-vga.h b/include/video/fbcon-vga.h
deleted file mode 100644
index e7c7b2db0ce7..000000000000
--- a/include/video/fbcon-vga.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * FBcon low-level driver for VGA characters/attributes
- */
-
-#ifndef _VIDEO_FBCON_VGA_H
-#define _VIDEO_FBCON_VGA_H
-
-#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);
-
-#endif /* _VIDEO_FBCON_VGA_H */
diff --git a/include/video/fbcon.h b/include/video/fbcon.h
deleted file mode 100644
index c28fea0c10c3..000000000000
--- a/include/video/fbcon.h
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * linux/drivers/video/fbcon.h -- Low level frame buffer based console driver
- *
- * 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.
- */
-
-#ifndef _VIDEO_FBCON_H
-#define _VIDEO_FBCON_H
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/console_struct.h>
-#include <linux/vt_buffer.h>
-
-#include <asm/io.h>
-
-
- /*
- * `switch' for the Low Level Operations
- */
-
-struct display_switch {
- void (*setup)(struct display *p);
- void (*bmove)(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width);
- /* for clear, conp may be NULL, which means use a blanking (black) color */
- void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
- 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 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,
- int bottom_only);
- unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */
-};
-
-extern struct display_switch fbcon_dummy;
-
- /*
- * This is the interface between the low-level console driver and the
- * low-level frame buffer device
- */
-
-struct display {
- /* Filled in by the frame buffer device */
-
- struct fb_var_screeninfo var; /* variable infos. yoffset and vmode */
- /* are updated by fbcon.c */
- struct fb_cmap cmap; /* colormap */
- u_short can_soft_blank; /* zero if no hardware blanking */
- u_short inverse; /* != 0 text black on white as default */
- struct display_switch *dispsw; /* low level operations */
- void *dispsw_data; /* optional dispsw helper data */
-
-#if 0
- struct fb_fix_cursorinfo fcrsr;
- struct fb_var_cursorinfo *vcrsr;
- struct fb_cursorstate crsrstate;
-#endif
-
- /* Filled in by the low-level console driver */
- struct vc_data *conp; /* pointer to console data */
- struct fb_info *fb_info; /* frame buffer for this console */
- int vrows; /* number of virtual rows */
- unsigned short cursor_x; /* current cursor position */
- unsigned short cursor_y;
- int fgcol; /* text colors */
- int bgcol;
- u_long next_line; /* offset to one line below */
- u_long next_plane; /* offset to next plane */
- u_char *fontdata; /* Font associated to this display */
- unsigned short _fontheightlog;
- unsigned short _fontwidthlog;
- unsigned short _fontheight;
- unsigned short _fontwidth;
- int userfont; /* != 0 if fontdata kmalloc()ed */
- u_short scrollmode; /* Scroll Method */
- short yscroll; /* Hardware scrolling */
- unsigned char fgshift, bgshift;
- unsigned short charmask; /* 0xff or 0x1ff */
-};
-
-/* drivers/video/fbcon.c */
-extern struct display fb_display[MAX_NR_CONSOLES];
-extern char con2fb_map[MAX_NR_CONSOLES];
-extern int PROC_CONSOLE(const struct fb_info *info);
-extern void set_con2fb_map(int unit, int newidx);
-extern int set_all_vcs(int fbidx, struct fb_ops *fb,
- struct fb_var_screeninfo *var, struct fb_info *info);
-
-#define fontheight(p) ((p)->_fontheight)
-#define fontheightlog(p) ((p)->_fontheightlog)
-
-#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)
-
-#define fontwidth(p) (8)
-#define fontwidthlog(p) (0)
-
-#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))
-
-#define fontwidth(p) ((p)->_fontwidth)
-#define fontwidthlog(p) ((p)->_fontwidthlog)
-
-#endif
-
- /*
- * Attribute Decoding
- */
-
-/* Color */
-#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) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
-#define attr_fgcol_ec(p,vc) \
- ((vc) ? (((vc)->vc_video_erase_char >> ((p)->fgshift)) & 0x0f) : 0)
-
-/* Monochrome */
-#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
- */
-
-/* Internal flags */
-#define __SCROLL_YPAN 0x001
-#define __SCROLL_YWRAP 0x002
-#define __SCROLL_YMOVE 0x003
-#define __SCROLL_YREDRAW 0x004
-#define __SCROLL_YMASK 0x00f
-#define __SCROLL_YFIXED 0x010
-#define __SCROLL_YNOMOVE 0x020
-#define __SCROLL_YPANREDRAW 0x040
-#define __SCROLL_YNOPARTIAL 0x080
-
-/* Only these should be used by the drivers */
-/* Which one should you use? If you have a fast card and slow bus,
- then probably just 0 to indicate fbcon should choose between
- YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
- and even better if your card can do fonting (1->8/32bit painting),
- you should consider either SCROLL_YREDRAW (if your card is
- able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
- The best is to test it with some real life scrolling (usually, not
- all lines on the screen are filled completely with non-space characters,
- and REDRAW performs much better on such lines, so don't cat a file
- with every line covering all screen columns, it would not be the right
- benchmark).
- */
-#define SCROLL_YREDRAW (__SCROLL_YFIXED|__SCROLL_YREDRAW)
-#define SCROLL_YNOMOVE (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
-
-/* SCROLL_YNOPARTIAL, used in combination with the above, is for video
- cards which can not handle using panning to scroll a portion of the
- screen without excessive flicker. Panning will only be used for
- whole screens.
- */
-/* Namespace consistency */
-#define SCROLL_YNOPARTIAL __SCROLL_YNOPARTIAL
-
-
-#if defined(__sparc__)
-
-/* We map all of our framebuffers such that big-endian accesses
- * are what we want, so the following is sufficient.
- */
-
-#define fb_readb sbus_readb
-#define fb_readw sbus_readw
-#define fb_readl sbus_readl
-#define fb_writeb sbus_writeb
-#define fb_writew sbus_writew
-#define fb_writel sbus_writel
-#define fb_memset sbus_memset_io
-
-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__)
-
-#define fb_readb __raw_readb
-#define fb_readw __raw_readw
-#define fb_readl __raw_readl
-#define fb_writeb __raw_writeb
-#define fb_writew __raw_writew
-#define fb_writel __raw_writel
-#define fb_memset memset_io
-
-#else
-
-#define fb_readb(addr) (*(volatile u8 *) (addr))
-#define fb_readw(addr) (*(volatile u16 *) (addr))
-#define fb_readl(addr) (*(volatile u32 *) (addr))
-#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
-#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
-#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
-#define fb_memset memset
-
-#endif
-
-
-extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
-extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
-
-
-/* ================================================================= */
-/* Utility Assembler Functions */
-/* ================================================================= */
-
-
-#if defined(__mc68000__)
-
-/* ====================================================================== */
-
-/* Those of a delicate disposition might like to skip the next couple of
- * pages.
- *
- * These functions are drop in replacements for memmove and
- * memset(_, 0, _). However their five instances add at least a kilobyte
- * to the object file. You have been warned.
- *
- * Not a great fan of assembler for the sake of it, but I think
- * that these routines are at least 10 times faster than their C
- * equivalents for large blits, and that's important to the lowest level of
- * a graphics driver. Question is whether some scheme with the blitter
- * would be faster. I suspect not for simple text system - not much
- * asynchrony.
- *
- * Code is very simple, just gruesome expansion. Basic strategy is to
- * increase data moved/cleared at each step to 16 bytes to reduce
- * instruction per data move overhead. movem might be faster still
- * For more than 15 bytes, we try to align the write direction on a
- * longword boundary to get maximum speed. This is even more gruesome.
- * Unaligned read/write used requires 68020+ - think this is a problem?
- *
- * Sorry!
- */
-
-
-/* ++roman: I've optimized Robert's original versions in some minor
- * aspects, e.g. moveq instead of movel, let gcc choose the registers,
- * use movem in some places...
- * For other modes than 1 plane, lots of more such assembler functions
- * were needed (e.g. the ones using movep or expanding color values).
- */
-
-/* ++andreas: more optimizations:
- subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
- addal is faster than addaw
- movep is rather expensive compared to ordinary move's
- some functions rewritten in C for clarity, no speed loss */
-
-static __inline__ void *fb_memclear_small(void *s, size_t count)
-{
- if (!count)
- return(0);
-
- __asm__ __volatile__(
- "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
- "1:"
- : "=a" (s), "=d" (count)
- : "d" (0), "0" ((char *)s+count), "1" (count)
- );
- __asm__ __volatile__(
- "subql #1,%1 ; jcs 3f\n\t"
- "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
- "2: moveml %2/%%d4/%%d5/%%d6,%0@-\n\t"
- "dbra %1,2b\n\t"
- "3:"
- : "=a" (s), "=d" (count)
- : "d" (0), "0" (s), "1" (count)
- : "d4", "d5", "d6"
- );
-
- return(0);
-}
-
-
-static __inline__ void *fb_memclear(void *s, size_t count)
-{
- if (!count)
- return(0);
-
- if (count < 16) {
- __asm__ __volatile__(
- "lsrl #1,%1 ; jcc 1f ; clrb %0@+\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; clrw %0@+\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t"
- "1:"
- : "=a" (s), "=d" (count)
- : "0" (s), "1" (count)
- );
- } else {
- long tmp;
- __asm__ __volatile__(
- "movel %1,%2\n\t"
- "lsrl #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
- "lsrl #1,%2 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
- "clrw %0@+ ; subqw #2,%1 ; jra 2f\n\t"
- "1: lsrl #1,%2 ; jcc 2f\n\t"
- "clrw %0@+ ; subqw #2,%1\n\t"
- "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
- "lsrl #1,%1 ; jcc 3f ; clrl %0@+\n\t"
- "3: lsrl #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
- "4: subql #1,%1 ; jcs 6f\n\t"
- "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
- "dbra %1,5b ; clrw %1; subql #1,%1; jcc 5b\n\t"
- "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
- "7: ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
- "8:"
- : "=a" (s), "=d" (count), "=d" (tmp)
- : "0" (s), "1" (count)
- );
- }
-
- return(0);
-}
-
-
-static __inline__ void *fb_memset255(void *s, size_t count)
-{
- if (!count)
- return(0);
-
- __asm__ __volatile__(
- "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
- "1:"
- : "=a" (s), "=d" (count)
- : "d" (-1), "0" ((char *)s+count), "1" (count)
- );
- __asm__ __volatile__(
- "subql #1,%1 ; jcs 3f\n\t"
- "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
- "2: moveml %2/%%d4/%%d5/%%d6,%0@-\n\t"
- "dbra %1,2b\n\t"
- "3:"
- : "=a" (s), "=d" (count)
- : "d" (-1), "0" (s), "1" (count)
- : "d4", "d5", "d6"
- );
-
- return(0);
-}
-
-
-static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
-{
- if (d < s) {
- if (count < 16) {
- __asm__ __volatile__(
- "lsrl #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t"
- "1: lsrl #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
- "1:"
- : "=a" (d), "=a" (s), "=d" (count)
- : "0" (d), "1" (s), "2" (count)
- );
- } else {
- long tmp;
- __asm__ __volatile__(
- "movel %0,%3\n\t"
- "lsrl #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
- "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
- "movew %1@+,%0@+ ; subqw #2,%2 ; jra 2f\n\t"
- "1: lsrl #1,%3 ; jcc 2f\n\t"
- "movew %1@+,%0@+ ; subqw #2,%2\n\t"
- "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
- "lsrl #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
- "3: lsrl #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
- "4: subql #1,%2 ; jcs 6f\n\t"
- "5: movel %1@+,%0@+;movel %1@+,%0@+\n\t"
- "movel %1@+,%0@+;movel %1@+,%0@+\n\t"
- "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
- "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
- "7: ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
- "8:"
- : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
- : "0" (d), "1" (s), "2" (count)
- );
- }
- } else {
- if (count < 16) {
- __asm__ __volatile__(
- "lsrl #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t"
- "1: lsrl #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
- "1:"
- : "=a" (d), "=a" (s), "=d" (count)
- : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
- );
- } else {
- long tmp;
- __asm__ __volatile__(
- "movel %0,%3\n\t"
- "lsrl #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
- "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
- "movew %1@-,%0@- ; subqw #2,%2 ; jra 2f\n\t"
- "1: lsrl #1,%3 ; jcc 2f\n\t"
- "movew %1@-,%0@- ; subqw #2,%2\n\t"
- "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
- "lsrl #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
- "3: lsrl #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
- "4: subql #1,%2 ; jcs 6f\n\t"
- "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
- "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
- "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
- "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
- "7: ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
- "8:"
- : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
- : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
- );
- }
- }
-
- return(0);
-}
-
-
-/* ++andreas: Simple and fast version of memmove, assumes size is
- divisible by 16, suitable for moving the whole screen bitplane */
-static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
-{
- if (!size)
- return;
- if (dst < src)
- __asm__ __volatile__
- ("1:"
- " moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
- " moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
- " addql #8,%1; addql #8,%1\n"
- " dbra %2,1b\n"
- " clrw %2; subql #1,%2\n"
- " jcc 1b"
- : "=a" (src), "=a" (dst), "=d" (size)
- : "0" (src), "1" (dst), "2" (size / 16 - 1)
- : "d0", "d1", "a0", "a1", "memory");
- else
- __asm__ __volatile__
- ("1:"
- " subql #8,%0; subql #8,%0\n"
- " moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
- " moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
- " dbra %2,1b\n"
- " clrw %2; subql #1,%2\n"
- " jcc 1b"
- : "=a" (src), "=a" (dst), "=d" (size)
- : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
- : "d0", "d1", "a0", "a1", "memory");
-}
-
-#elif defined(CONFIG_SUN4)
-
-/* You may think that I'm crazy and that I should use generic
- routines. No, I'm not: sun4's framebuffer crashes if we std
- into it, so we cannot use memset. */
-
-static __inline__ void *sun4_memset(void *s, char val, size_t count)
-{
- int i;
- for(i=0; i<count;i++)
- ((char *) s) [i] = val;
- return s;
-}
-
-static __inline__ void *fb_memset255(void *s, size_t count)
-{
- return sun4_memset(s, 255, count);
-}
-
-static __inline__ void *fb_memclear(void *s, size_t count)
-{
- return sun4_memset(s, 0, count);
-}
-
-static __inline__ void *fb_memclear_small(void *s, size_t count)
-{
- return sun4_memset(s, 0, count);
-}
-
-/* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */
-static __inline__ void fast_memmove(void *d, const void *s, size_t count)
-{
- int i;
- if (d<s) {
- for (i=0; i<count; i++)
- ((char *) d)[i] = ((char *) s)[i];
- } else
- for (i=0; i<count; i++)
- ((char *) d)[count-i-1] = ((char *) s)[count-i-1];
-}
-
-static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
-{
- fast_memmove(dst, src, size);
- return dst;
-}
-
-#else
-
-static __inline__ void *fb_memclear_small(void *s, size_t count)
-{
- char *xs = (char *) s;
-
- while (count--)
- fb_writeb(0, xs++);
-
- return s;
-}
-
-static __inline__ void *fb_memclear(void *s, size_t count)
-{
- unsigned long xs = (unsigned long) s;
-
- if (count < 8)
- goto rest;
-
- if (xs & 1) {
- fb_writeb(0, xs++);
- count--;
- }
- if (xs & 2) {
- fb_writew(0, xs);
- xs += 2;
- count -= 2;
- }
- while (count > 3) {
- fb_writel(0, xs);
- xs += 4;
- count -= 4;
- }
-rest:
- while (count--)
- fb_writeb(0, xs++);
-
- return s;
-}
-
-static __inline__ void *fb_memset255(void *s, size_t count)
-{
- unsigned long xs = (unsigned long) s;
-
- if (count < 8)
- goto rest;
-
- if (xs & 1) {
- fb_writeb(0xff, xs++);
- count--;
- }
- if (xs & 2) {
- fb_writew(0xffff, xs);
- xs += 2;
- count -= 2;
- }
- while (count > 3) {
- fb_writel(0xffffffff, xs);
- xs += 4;
- count -= 4;
- }
-rest:
- while (count--)
- fb_writeb(0xff, xs++);
-
- return s;
-}
-
-#if defined(__i386__)
-
-static __inline__ void fast_memmove(void *d, const void *s, size_t count)
-{
- int d0, d1, d2, d3;
- 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"
- : "=&c" (d0), "=&D" (d1), "=&S" (d2)
- :"0"(count),"1"((long)d),"2"((long)s)
- :"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\n\t"
- "cld"
- : "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3)
- :"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s)
- :"memory");
- }
-}
-
-static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
-{
- fast_memmove(dst, src, size);
- return dst;
-}
-
-#else /* !__i386__ */
-
- /*
- * Anyone who'd like to write asm functions for other CPUs?
- * (Why are these functions better than those from include/asm/string.h?)
- */
-
-static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
-{
- unsigned long dst, src;
-
- if (d < s) {
- dst = (unsigned long) d;
- src = (unsigned long) s;
-
- if ((count < 8) || ((dst ^ src) & 3))
- goto restup;
-
- if (dst & 1) {
- fb_writeb(fb_readb(src++), dst++);
- count--;
- }
- if (dst & 2) {
- fb_writew(fb_readw(src), dst);
- src += 2;
- dst += 2;
- count -= 2;
- }
- while (count > 3) {
- fb_writel(fb_readl(src), dst);
- src += 4;
- dst += 4;
- count -= 4;
- }
-
- restup:
- while (count--)
- fb_writeb(fb_readb(src++), dst++);
- } else {
- dst = (unsigned long) d + count;
- src = (unsigned long) s + count;
-
- if ((count < 8) || ((dst ^ src) & 3))
- goto restdown;
-
- if (dst & 1) {
- src--;
- dst--;
- count--;
- fb_writeb(fb_readb(src), dst);
- }
- if (dst & 2) {
- src -= 2;
- dst -= 2;
- count -= 2;
- fb_writew(fb_readw(src), dst);
- }
- while (count > 3) {
- src -= 4;
- dst -= 4;
- count -= 4;
- fb_writel(fb_readl(src), dst);
- }
-
- restdown:
- while (count--) {
- src--;
- dst--;
- fb_writeb(fb_readb(src), dst);
- }
- }
-
- return d;
-}
-
-static __inline__ void fast_memmove(char *d, const char *s, size_t count)
-{
- unsigned long dst, src;
-
- if (d < s) {
- dst = (unsigned long) d;
- src = (unsigned long) s;
-
- if ((count < 8) || ((dst ^ src) & 3))
- goto restup;
-
- if (dst & 1) {
- fb_writeb(fb_readb(src++), dst++);
- count--;
- }
- if (dst & 2) {
- fb_writew(fb_readw(src), dst);
- src += 2;
- dst += 2;
- count -= 2;
- }
- while (count > 3) {
- fb_writel(fb_readl(src), dst);
- src += 4;
- dst += 4;
- count -= 4;
- }
-
- restup:
- while (count--)
- fb_writeb(fb_readb(src++), dst++);
- } else {
- dst = (unsigned long) d + count;
- src = (unsigned long) s + count;
-
- if ((count < 8) || ((dst ^ src) & 3))
- goto restdown;
-
- if (dst & 1) {
- src--;
- dst--;
- count--;
- fb_writeb(fb_readb(src), dst);
- }
- if (dst & 2) {
- src -= 2;
- dst -= 2;
- count -= 2;
- fb_writew(fb_readw(src), dst);
- }
- while (count > 3) {
- src -= 4;
- dst -= 4;
- count -= 4;
- fb_writel(fb_readl(src), dst);
- }
-
- restdown:
- while (count--) {
- src--;
- dst--;
- fb_writeb(fb_readb(src), dst);
- }
- }
-}
-
-#endif /* !__i386__ */
-
-#endif /* !__mc68000__ */
-
-#endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/iga.h b/include/video/iga.h
index de9685c58f1a..5a48f16578f8 100644
--- a/drivers/video/iga.h
+++ b/include/video/iga.h
@@ -7,11 +7,6 @@
#ifndef _IGA1682_H
#define _IGA1682_H 1
-struct iga1682_info
-{
- unsigned int total_vram;
-};
-
#define IGA_ATTR_CTL 0x3C0
#define IGA_IDX_VGA_OVERSCAN 0x11
#define DAC_W_INDEX 0x03C8
diff --git a/include/video/neomagic.h b/include/video/neomagic.h
index e0b73849bf0a..eec28b762178 100644
--- a/include/video/neomagic.h
+++ b/include/video/neomagic.h
@@ -176,6 +176,7 @@ struct neofb_par {
int lcd_stretch;
int internal_display;
int external_display;
+ int libretto;
};
typedef struct {
diff --git a/drivers/video/radeon.h b/include/video/radeon.h
index 64a023033ca0..64a023033ca0 100644
--- a/drivers/video/radeon.h
+++ b/include/video/radeon.h
diff --git a/kernel/printk.c b/kernel/printk.c
index d7c4d22bf347..6a9ad3289cb1 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -560,6 +560,7 @@ void console_conditional_schedule(void)
schedule();
}
}
+EXPORT_SYMBOL(console_conditional_schedule);
void console_print(const char *s)
{