summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@maxwell.earthlink.net>2002-10-15 20:46:14 -0700
committerJames Simmons <jsimmons@maxwell.earthlink.net>2002-10-15 20:46:14 -0700
commit143b8e9d04987f7d776646280cd47b94aa8e4a16 (patch)
tree47ca083421db1f680d44605df071a9378e57a6ca
parent007376bde07f4ee495941eb32d9509cb413889fd (diff)
Cleaned up and moved all the graphics related code inf drivers/video and move the console display related stuff into lower directory called console.
-rw-r--r--Documentation/DocBook/kernel-api.tmpl4
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/config.in17
-rw-r--r--arch/arm/config.in10
-rw-r--r--arch/i386/config.in12
-rw-r--r--arch/ia64/config.in11
-rw-r--r--arch/m68k/config.in7
-rw-r--r--arch/mips/config.in11
-rw-r--r--arch/mips64/config.in15
-rw-r--r--arch/parisc/config.in19
-rw-r--r--arch/ppc/config.in7
-rw-r--r--arch/ppc64/config.in7
-rw-r--r--arch/sh/config.in13
-rw-r--r--arch/sparc/config.in7
-rw-r--r--arch/sparc64/config.in4
-rw-r--r--arch/x86_64/config.in12
-rw-r--r--drivers/Makefile3
-rw-r--r--drivers/video/Config.help123
-rw-r--r--drivers/video/Config.in145
-rw-r--r--drivers/video/Makefile41
-rw-r--r--drivers/video/aty128fb.c3165
-rw-r--r--drivers/video/cfbcopyarea.c104
-rw-r--r--drivers/video/cfbfillrect.c110
-rw-r--r--drivers/video/cfbimgblt.c331
-rw-r--r--drivers/video/console/Config.help149
-rw-r--r--drivers/video/console/Config.in162
-rw-r--r--drivers/video/console/Makefile49
-rw-r--r--drivers/video/console/dummycon.c (renamed from drivers/video/dummycon.c)0
-rw-r--r--drivers/video/console/fbcon-accel.c (renamed from drivers/video/fbcon-accel.c)0
-rw-r--r--drivers/video/console/fbcon-accel.h (renamed from drivers/video/fbcon-accel.h)0
-rw-r--r--drivers/video/console/fbcon-afb.c (renamed from drivers/video/fbcon-afb.c)0
-rw-r--r--drivers/video/console/fbcon-hga.c (renamed from drivers/video/fbcon-hga.c)0
-rw-r--r--drivers/video/console/fbcon-ilbm.c (renamed from drivers/video/fbcon-ilbm.c)0
-rw-r--r--drivers/video/console/fbcon-iplan2p2.c (renamed from drivers/video/fbcon-iplan2p2.c)0
-rw-r--r--drivers/video/console/fbcon-iplan2p4.c (renamed from drivers/video/fbcon-iplan2p4.c)0
-rw-r--r--drivers/video/console/fbcon-iplan2p8.c (renamed from drivers/video/fbcon-iplan2p8.c)0
-rw-r--r--drivers/video/console/fbcon-sti.c (renamed from drivers/video/fbcon-sti.c)0
-rw-r--r--drivers/video/console/fbcon-vga-planes.c (renamed from drivers/video/fbcon-vga-planes.c)0
-rw-r--r--drivers/video/console/fbcon.c (renamed from drivers/video/fbcon.c)28
-rw-r--r--drivers/video/console/font_6x11.c (renamed from drivers/video/font_6x11.c)0
-rw-r--r--drivers/video/console/font_8x16.c (renamed from drivers/video/font_8x16.c)0
-rw-r--r--drivers/video/console/font_8x8.c (renamed from drivers/video/font_8x8.c)0
-rw-r--r--drivers/video/console/font_acorn_8x8.c (renamed from drivers/video/font_acorn_8x8.c)0
-rw-r--r--drivers/video/console/font_mini_4x6.c (renamed from drivers/video/font_mini_4x6.c)0
-rw-r--r--drivers/video/console/font_pearl_8x8.c (renamed from drivers/video/font_pearl_8x8.c)0
-rw-r--r--drivers/video/console/font_sun12x22.c (renamed from drivers/video/font_sun12x22.c)0
-rw-r--r--drivers/video/console/font_sun8x16.c (renamed from drivers/video/font_sun8x16.c)0
-rw-r--r--drivers/video/console/fonts.c (renamed from drivers/video/fonts.c)0
-rw-r--r--drivers/video/console/mdacon.c (renamed from drivers/video/mdacon.c)0
-rw-r--r--drivers/video/console/newport_con.c (renamed from drivers/video/newport_con.c)0
-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)0
-rw-r--r--drivers/video/console/sti-bmode.h (renamed from drivers/video/sti-bmode.h)0
-rw-r--r--drivers/video/console/sticon-bmode.c (renamed from drivers/video/sticon-bmode.c)0
-rw-r--r--drivers/video/console/sticon.c (renamed from drivers/video/sticon.c)0
-rw-r--r--drivers/video/console/vgacon.c (renamed from drivers/video/vgacon.c)0
-rw-r--r--drivers/video/fbcmap.c57
-rw-r--r--drivers/video/fbgen.c45
-rw-r--r--drivers/video/fbmem.c7
-rw-r--r--drivers/video/neofb.c2
-rw-r--r--drivers/video/sgivwfb.c1
-rw-r--r--drivers/video/sis/sis_accel.c495
-rw-r--r--include/linux/fb.h25
-rw-r--r--include/linux/sisfb.h58
64 files changed, 2883 insertions, 2375 deletions
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/Makefile b/Makefile
index b3df7fb5a849..99e91d6415fb 100644
--- a/Makefile
+++ b/Makefile
@@ -668,7 +668,7 @@ defconfig:
CLEAN_FILES += \
include/linux/compile.h \
vmlinux System.map \
- drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
+ drivers/char/consolemap_deftbl.c drivers/video/console/promcon_tbl.c \
drivers/char/conmakehash \
drivers/char/drm/*-mod.c \
drivers/char/defkeymap.c drivers/char/qtronixmap.c \
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index dc851ada6963..c4f6d381d15e 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -348,22 +348,7 @@ source drivers/media/Config.in
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- bool 'VGA text console' CONFIG_VGA_CONSOLE
-# 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/Config.in
- if [ "$CONFIG_FB" = "y" ]; then
- define_bool CONFIG_PCI_CONSOLE y
- fi
- endmenu
-fi
+source drivers/video/Config.in
mainmenu_option next_comment
comment 'Sound'
diff --git a/arch/arm/config.in b/arch/arm/config.in
index 9e6605c5a4e4..e9f7e1c2f39b 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -498,15 +498,7 @@ source drivers/media/Config.in
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
- bool 'VGA text console' CONFIG_VGA_CONSOLE
- fi
- source drivers/video/Config.in
- endmenu
-fi
+source drivers/video/Config.in
if [ "$CONFIG_ARCH_ACORN" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 784e35d23bce..941d04a0da6b 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -417,17 +417,7 @@ source drivers/media/Config.in
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- bool 'VGA text console' CONFIG_VGA_CONSOLE
- bool 'Video mode selection support' CONFIG_VIDEO_SELECT
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
- source drivers/video/Config.in
- fi
- endmenu
-fi
+source drivers/video/Config.in
mainmenu_option next_comment
comment 'Sound'
diff --git a/arch/ia64/config.in b/arch/ia64/config.in
index c2e6fdf686fd..9147f72fbf74 100644
--- a/arch/ia64/config.in
+++ b/arch/ia64/config.in
@@ -229,16 +229,7 @@ fi # HP_SIM
source fs/Config.in
if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
- if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- bool 'VGA text console' CONFIG_VGA_CONSOLE
- source drivers/video/Config.in
- if [ "$CONFIG_FB" = "y" ]; then
- define_bool CONFIG_PCI_CONSOLE y
- fi
- endmenu
- fi
+ source drivers/video/Config.in
mainmenu_option next_comment
comment 'Sound'
diff --git a/arch/m68k/config.in b/arch/m68k/config.in
index 436e3a3986a9..9dc1eec61bac 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -527,12 +527,7 @@ endmenu
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- source drivers/video/Config.in
- endmenu
-fi
+source drivers/video/Config.in
mainmenu_option next_comment
comment 'Kernel hacking'
diff --git a/arch/mips/config.in b/arch/mips/config.in
index f48cfd6ae206..f7319fdfdbd5 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -449,16 +449,7 @@ fi
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- bool 'VGA text console' CONFIG_VGA_CONSOLE
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
- source drivers/video/Config.in
- fi
- endmenu
-fi
+source drivers/video/Config.in
if [ "$CONFIG_DECSTATION" != "y" ]; then
mainmenu_option next_comment
diff --git a/arch/mips64/config.in b/arch/mips64/config.in
index f60cccdea4be..9851d55ee8c0 100644
--- a/arch/mips64/config.in
+++ b/arch/mips64/config.in
@@ -199,20 +199,7 @@ source drivers/media/Config.in
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- source drivers/video/Config.in
- if [ "$CONFIG_SGI_IP22" = "y" ]; then
- tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
- if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
- define_bool CONFIG_DUMMY_CONSOLE y
- else
- define_bool CONFIG_FONT_8x16 y
- fi
- fi
- endmenu
-fi
+source drivers/video/Config.in
if [ "$CONFIG_PROC_FS" = "y" ]; then
define_bool CONFIG_KCORE_ELF y
diff --git a/arch/parisc/config.in b/arch/parisc/config.in
index 990b739f6d80..2ec98ccce0af 100644
--- a/arch/parisc/config.in
+++ b/arch/parisc/config.in
@@ -168,24 +168,7 @@ if [ "$CONFIG_SOUND" != "n" ]; then
fi
endmenu
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- source drivers/video/Config.in
-
-# bool 'IODC console' CONFIG_IODC_CONSOLE
- bool 'STI console' CONFIG_STI_CONSOLE
- if [ "$CONFIG_IODC_CONSOLE" = "n" ]; then
- if [ "$CONFIG_GSC_PS2" = "y" ]; then
- define_bool CONFIG_DUMMY_CONSOLE y
- fi
- fi
- if [ "$CONFIG_STI_CONSOLE" = "y" ]; then
- define_bool CONFIG_DUMMY_CONSOLE y
- fi
- endmenu
-fi
-# endmenu
+source drivers/video/Config.in
mainmenu_option next_comment
comment 'Kernel hacking'
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 84f098ad2753..bb2c92f7b17e 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -459,14 +459,7 @@ source net/irda/Config.in
source drivers/isdn/Config.in
-mainmenu_option next_comment
-comment 'Console drivers'
-if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
- bool 'VGA text console' CONFIG_VGA_CONSOLE
-fi
source drivers/video/Config.in
-endmenu
-
if [ "$CONFIG_PPC_ISERIES" = "y" ]; then
mainmenu_option next_comment
diff --git a/arch/ppc64/config.in b/arch/ppc64/config.in
index ec1e5539b0ff..bd8c78c88421 100644
--- a/arch/ppc64/config.in
+++ b/arch/ppc64/config.in
@@ -151,12 +151,7 @@ source drivers/media/Config.in
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- source drivers/video/Config.in
- endmenu
-fi
+source drivers/video/Config.in
mainmenu_option next_comment
comment 'Sound'
diff --git a/arch/sh/config.in b/arch/sh/config.in
index 54640eb6172c..0603186fbc39 100644
--- a/arch/sh/config.in
+++ b/arch/sh/config.in
@@ -336,18 +336,7 @@ source fs/Config.in
source drivers/media/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- bool 'VGA text console' CONFIG_VGA_CONSOLE
- bool 'Video mode selection support' CONFIG_VIDEO_SELECT
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
- source drivers/video/Config.in
- fi
- endmenu
-fi
-
+source drivers/video/Config.in
mainmenu_option next_comment
comment 'Sound'
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index e93547ad28f3..83c207b989e8 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -60,14 +60,7 @@ source drivers/parport/Config.in
dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
endmenu
-mainmenu_option next_comment
-comment 'Console drivers'
-bool 'PROM console' CONFIG_PROM_CONSOLE
-if [ "$CONFIG_PROM_CONSOLE" != "y" ]; then
- define_bool CONFIG_DUMMY_CONSOLE y
-fi
source drivers/video/Config.in
-endmenu
source drivers/mtd/Config.in
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index 537b7d099c94..848e2f7eb6a8 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -74,11 +74,7 @@ if [ "$CONFIG_PCI" = "y" ]; then
fi
endmenu
-mainmenu_option next_comment
-comment 'Console drivers'
-bool 'PROM console' CONFIG_PROM_CONSOLE
source drivers/video/Config.in
-endmenu
source drivers/serial/Config.in
source drivers/sbus/char/Config.in
diff --git a/arch/x86_64/config.in b/arch/x86_64/config.in
index 6c41e4e22b1d..04395edd04ca 100644
--- a/arch/x86_64/config.in
+++ b/arch/x86_64/config.in
@@ -188,17 +188,7 @@ source drivers/media/Config.in
source fs/Config.in
-if [ "$CONFIG_VT" = "y" ]; then
- mainmenu_option next_comment
- comment 'Console drivers'
- bool 'VGA text console' CONFIG_VGA_CONSOLE
- bool 'Video mode selection support' CONFIG_VIDEO_SELECT
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
- source drivers/video/Config.in
- fi
- endmenu
-fi
+source drivers/video/Config.in
mainmenu_option next_comment
comment 'Sound'
diff --git a/drivers/Makefile b/drivers/Makefile
index 958ecc4df984..560d819124a8 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -17,7 +17,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/
@@ -27,7 +27,6 @@ obj-$(CONFIG_ALL_PPC) += macintosh/
obj-$(CONFIG_MAC) += macintosh/
obj-$(CONFIG_PNP) += pnp/
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/video/Config.help b/drivers/video/Config.help
index ee952117f677..d508d1f1c7d3 100644
--- a/drivers/video/Config.help
+++ b/drivers/video/Config.help
@@ -1,19 +1,6 @@
CONFIG_FB_SGIVW
SGI Visual Workstation support for framebuffer graphics.
-CONFIG_VIDEO_SELECT
- 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_FB
The frame buffer device provides an abstraction for the graphics
hardware. It represents the frame buffer of some video hardware and
@@ -242,14 +229,6 @@ CONFIG_FB_VESA
You will get a boot time penguin logo at no additional cost. Please
read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
-CONFIG_FBCON_VGA_PLANES
- 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_FB_VGA16
This is the frame buffer device driver for VGA 16 color graphic
cards. Say Y if you have such a card.
@@ -280,58 +259,6 @@ CONFIG_FB_STI
Really old HP boxes may not have STI, and must use the PDC BIOS
console or the IODC BIOS.
-CONFIG_FBCON_FONTS
- 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_FONT_8x16
- 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_FBCON_FONTWIDTH8_ONLY
- Answer Y here will make the kernel provide only the 8x8 fonts (these
- are the less readable).
-
- If unsure, say N.
-
-CONFIG_FONT_SUN8x16
- This is the high resolution console font for Sun machines. Say Y.
-
-CONFIG_FONT_SUN12x22
- 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_FONT_8x8
- 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_6x11
- Small console font with Macintosh-style high-half glyphs. Some Mac
- framebuffer drivers don't support this one at all.
-
-CONFIG_FONT_PEARL_8x8
- Small console font with PC-style control-character and high-half
- glyphs.
-
-CONFIG_FONT_ACORN_8x8
- Small console font with PC-style control characters and high-half
- glyphs.
-
CONFIG_FB_HGA
Say Y here if you have a Hercules mono graphics card.
@@ -646,53 +573,3 @@ CONFIG_FB_SA1100
If you plan to use the LCD display with your SA-1100 system, say
Y here.
-CONFIG_FBCON_ADVANCED
- 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
- This is the low level frame buffer console driver for monochrome
- (2 colors) packed pixels.
-
-CONFIG_FBCON_AFB
- This is the low level frame buffer console driver for 1 to 8
- bitplanes (2 to 256 colors) on Amiga.
-
-CONFIG_FBCON_ILBM
- This is the low level frame buffer console driver for 1 to 8
- interleaved bitplanes (2 to 256 colors) on Amiga.
-
-CONFIG_FBCON_IPLAN2P2
- This is the low level frame buffer console driver for 2 interleaved
- bitplanes (4 colors) on Atari.
-
-CONFIG_FBCON_IPLAN2P4
- This is the low level frame buffer console driver for 4 interleaved
- bitplanes (16 colors) on Atari.
-
-CONFIG_FBCON_IPLAN2P8
- This is the low level frame buffer console driver for 8 interleaved
- bitplanes (256 colors) on Atari.
-
-CONFIG_FBCON_HGA
- This is the low level frame buffer console driver for Hercules mono
- graphics cards.
-
diff --git a/drivers/video/Config.in b/drivers/video/Config.in
index 534f8c9ef4e5..0e1c8808c985 100644
--- a/drivers/video/Config.in
+++ b/drivers/video/Config.in
@@ -3,12 +3,11 @@
#
mainmenu_option next_comment
-comment 'Frame-buffer support'
+comment 'Graphics support'
bool 'Support for frame buffer devices ' CONFIG_FB
if [ "$CONFIG_FB" = "y" ]; then
- define_bool CONFIG_DUMMY_CONSOLE y
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then
tristate ' Cirrus Logic support (EXPERIMENTAL)' CONFIG_FB_CLGEN
@@ -78,7 +77,7 @@ if [ "$CONFIG_FB" = "y" ]; then
bool ' Chips 65550 display support' CONFIG_FB_CT65550
bool ' IMS Twin Turbo display support' CONFIG_FB_IMSTT
bool ' S3 Trio display support' CONFIG_FB_S3TRIO
- tristate ' VGA 16-color graphics console' CONFIG_FB_VGA16
+ tristate ' VGA 16-color graphics support' CONFIG_FB_VGA16
fi
if [ "$CONFIG_PARISC" = "y" ]; then
bool ' Generic STI frame buffer device support' CONFIG_FB_STI
@@ -95,9 +94,9 @@ if [ "$CONFIG_FB" = "y" ]; then
tristate ' TGA framebuffer support' CONFIG_FB_TGA
fi
if [ "$CONFIG_X86" = "y" ]; then
- bool ' VESA VGA graphics console' CONFIG_FB_VESA
- tristate ' VGA 16-color graphics console' CONFIG_FB_VGA16
- tristate ' Hercules mono graphics console ' CONFIG_FB_HGA
+ bool ' VESA VGA graphics support' CONFIG_FB_VESA
+ tristate ' VGA 16-color graphics support' CONFIG_FB_VGA16
+ tristate ' Hercules mono graphics support ' CONFIG_FB_HGA
define_bool CONFIG_VIDEO_SELECT y
fi
if [ "$CONFIG_VISWS" = "y" ]; then
@@ -214,138 +213,8 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL
fi
-
- bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED
- if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
- tristate ' Monochrome support' CONFIG_FBCON_MFB
- tristate ' 24 bpp packed pixels support' CONFIG_FBCON_CFB24
- tristate ' Hardware acceleration support' CONFIG_FBCON_ACCEL
- tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB
- tristate ' Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
- tristate ' Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
- tristate ' Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4
- tristate ' Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
-# tristate ' Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16
- tristate ' VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES
- tristate ' HGA monochrome support ' CONFIG_FBCON_HGA
- else
- if [ "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
- "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
- "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
- "$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_RADEON" = "y" ]; then
- define_tristate CONFIG_FBCON_CFB24 y
- else
- if [ "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
- "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
- "$CONFIG_FB_ATY128" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
- "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_PVR2" = "m" ]; then
- define_tristate CONFIG_FBCON_CFB24 m
- fi
- fi
- if [ "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
- "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_HIT" = "y" -o \
- "$CONFIG_FB_HP300" = "y" -o "$CONFIG_FB_Q40" = "y" -o \
- "$CONFIG_FB_ANAKIN" = "y" -o "$CONFIG_FB_G364" = "y" -o \
- "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_CLPS711X" = "y" -o \
- "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
- "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
- "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
- "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
- "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_OF" = "y" -o \
- "$CONFIG_FB_SGIVW" = "y" ]; then
- define_tristate CONFIG_FBCON_ACCEL y
- else
- if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
- "$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
- "$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
- "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
- "$CONFIG_FB_ATY" = "m" ]; then
- define_tristate CONFIG_FBCON_ACCEL m
- fi
- fi
- if [ "$CONFIG_FB_AMIGA" = "y" ]; then
- define_tristate CONFIG_FBCON_AFB y
- define_tristate CONFIG_FBCON_ILBM y
- else
- if [ "$CONFIG_FB_AMIGA" = "m" ]; then
- define_tristate CONFIG_FBCON_AFB m
- define_tristate CONFIG_FBCON_ILBM m
- fi
- fi
- if [ "$CONFIG_FB_ATARI" = "y" ]; then
- define_tristate CONFIG_FBCON_IPLAN2P2 y
- define_tristate CONFIG_FBCON_IPLAN2P4 y
- define_tristate CONFIG_FBCON_IPLAN2P8 y
- else
- if [ "$CONFIG_FB_ATARI" = "m" ]; then
- define_tristate CONFIG_FBCON_IPLAN2P2 m
- define_tristate CONFIG_FBCON_IPLAN2P4 m
- define_tristate CONFIG_FBCON_IPLAN2P8 m
- fi
- fi
- if [ "$CONFIG_FB_VGA16" = "y" ]; then
- define_tristate CONFIG_FBCON_VGA_PLANES y
- else
- if [ "$CONFIG_FB_VGA16" = "m" ]; then
- define_tristate CONFIG_FBCON_VGA_PLANES m
- fi
- fi
- if [ "$CONFIG_FB_HGA" = "y" ]; then
- define_tristate CONFIG_FBCON_HGA y
- else
- if [ "$CONFIG_FB_HGA" = "m" ]; then
- define_tristate CONFIG_FBCON_HGA m
- fi
- fi
- if [ "$CONFIG_FB_STI" = "y" ]; then
- define_tristate CONFIG_FBCON_STI y
- fi
- fi
- bool ' Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY
- if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
- bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16
- if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
- bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22
- fi
- bool ' Select other fonts' CONFIG_FBCON_FONTS
- if [ "$CONFIG_FBCON_FONTS" = "y" ]; then
- bool ' VGA 8x8 font' CONFIG_FONT_8x8
- bool ' VGA 8x16 font' CONFIG_FONT_8x16
- if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
- bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
- fi
- bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
- bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
- fi
- else
- bool ' Select compiled-in fonts' CONFIG_FBCON_FONTS
- if [ "$CONFIG_FBCON_FONTS" = "y" ]; then
- bool ' VGA 8x8 font' CONFIG_FONT_8x8
- bool ' VGA 8x16 font' CONFIG_FONT_8x16
- bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16
- if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
- bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22
- bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
- fi
- bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
- bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
- bool ' Mini 4x6 font' CONFIG_FONT_MINI_4x6
- else
- define_bool CONFIG_FONT_8x8 y
- define_bool CONFIG_FONT_8x16 y
- if [ "$CONFIG_MAC" = "y" ]; then
- if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
- define_bool CONFIG_FONT_6x11 y
- fi
- fi
- if [ "$CONFIG_AMIGA" = "y" ]; then
- define_bool CONFIG_FONT_PEARL_8x8 y
- fi
- if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then
- define_bool CONFIG_FONT_ACORN_8x8 y
- fi
- fi
- fi
fi
+source drivers/video/console/Config.in
+
endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 3cddbde0ff50..0f8739db41f4 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -5,31 +5,12 @@
# 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 fbgen.o \
- fbcon-afb.o fbcon-ilbm.o fbcon-accel.o cyber2000fb.o \
- fbcon-iplan2p2.o fbcon-iplan2p4.o fbcon-iplan2p8.o \
- fbcon-vga-planes.o fbcon-vga8-planes.o fbcon-hga.o
+export-objs := fbmem.o fbcmap.o fbmon.o modedb.o fbgen.o cyber2000fb.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
-
# 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 fbgen.o
# Only include macmodes.o if we have FB support and are PPC
ifeq ($(CONFIG_FB),y)
obj-$(CONFIG_PPC) += macmodes.o
@@ -86,7 +67,7 @@ obj-$(CONFIG_FB_TX3912) += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbi
obj-$(CONFIG_FB_MATROX) += matrox/
obj-$(CONFIG_FB_RIVA) += riva/
-obj-$(CONFIG_FB_SIS) += sis/
+obj-$(CONFIG_FB_SIS) += sis/ cfbimgblt.o
obj-$(CONFIG_FB_ATY) += aty/ cfbimgblt.o
obj-$(CONFIG_FB_SUN3) += sun3fb.o
@@ -99,21 +80,7 @@ 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_ILBM) += fbcon-ilbm.o
-obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
-obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o
-obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o
-obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
-obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
-obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
+obj-$(CONFIG_VT) += console/
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/aty128fb.c b/drivers/video/aty128fb.c
index ae43cc8ea62e..921adccb4c6f 100644
--- a/drivers/video/aty128fb.c
+++ b/drivers/video/aty128fb.c
@@ -7,13 +7,23 @@
* 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)
+ *
* 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 +59,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>
@@ -92,27 +102,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) */
@@ -133,9 +143,9 @@ static struct fb_videomode defaultmode __initdata = {
/* struct to hold chip description information */
struct aty128_chip_info {
- const char *name;
- unsigned short device;
- int chip_gen;
+ const char *name;
+ unsigned short device;
+ int chip_gen;
};
/* Chip generations */
@@ -148,16 +158,17 @@ enum {
/* 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}
+ {"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},
+ {"Rage128 Pro TF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_U1, 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}
};
/* packed BIOS settings */
@@ -190,28 +201,38 @@ 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" };
+ { 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 const char *aty128fb_name = "ATY Rage128";
static char fontname[40] __initdata = { 0 };
@@ -222,99 +243,105 @@ 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;
+ 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_PCI
- struct pci_dev *pdev;
+ struct pci_dev *pdev;
#endif
#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) */
+ 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
+ unsigned char red[64]; /* see comments in aty128fb_setcolreg */
+ unsigned char green[64];
+ unsigned char blue[64];
+};
+
+struct fb_info_aty128 {
+ struct fb_info fb_info;
+ struct display disp;
+ struct aty128fb_par par;
+ u32 pseudo_palette[17];
+ struct fb_info_aty128 *next;
};
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)
/*
@@ -323,19 +350,16 @@ static struct fb_info_aty128 *board_list = NULL;
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,
struct fb_info *fb);
static int aty128fb_blank(int blank, struct fb_info *fb);
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info);
static int aty128fb_rasterimg(struct fb_info *info, int start);
/*
@@ -343,88 +367,52 @@ static int aty128fb_rasterimg(struct fb_info *info, int start);
*/
int aty128fb_init(void);
-static int aty128fbcon_switch(int con, struct fb_info *fb);
/*
* 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);
+ struct aty128fb_par *par);
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);
#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_set_var = gen_set_var,
+ .fb_check_var = aty128fb_check_var,
+ .fb_set_par = aty128fb_set_par,
+ .fb_get_cmap = gen_get_cmap,
+ .fb_set_cmap = gen_set_cmap,
+ .fb_setcolreg = aty128fb_setcolreg,
+ .fb_pan_display = aty128fb_pan_display,
+ .fb_blank = aty128fb_blank,
+ .fb_ioctl = aty128fb_ioctl,
+#if 0
+ .fb_fillrect = aty128fb_fillrect,
+ .fb_copyarea = aty128fb_copyarea,
+ .fb_imageblit = aty128fb_imageblit,
+ .fb_rasterimg = aty128fb_rasterimg,
+#else
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+#endif
};
#ifdef CONFIG_PMAC_BACKLIGHT
@@ -443,1345 +431,1194 @@ 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;
-
- wait_for_idle(info);
-
- /* 3D scaler not spoken here */
- wait_for_fifo(1, info);
- aty_st_le32(SCALE_3D_CNTL, 0x00000000);
+ u32 pitch_value;
- aty128_reset_engine(info);
+ wait_for_idle(par);
- pitch_value = par->crtc.pitch;
- if (par->crtc.bpp == 24) {
- pitch_value = pitch_value * 3;
- }
+ /* 3D scaler not spoken here */
+ wait_for_fifo(1, par);
+ aty_st_le32(SCALE_3D_CNTL, 0x00000000);
- 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_pll(struct aty128_pll *pll, const struct fb_info_aty128 *info)
+aty128_set_lcd_enable(struct aty128fb_par *par, int on)
{
- u32 div3;
+ u32 reg;
- unsigned char post_conv[] = /* register values for post dividers */
+ 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 aty128fb_par *par)
+{
+ u32 div3;
+
+ 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)
+aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- 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)
-{
- 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
- */
-static int
-aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *fb)
-{
- const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- struct aty128fb_par par;
-
- if (con == -1)
- par = info->default_par;
- else
- aty128_decode_var(&fb_display[con].var, &par, info);
-
- aty128_encode_fix(fix, &par, info);
-
- return 0;
-}
-
-
- /*
- * Pan or Wrap the Display
- *
- * Not supported (yet!)
- */
+/*
+ * Pan or Wrap the Display
+ */
static int
aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb)
+ 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;
+ struct aty128fb_par *par = fb->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;
+ 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;
+ xoffset = (var->xoffset +7) & ~7;
+ yoffset = var->yoffset;
- if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
- return -EINVAL;
+ if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
+ return -EINVAL;
- par->crtc.xoffset = xoffset;
- par->crtc.yoffset = yoffset;
+ par->crtc.xoffset = xoffset;
+ par->crtc.yoffset = yoffset;
- offset = ((yoffset * par->crtc.vxres + xoffset) * par->crtc.bpp) >> 6;
+ offset = ((yoffset * par->crtc.vxres + xoffset)*(par->crtc.bpp >> 3)) & ~7;
- aty_st_le32(CRTC_OFFSET, offset);
+ if (par->crtc.bpp == 24)
+ offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */
- return 0;
+ aty_st_le32(CRTC_OFFSET, offset);
+
+ 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)
{
- struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;
+ struct aty128fb_par *par = info->par;
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
+ if (par->blitter_may_be_busy)
+ wait_for_idle(par);
- return 0;
+ 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;
+ 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;
- }
+ 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;
+#ifdef CONFIG_PMAC_PBOOK
+ } else 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;
- }
+ else 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 */
+ 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_ALL_PPC */
+ else
+ mode_option = this_opt;
+ }
+ return 0;
}
- /*
- * Initialisation
- */
+/*
+ * Initialisation
+ */
static int __init
-aty128_init(struct fb_info_aty128 *info, const char *name)
+aty128_init(struct fb_info *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;
- }
+ struct aty128fb_par *par = info->par;
+ struct fb_var_screeninfo var;
+ u32 dac;
+ u8 chip_rev;
+ const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
+ const char *video_card;
- if (noaccel)
- var.accel_flags &= ~FB_ACCELF_TEXT;
- else
- var.accel_flags |= FB_ACCELF_TEXT;
+ if (!par->vram_size) /* may have already been probed */
+ par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
- if (aty128_decode_var(&var, &info->default_par, info)) {
- printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
- return 0;
- }
+ /* Get the chip revision */
+ chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
- /* 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];
- }
+ /* put a name with the face */
+ while (aci->name && par->pdev->device != aci->device)
+ aci++;
+ video_card = aci->name? aci->name: "Rage128";
+ par->chip_gen = aci->chip_gen;
- /* 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);
+ printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
- /* turn off bus mastering, just in case */
- aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
+ 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);
+
+ /* fill in info */
+ strcpy(info->modename, aty128fb_name);
+ info->node = NODEV;
+ info->fbops = &aty128fb_ops;
+ 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_PBOOK
+ par->lcd_on = default_lcd_on;
+ par->crt_on = default_crt_on;
+#endif
- aty128fb_set_var(&var, -1, &info->fb_info);
- aty128_init_engine(&info->default_par, info);
+ 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;
- board_list = aty128_board_list_add(board_list, info);
+ 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;
+ }
- size = (var.bits_per_pixel <= 8) ? 256 : 32;
- fb_alloc_cmap(&info->fb_info.cmap, size, 0);
+ if (noaccel)
+ var.accel_flags &= ~FB_ACCELF_TEXT;
+ else
+ var.accel_flags |= FB_ACCELF_TEXT;
- if (register_framebuffer(&info->fb_info) < 0)
- return 0;
+ if (aty128fb_check_var(&var, info)) {
+ printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
+ return 0;
+ }
-#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 */
+ /* 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);
- printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
- GET_FB_IDX(info->fb_info.node), aty128fb_name, name);
+ /* turn off bus mastering, just in case */
+ aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
- return 1; /* success! */
-}
+ info->var = var;
+ fb_alloc_cmap(&info->cmap, 256, 0);
+ gen_set_disp(-1, info);
+ var.activate = FB_ACTIVATE_NOW;
+ gen_set_var(&var, -1, info);
-/* 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;
+ aty128_init_engine(par);
- 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;
+ if (register_framebuffer(info) < 0)
+ return 0;
- return board_list;
+#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
+ if (!par->pdev)
+ printk(KERN_WARNING "aty128fb: Not a PCI card, can't enable power management\n");
+ else {
+ par->pm_reg = pci_find_capability(par->pdev, PCI_CAP_ID_PM);
+ pmu_register_sleep_notifier(&aty128_sleep_notifier);
+ }
+#endif
+
+ printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
+ GET_FB_IDX(info->node), aty128fb_name, name);
+
+ return 1; /* success! */
}
@@ -1789,21 +1626,21 @@ 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++;
- }
+ 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++;
+ }
#endif
- return 0;
+ return 0;
}
@@ -1813,7 +1650,9 @@ static int __init
aty128_pci_register(struct pci_dev *pdev,
const struct aty128_chip_info *aci)
{
- struct fb_info_aty128 *info = NULL;
+ struct fb_info_aty128 *lump = NULL;
+ struct fb_info *info;
+ struct aty128fb_par *par;
unsigned long fb_addr, reg_addr;
int err;
#if !defined(CONFIG_PPC) && !defined(__sparc__)
@@ -1824,7 +1663,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,38 +1682,46 @@ aty128_pci_register(struct pci_dev *pdev,
}
/* We have the resources. Now virtualize them */
- if (!(info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC))) {
+ if (!(lump = kmalloc(sizeof(struct fb_info_aty128), 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(lump, 0, sizeof(struct fb_info_aty128));
+ info = &lump->fb_info;
+ par = &lump->par;
- /* Copy PCI device info into info->pdev */
- info->pdev = pdev;
+ info->par = par;
+ info->disp = &lump->disp;
+ info->fix = aty128fb_fix;
+ info->currcon = -1;
+ info->pseudo_palette = lump->pseudo_palette;
- info->fb_info.currcon = -1;
+ par->pdev = pdev;
/* Virtualize mmio region */
- info->regbase_phys = reg_addr;
- info->regbase = ioremap(reg_addr, 0x1FFF);
-
- if (!info->regbase)
+ 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;
}
@@ -1889,14 +1736,17 @@ aty128_pci_register(struct pci_dev *pdev,
aty128_get_pllinfo(info, bios_seg);
}
#endif
- aty128_timings(info);
+ aty128_timings(par);
if (!aty128_init(info, "PCI"))
goto err_out;
+ lump->next = board_list;
+ board_list = lump;
+
#ifdef CONFIG_MTRR
if (mtrr) {
- info->mtrr.vram = mtrr_add(info->frame_buffer_phys,
+ info->mtrr.vram = mtrr_add(info->fix.smem_start,
info->vram_size, MTRR_TYPE_WRCOMB, 1);
info->mtrr.vram_valid = 1;
/* let there be speed */
@@ -1906,10 +1756,10 @@ 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);
+ kfree(lump);
err_unmap_out:
release_mem_region(pci_resource_start(pdev, 2),
pci_resource_len(pdev, 2));
@@ -1926,8 +1776,7 @@ err_free_fb:
/* 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;
@@ -1985,7 +1834,7 @@ static char __init
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 +1854,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 +1871,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_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]));
+#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 */
- 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;
+ if (!par->constants.dotclock)
+ par->constants.dotclock = 2950;
- 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;
- }
-}
-
-
-static int
-aty128fbcon_switch(int con, struct fb_info *fb)
-{
- struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
- struct aty128fb_par par;
+#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;
- /* 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);
+ par->constants.xclk = round_div((2 * Nx * par->constants.dotclock),
+ (M * PostDivSet[xclk_cntl]));
- /* set the current console */
- fb->currcon = con;
-
- aty128_decode_var(&fb_display[con].var, &par, info);
- aty128_set_par(&par, info);
-
- 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, int con, 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 +2085,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 +2148,7 @@ aty128_set_backlight_level(int level, void* data)
}
#endif /* CONFIG_PMAC_BACKLIGHT */
+#if 0
/*
* Accelerated functions
*/
@@ -2301,39 +2156,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,200 +2212,128 @@ 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);
-}
-
-
-static void fbcon_aty24_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_cfb24_clear_margins(conp, p, bottom_only);
-}
-
-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);
-
- if (fb->blitter_may_be_busy)
- wait_for_idle(fb);
-
- fbcon_cfb32_putc(conp, p, c, yy, xx);
-}
-
-
-static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count,
- int yy, int xx)
-{
- 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);
+#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);
+ }
}
+extern struct display_switch fbcon_dummy;
-static void fbcon_aty32_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_cfb32_clear_margins(conp, p, 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 *board;
+ int result;
+
+ result = PBOOK_SLEEP_OK;
+
+ for (board = board_list; board != NULL; board = board->next) {
+ struct fb_info *info = &board->fb_info;
+ struct aty128fb_par *par = info->par;
+ int nb;
+
+ nb = info->var.yres * info->fix.line_length;
+
+ 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:
+ if (info->currcon >= 0)
+ fb_display[info->currcon].dispsw = &fbcon_dummy;
+
+ 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);
+
+ 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;
+ }
+ gen_set_disp(-1, info);
+ aty128fb_blank(0, info);
+ break;
+ }
+ }
+ return result;
}
-
-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
+#endif /* CONFIG_PMAC_PBOOK */
#ifdef MODULE
MODULE_AUTHOR("(c)1999-2000 Brad Douglas <brad@neruo.com>");
@@ -2570,55 +2353,55 @@ MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
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);
- }
+ 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");
- }
+ if (nomtrr) {
+ mtrr = 0;
+ printk(KERN_INFO "aty128fb: Parameter NOMTRR set\n");
+ }
#endif
-
- aty128fb_init();
- return 0;
+
+ aty128fb_init();
+ return 0;
}
void __exit
cleanup_module(void)
{
- struct fb_info_aty128 *info = board_list;
+ struct fb_info_aty128 *info = board_list;
- while (board_list) {
- info = board_list;
- board_list = board_list->next;
+ while (board_list) {
+ info = board_list;
+ board_list = board_list->next;
- unregister_framebuffer(&info->fb_info);
+ 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);
+ if (info->mtrr.vram_valid)
+ mtrr_del(info->mtrr.vram, info->fix.smem_start,
+ info->vram_size);
#endif /* CONFIG_MTRR */
- iounmap(info->regbase);
- iounmap(info->frame_buffer);
+ iounmap(info->par.regbase);
+ iounmap(info->fb_info.screen_base);
- 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));
+ release_mem_region(pci_resource_start(info->par.pdev, 0),
+ pci_resource_len(info->par.pdev, 0));
+ release_mem_region(pci_resource_start(info->par.pdev, 1),
+ pci_resource_len(info->par.pdev, 1));
+ release_mem_region(pci_resource_start(info->par.pdev, 2),
+ pci_resource_len(info->par.pdev, 2));
- kfree(info);
- }
+ kfree(info);
+ }
}
#endif /* MODULE */
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 07b47422410b..e3fcc679afb9 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -38,9 +38,11 @@
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 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, tmp;
+ unsigned long start_index, end_index, start_mask, end_mask, last,
+ tmp;
unsigned long *dst = NULL, *src = NULL;
char *src1, *dst1;
int height;
@@ -84,10 +86,16 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
lineincr = linesize;
} 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);
+ 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;
}
@@ -98,7 +106,7 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
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));
+ ((unsigned long) src1 & (bpl - 1));
start_mask = end_mask = 0;
if (start_index) {
@@ -111,7 +119,6 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
n -= end_index;
}
n /= bpl;
-
if (n <= 0) {
if (start_mask) {
if (end_mask)
@@ -148,16 +155,25 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
last = (FB_READ(src) & start_mask);
if (shift > 0)
- FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
+ 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);
+ FB_WRITE((last <<
+ shift_left) |
+ (tmp >>
+ shift_right),
+ dst);
last = tmp;
src++;
}
- FB_WRITE(FB_READ(dst) | (last << shift_left), dst);
+ FB_WRITE(FB_READ(dst) |
+ (last << shift_left),
+ dst);
src1 += lineincr;
dst1 += lineincr;
} while (--height);
@@ -172,16 +188,25 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
last = (FB_READ(src) & end_mask);
if (shift < 0)
- FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
+ 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);
+ FB_WRITE((tmp <<
+ shift_left) |
+ (last >>
+ shift_right),
+ dst);
last = tmp;
src--;
}
- FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
+ FB_WRITE(FB_READ(dst) |
+ (last >> shift_right),
+ dst);
src1 += lineincr;
dst1 += lineincr;
} while (--height);
@@ -191,20 +216,27 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
if (lineincr > 0) {
/* positive increment */
do {
- dst = (unsigned long *) (dst1 - start_index);
- src = (unsigned long *) (src1 - start_index);
+ dst =
+ (unsigned long *) (dst1 -
+ start_index);
+ src =
+ (unsigned long *) (src1 -
+ start_index);
if (start_mask)
- FB_WRITE(FB_READ(src) | start_mask, dst);
+ FB_WRITE(FB_READ(src) |
+ start_mask, dst);
for (j = 0; j < n; j++) {
- FB_WRITE(FB_READ(src), dst);
+ FB_WRITE(FB_READ(src),
+ dst);
dst++;
src++;
}
if (end_mask)
- FB_WRITE(FB_READ(src) | end_mask, dst);
+ FB_WRITE(FB_READ(src) |
+ end_mask, dst);
src1 += lineincr;
dst1 += lineincr;
} while (--height);
@@ -215,9 +247,11 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
src = (unsigned long *) src1;
if (start_mask)
- FB_WRITE(FB_READ(src) | start_mask, dst);
+ FB_WRITE(FB_READ(src) |
+ start_mask, dst);
for (j = 0; j < n; j++) {
- FB_WRITE(FB_READ(src), dst);
+ FB_WRITE(FB_READ(src),
+ dst);
dst--;
src--;
}
@@ -226,5 +260,33 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
} while (--height);
}
}
+ } else {
+ int n = ((area->width * p->var.bits_per_pixel) >> 3);
+ int n16 = (n >> 4) << 4;
+ int n_fract = n - n16;
+ int rows;
+
+ if (area->dy < area->sy
+ || (area->dy == area->sy && area->dx < area->sx)) {
+ for (rows = height; rows--;) {
+ if (n16)
+ fast_memmove(dst1, src1, n16);
+ if (n_fract)
+ fb_memmove(dst1 + n16, src1 + n16,
+ n_fract);
+ dst1 += linesize;
+ src1 += linesize;
+ }
+ } else {
+ for (rows = height; rows--;) {
+ if (n16)
+ fast_memmove(dst1, src1, n16);
+ if (n_fract)
+ fb_memmove(dst1 + n16, src1 + n16,
+ n_fract);
+ dst1 -= linesize;
+ src1 -= linesize;
+ }
+ }
}
}
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index b3ad462b7a27..8f42a317a1c4 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -35,7 +35,7 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
unsigned long height, ppw, fg, fgcolor;
int i, n, x2, y2, linesize = p->fix.line_length;
int bpl = sizeof(unsigned long);
- unsigned long *dst;
+ unsigned long *dst = NULL;
char *dst1;
if (!rect->width || !rect->height)
@@ -55,7 +55,7 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
ppw = BITS_PER_LONG / p->var.bits_per_pixel;
dst1 = p->screen_base + (rect->dy * linesize) +
- (rect->dx * (p->var.bits_per_pixel >> 3));
+ (rect->dx * (p->var.bits_per_pixel >> 3));
start_index = ((unsigned long) dst1 & (bpl - 1));
end_index = ((unsigned long) (dst1 + n) & (bpl - 1));
@@ -97,11 +97,12 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
case ROP_COPY:
do {
/* Word align to increases performace :-) */
- dst = (unsigned long *) (dst1 - start_index);
+ dst =
+ (unsigned long *) (dst1 - start_index);
if (start_mask) {
FB_WRITE(FB_READ(dst) |
- start_mask, dst);
+ start_mask, dst);
dst++;
}
@@ -112,17 +113,18 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
if (end_mask)
FB_WRITE(FB_READ(dst) | end_mask,
- dst);
+ dst);
dst1 += linesize;
} while (--height);
break;
case ROP_XOR:
do {
- dst = (unsigned long *) (dst1 - start_index);
+ dst =
+ (unsigned long *) (dst1 - start_index);
if (start_mask) {
FB_WRITE(FB_READ(dst) ^
- start_mask, dst);
+ start_mask, dst);
dst++;
}
@@ -133,56 +135,92 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
if (end_mask) {
FB_WRITE(FB_READ(dst) ^ end_mask,
- dst);
+ dst);
}
dst1 += linesize;
} while (--height);
break;
}
} 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;
+ /*
+ * Slow Method: The aim is to find the number of pixels to
+ * pack in order to write doubleword multiple data.
+ * For 24 bpp, 4 pixels are packed which are written as
+ * 3 dwords.
+ */
+ char *dst2, *dst3;
+ int bytes = (p->var.bits_per_pixel + 7) >> 3;
+ int read, write, total, pack_size;
+ u32 pixarray[BITS_PER_LONG >> 3], m;
+
+ fg = fgcolor;
+ read = (bytes + (bpl - 1)) & ~(bpl - 1);
+ write = bytes;
+ total = (rect->width * bytes);
+
+ pack_size = bpl * write;
+
+ dst3 = (char *) pixarray;
+
+ for (n = read; n--;) {
+ *(u32 *) dst3 = fg;
+ dst3 += bytes;
+ }
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;
+ dst2 = dst1;
+ n = total;
+
+ while (n >= pack_size) {
+ for (m = 0; m < write; m++) {
+ fb_writel(pixarray[m],
+ (u32 *) dst2);
+ dst2 += 4;
+ }
+ n -= pack_size;
+ }
+ if (n) {
+ m = 0;
+ while (n--)
+ fb_writeb(((u8 *)
+ pixarray)[m++],
+ dst2++);
}
- 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); */
+ dst2 = dst1;
+ n = total;
+
+ while (n >= pack_size) {
+ for (m = 0; m < write; m++) {
+ fb_writel(fb_readl
+ ((u32 *) dst2) ^
+ pixarray[m],
+ (u32 *) dst2);
+ dst2 += 4;
+ }
+ n -= pack_size;
+ }
+ if (n) {
+ m = 0;
+ while (n--) {
+ fb_writeb(fb_readb(dst2) ^
+ ((u8 *)
+ pixarray)[m++],
+ dst2);
+ dst2++;
+ }
}
- if (end_mask)
- *dst ^= end_mask;
dst1 += linesize;
} while (--height);
break;
}
+
}
return;
}
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index f522f900d66f..96018596ca8e 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -22,6 +22,13 @@
* 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.
@@ -39,16 +46,251 @@
#define DPRINTK(fmt, args...)
#endif
-void cfb_imageblit(struct fb_info *p, struct fb_image *image)
+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
+};
+
+static u32 cfb_pixarray[4];
+static u32 cfb_tabdef[2];
+
+
+static inline void fast_imageblit(struct fb_image *image,
+ struct fb_info *p, char *dst1,
+ int fgcolor, int bgcolor)
+{
+ int i, j, k, l = 8, n;
+ int bit_mask, end_mask, eorx;
+ unsigned long fgx = fgcolor, bgx = bgcolor, pad;
+ unsigned long tmp = ~0 << (BITS_PER_LONG - p->var.bits_per_pixel);
+ unsigned long ppw = BITS_PER_LONG / p->var.bits_per_pixel;
+ 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 <<= p->var.bits_per_pixel;
+ bgx <<= p->var.bits_per_pixel;
+ fgx |= fgcolor;
+ bgx |= bgcolor;
+ }
+
+ n = ((image->width + 7) >> 3);
+ pad = (n << 3) - 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;
+ for (j = n; j > 0; j--) {
+ l--;
+ if (test_bit(l, (unsigned long *) src))
+ end_mask |=
+ (tmp >>
+ (p->var.bits_per_pixel *
+ (j - 1)));
+ if (!l) {
+ l = 8;
+ src++;
+ }
+ }
+ fb_writel((end_mask & eorx) ^ bgx, dst++);
+ }
+ l -= pad;
+ dst1 += p->fix.line_length;
+ }
+}
+
+
+/*
+ * Slow method: The idea is to find the number of pixels necessary to form
+ * dword-sized multiples that will be written to the framebuffer. For BPP24,
+ * 4 pixels has to be read which are then packed into 3 double words that
+ * are then written to the framebuffer.
+ *
+ * With this method, processing is done 1 pixel at a time.
+ */
+static inline void slow_imageblit(struct fb_image *image,
+ struct fb_info *p, char *dst1,
+ int fgcolor, int bgcolor)
+{
+ int bytes = (p->var.bits_per_pixel + 7) >> 3;
+ int tmp = ~0UL >> (BITS_PER_LONG - p->var.bits_per_pixel);
+ int i, j, k, l = 8, m, end_mask, eorx;
+ int read, write, total, pack_size, bpl = sizeof(unsigned long);
+ unsigned long *dst;
+ char *dst2 = (char *) cfb_pixarray, *src = image->data;
+
+ cfb_tabdef[0] = 0;
+ cfb_tabdef[1] = tmp;
+
+ eorx = fgcolor ^ bgcolor;
+ read = (bytes + (bpl - 1)) & ~(bpl - 1);
+ write = bytes;
+ total = image->width * bytes;
+ pack_size = bpl * write;
+
+ for (i = image->height; i--;) {
+ dst = (unsigned long *) dst1;
+ j = total;
+ m = read;
+
+ while (j >= pack_size) {
+ l--;
+ m--;
+ end_mask = cfb_tabdef[(*src >> l) & 1];
+ *(unsigned long *) dst2 =
+ (end_mask & eorx) ^ bgcolor;
+ dst2 += bytes;
+ if (!m) {
+ for (k = 0; k < write; k++)
+ fb_writel(cfb_pixarray[k], dst++);
+ dst2 = (char *) cfb_pixarray;
+ j -= pack_size;
+ m = read;
+ }
+ if (!l) {
+ l = 8;
+ src++;
+ }
+ }
+ /* write residual pixels */
+ if (j) {
+ k = 0;
+ while (j--)
+ fb_writeb(((u8 *) cfb_pixarray)[k++],
+ dst++);
+ }
+ dst1 += p->fix.line_length;
+ }
+}
+
+static inline void bitwise_blit(struct fb_image *image, struct fb_info *p,
+ char *dst1, int fgcolor, int bgcolor)
{
- int pad, ppw;
- int x2, y2, n, i, j, k, l = 7;
+ int i, j, k, l = 8, n, pad, ppw;
unsigned long tmp = ~0 << (BITS_PER_LONG - p->var.bits_per_pixel);
- unsigned long fgx, bgx, fgcolor, bgcolor, eorx;
+ unsigned long fgx = fgcolor, bgx = bgcolor, eorx;
unsigned long end_mask;
unsigned long *dst = NULL;
+ char *src = image->data;
+
+ ppw = BITS_PER_LONG / p->var.bits_per_pixel;
+
+ 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--) {
+ l--;
+ if (test_bit(l, (unsigned long *) src))
+ end_mask |=
+ (tmp >>
+ (p->var.bits_per_pixel *
+ (k - 1)));
+ if (!l) {
+ l = 8;
+ src++;
+ }
+ }
+ fb_writel((end_mask & eorx) ^ bgx, dst);
+ dst++;
+ }
+
+ if (n) {
+ end_mask = 0;
+ for (j = n; j > 0; j--) {
+ l--;
+ if (test_bit(l, (unsigned long *) src))
+ end_mask |=
+ (tmp >>
+ (p->var.bits_per_pixel *
+ (j - 1)));
+ if (!l) {
+ l = 8;
+ src++;
+ }
+ }
+ fb_writel((end_mask & eorx) ^ bgx, dst);
+ dst++;
+ }
+ l -= pad;
+ dst1 += p->fix.line_length;
+ }
+}
+
+void cfb_imageblit(struct fb_info *p, struct fb_image *image)
+{
+ int x2, y2, n;
+ unsigned long fgcolor, bgcolor;
+ unsigned long end_mask;
u8 *dst1;
- u8 *src;
/*
* We could use hardware clipping but on many cards you get around hardware
@@ -60,68 +302,37 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
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;
- image->width = x2 - image->dx;
+ 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;
+ dst1 = p->screen_base + image->dy * p->fix.line_length +
+ ((image->dx * p->var.bits_per_pixel) >> 3);
if (image->depth == 1) {
-
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];
+ 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;
- }
-
- for (i = 0; i < ppw-1; i++) {
- fgx <<= p->var.bits_per_pixel;
- bgx <<= p->var.bits_per_pixel;
- fgx |= fgcolor;
- bgx |= bgcolor;
+ fgcolor = image->fg_color;
+ bgcolor = image->bg_color;
}
- 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 {
+
+ if (p->var.bits_per_pixel >= 8) {
+ if (BITS_PER_LONG % p->var.bits_per_pixel == 0)
+ fast_imageblit(image, p, dst1, fgcolor,
+ bgcolor);
+ else
+ slow_imageblit(image, p, dst1, fgcolor,
+ bgcolor);
+ } else
+ /* Is there such a thing as 3 or 5 bits per pixel? */
+ slow_imageblit(image, p, dst1, fgcolor, bgcolor);
+
+ }
+
+ else {
/* Draw the penguin */
n = ((image->width * p->var.bits_per_pixel) >> 3);
end_mask = 0;
diff --git a/drivers/video/console/Config.help b/drivers/video/console/Config.help
new file mode 100644
index 000000000000..1bd59ed8f72e
--- /dev/null
+++ b/drivers/video/console/Config.help
@@ -0,0 +1,149 @@
+CONFIG_VIDEO_SELECT
+ 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_FBCON_VGA_PLANES
+ 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_FB_VGA16
+ This is the frame buffer device driver for VGA 16 color graphic
+ cards. Say Y if you have such a card.
+
+ This code is also available as a module. If you want to compile it
+ as a module ( = code which can be inserted in and removed from the
+ running kernel whenever you want), say M here and read
+ <file:Documentation/modules.txt>. The module will be called
+ vga16fb.o.
+
+CONFIG_FB_STI
+ 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 implement the linux framebuffer device and
+ an fbcon color text console using calls to the STI BIOS routines.
+ The HP framebuffer device is usually planar, uses a strange memory
+ layout, and changing the plane mask to create colored pixels
+ requires a call to the STI routines, so do not expect /dev/fb to
+ actually be useful. However, it is the best we have as far as
+ graphics on the HP chipsets due to lack of hardware level
+ documentation for the various on-board HP chipsets used in these
+ systems. It is sufficient for basic text console functions,
+ including fonts.
+
+ You should probably enable this option, unless you are having
+ trouble getting video when booting the kernel (make sure it isn't
+ just that you are running the console on the serial port, though).
+ Really old HP boxes may not have STI, and must use the PDC BIOS
+ console or the IODC BIOS.
+
+CONFIG_FBCON_FONTS
+ 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_FONT_8x16
+ 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_FBCON_FONTWIDTH8_ONLY
+ Answer Y here will make the kernel provide only the 8x8 fonts (these
+ are the less readable).
+
+ If unsure, say N.
+
+CONFIG_FONT_SUN8x16
+ This is the high resolution console font for Sun machines. Say Y.
+
+CONFIG_FONT_SUN12x22
+ 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_FONT_8x8
+ 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_6x11
+ Small console font with Macintosh-style high-half glyphs. Some Mac
+ framebuffer drivers don't support this one at all.
+
+CONFIG_FONT_PEARL_8x8
+ Small console font with PC-style control-character and high-half
+ glyphs.
+
+CONFIG_FONT_ACORN_8x8
+ Small console font with PC-style control characters and high-half
+ glyphs.
+
+CONFIG_FBCON_ADVANCED
+ 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_AFB
+ This is the low level frame buffer console driver for 1 to 8
+ bitplanes (2 to 256 colors) on Amiga.
+
+CONFIG_FBCON_ILBM
+ This is the low level frame buffer console driver for 1 to 8
+ interleaved bitplanes (2 to 256 colors) on Amiga.
+
+CONFIG_FBCON_IPLAN2P2
+ This is the low level frame buffer console driver for 2 interleaved
+ bitplanes (4 colors) on Atari.
+
+CONFIG_FBCON_IPLAN2P4
+ This is the low level frame buffer console driver for 4 interleaved
+ bitplanes (16 colors) on Atari.
+
+CONFIG_FBCON_IPLAN2P8
+ This is the low level frame buffer console driver for 8 interleaved
+ bitplanes (256 colors) on Atari.
+
+CONFIG_FBCON_HGA
+ This is the low level frame buffer console driver for Hercules mono
+ graphics cards.
+
diff --git a/drivers/video/console/Config.in b/drivers/video/console/Config.in
new file mode 100644
index 000000000000..25d1e8671b56
--- /dev/null
+++ b/drivers/video/console/Config.in
@@ -0,0 +1,162 @@
+#
+# Console Display configuration
+#
+
+if [ "$CONFIG_VT" != "n" ]; then
+ mainmenu_option next_comment
+ comment 'Console Display driver support'
+
+ bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+ if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a \
+ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
+ bool 'VGA text console' CONFIG_VGA_CONSOLE
+# 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
+ fi
+ tristate 'MDA text console (dual-headed) ' CONFIG_MDA_CONSOLE
+ if [ "$CONFIG_FB" = "y" ]; then
+ define_bool CONFIG_PCI_CONSOLE y
+ fi
+#if [ "$CONFIG_SGI_IP22" = "y" ]; then
+# tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
+# if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
+# define_bool CONFIG_DUMMY_CONSOLE y
+# else
+# define_bool CONFIG_FONT_8x16 y
+#fi
+ if [ "$CONFIG_ARCH_PARISC" = "y" ]; then
+# bool 'IODC console' CONFIG_IODC_CONSOLE
+ bool 'STI console' CONFIG_STI_CONSOLE
+ if [ "$CONFIG_IODC_CONSOLE" = "n" ]; then
+ if [ "$CONFIG_GSC_PS2" = "y" ]; then
+ define_bool CONFIG_DUMMY_CONSOLE y
+ fi
+ fi
+ if [ "$CONFIG_STI_CONSOLE" = "y" ]; then
+ define_bool CONFIG_DUMMY_CONSOLE y
+ fi
+ fi
+ if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
+ bool 'PROM console' CONFIG_PROM_CONSOLE
+ if [ "$CONFIG_PROM_CONSOLE" != "y" ]; then
+ define_bool CONFIG_DUMMY_CONSOLE y
+ fi
+ fi
+ if [ "$CONFIG_FB" = "y" ]; then
+ bool 'Framebuffer Console support' CONFIG_FRAMEBUFFER_CONSOLE
+ if [ "$CONFIG_FRAMEBUFFER_CONSOLE" = "y" ]; then
+ define_bool CONFIG_DUMMY_CONSOLE y
+ bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED
+ if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
+ tristate ' Hardware acceleration support' CONFIG_FBCON_ACCEL
+ tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB
+ tristate ' Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
+ tristate ' Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
+ tristate ' Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4
+ tristate ' Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
+ tristate ' VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES
+ tristate ' HGA monochrome support ' CONFIG_FBCON_HGA
+ else
+ if [ "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
+ "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_HIT" = "y" -o \
+ "$CONFIG_FB_HP300" = "y" -o "$CONFIG_FB_Q40" = "y" -o \
+ "$CONFIG_FB_ANAKIN" = "y" -o "$CONFIG_FB_G364" = "y" -o \
+ "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_CLPS711X" = "y" -o \
+ "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
+ "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
+ "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
+ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
+ "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_OF" = "y" -o \
+ "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_SIS" = "y" ]; then
+ define_tristate CONFIG_FBCON_ACCEL y
+ else
+ if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
+ "$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
+ "$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
+ "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
+ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_SIS" = "y" ]; then
+ define_tristate CONFIG_FBCON_ACCEL m
+ fi
+ fi
+ if [ "$CONFIG_FB_AMIGA" = "y" ]; then
+ define_tristate CONFIG_FBCON_AFB y
+ define_tristate CONFIG_FBCON_ILBM y
+ else
+ if [ "$CONFIG_FB_AMIGA" = "m" ]; then
+ define_tristate CONFIG_FBCON_AFB m
+ define_tristate CONFIG_FBCON_ILBM m
+ fi
+ fi
+ if [ "$CONFIG_FB_ATARI" = "y" ]; then
+ define_tristate CONFIG_FBCON_IPLAN2P2 y
+ define_tristate CONFIG_FBCON_IPLAN2P4 y
+ define_tristate CONFIG_FBCON_IPLAN2P8 y
+ else
+ if [ "$CONFIG_FB_ATARI" = "m" ]; then
+ define_tristate CONFIG_FBCON_IPLAN2P2 m
+ define_tristate CONFIG_FBCON_IPLAN2P4 m
+ define_tristate CONFIG_FBCON_IPLAN2P8 m
+ fi
+ fi
+ if [ "$CONFIG_FB_VGA16" = "y" ]; then
+ define_tristate CONFIG_FBCON_VGA_PLANES y
+ else
+ if [ "$CONFIG_FB_VGA16" = "m" ]; then
+ define_tristate CONFIG_FBCON_VGA_PLANES m
+ fi
+ fi
+ fi
+ bool ' Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY
+ if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
+ bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22
+ fi
+ bool ' Select other fonts' CONFIG_FBCON_FONTS
+ if [ "$CONFIG_FBCON_FONTS" = "y" ]; then
+ bool ' VGA 8x8 font' CONFIG_FONT_8x8
+ bool ' VGA 8x16 font' CONFIG_FONT_8x16
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
+ fi
+ bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
+ bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
+ fi
+ else
+ bool ' Select compiled-in fonts' CONFIG_FBCON_FONTS
+ if [ "$CONFIG_FBCON_FONTS" = "y" ]; then
+ bool ' VGA 8x8 font' CONFIG_FONT_8x8
+ bool ' VGA 8x16 font' CONFIG_FONT_8x16
+ bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22
+ bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
+ fi
+ bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
+ bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
+ bool ' Mini 4x6 font' CONFIG_FONT_MINI_4x6
+ else
+ define_bool CONFIG_FONT_8x8 y
+ define_bool CONFIG_FONT_8x16 y
+ if [ "$CONFIG_MAC" = "y" ]; then
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ define_bool CONFIG_FONT_6x11 y
+ fi
+ fi
+ if [ "$CONFIG_AMIGA" = "y" ]; then
+ define_bool CONFIG_FONT_PEARL_8x8 y
+ fi
+ if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then
+ define_bool CONFIG_FONT_ACORN_8x8 y
+ fi
+ fi
+ fi
+ fi
+ fi
+ endmenu
+fi
+
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
new file mode 100644
index 000000000000..19ffc6d45dd7
--- /dev/null
+++ b/drivers/video/console/Makefile
@@ -0,0 +1,49 @@
+# 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 fbcon-accel.o fbcon-afb.o fbcon-ilbm.o \
+ fbcon-iplan2p2.o fbcon-iplan2p4.o fbcon-iplan2p8.o \
+ fbcon-vga-planes.o fbcon-vga8-planes.o fbcon-hga.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_FRAMEBUFFER_CONSOLE) += fbcon.o fonts.o
+
+# Generic Low Level Drivers
+
+obj-$(CONFIG_FBCON_AFB) += fbcon-afb.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_HGA) += fbcon-hga.o
+obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
+obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
+
+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..82686f4b2633 100644
--- a/drivers/video/dummycon.c
+++ b/drivers/video/console/dummycon.c
diff --git a/drivers/video/fbcon-accel.c b/drivers/video/console/fbcon-accel.c
index 8f6c5dfe0066..8f6c5dfe0066 100644
--- a/drivers/video/fbcon-accel.c
+++ b/drivers/video/console/fbcon-accel.c
diff --git a/drivers/video/fbcon-accel.h b/drivers/video/console/fbcon-accel.h
index 80944b6e04c1..80944b6e04c1 100644
--- a/drivers/video/fbcon-accel.h
+++ b/drivers/video/console/fbcon-accel.h
diff --git a/drivers/video/fbcon-afb.c b/drivers/video/console/fbcon-afb.c
index 6afee164b609..6afee164b609 100644
--- a/drivers/video/fbcon-afb.c
+++ b/drivers/video/console/fbcon-afb.c
diff --git a/drivers/video/fbcon-hga.c b/drivers/video/console/fbcon-hga.c
index 4cb12c6e47f5..4cb12c6e47f5 100644
--- a/drivers/video/fbcon-hga.c
+++ b/drivers/video/console/fbcon-hga.c
diff --git a/drivers/video/fbcon-ilbm.c b/drivers/video/console/fbcon-ilbm.c
index 157736e809a7..157736e809a7 100644
--- a/drivers/video/fbcon-ilbm.c
+++ b/drivers/video/console/fbcon-ilbm.c
diff --git a/drivers/video/fbcon-iplan2p2.c b/drivers/video/console/fbcon-iplan2p2.c
index 9eea32a4efb9..9eea32a4efb9 100644
--- a/drivers/video/fbcon-iplan2p2.c
+++ b/drivers/video/console/fbcon-iplan2p2.c
diff --git a/drivers/video/fbcon-iplan2p4.c b/drivers/video/console/fbcon-iplan2p4.c
index fdbb6a4d2790..fdbb6a4d2790 100644
--- a/drivers/video/fbcon-iplan2p4.c
+++ b/drivers/video/console/fbcon-iplan2p4.c
diff --git a/drivers/video/fbcon-iplan2p8.c b/drivers/video/console/fbcon-iplan2p8.c
index 416f28fd1e59..416f28fd1e59 100644
--- a/drivers/video/fbcon-iplan2p8.c
+++ b/drivers/video/console/fbcon-iplan2p8.c
diff --git a/drivers/video/fbcon-sti.c b/drivers/video/console/fbcon-sti.c
index ef6b9a49d119..ef6b9a49d119 100644
--- a/drivers/video/fbcon-sti.c
+++ b/drivers/video/console/fbcon-sti.c
diff --git a/drivers/video/fbcon-vga-planes.c b/drivers/video/console/fbcon-vga-planes.c
index 2056b16117c2..2056b16117c2 100644
--- a/drivers/video/fbcon-vga-planes.c
+++ b/drivers/video/console/fbcon-vga-planes.c
diff --git a/drivers/video/fbcon.c b/drivers/video/console/fbcon.c
index 136faec87d09..28cc533e65b8 100644
--- a/drivers/video/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -335,14 +335,15 @@ int set_all_vcs(int fbidx, struct fb_ops *fb, struct fb_var_screeninfo *var,
int unit, err;
var->activate |= FB_ACTIVATE_TEST;
- err = gen_set_var(var, PROC_CONSOLE(info), info);
+ err = fb_set_var(var, info);
var->activate &= ~FB_ACTIVATE_TEST;
gen_set_disp(PROC_CONSOLE(info), info);
if (err)
return err;
for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
if (fb_display[unit].conp && con2fb_map[unit] == fbidx) {
- gen_set_var(var, unit, info);
+ if (CON_IS_VISIBLE(fb_display[unit].conp))
+ fb_set_var(var, info);
gen_set_disp(unit, info);
}
return 0;
@@ -983,6 +984,19 @@ 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(int unit, struct vc_data *conp,
struct display *p, int count)
{
@@ -994,7 +1008,7 @@ static __inline__ void ywrap_up(int unit, struct vc_data *conp,
info->var.xoffset = 0;
info->var.yoffset = p->yscroll*fontheight(p);
info->var.vmode |= FB_VMODE_YWRAP;
- gen_update_var(unit, info);
+ update_var(unit, info);
scrollback_max += count;
if (scrollback_max > scrollback_phys_max)
scrollback_max = scrollback_phys_max;
@@ -1012,7 +1026,7 @@ static __inline__ void ywrap_down(int unit, struct vc_data *conp,
info->var.xoffset = 0;
info->var.yoffset = p->yscroll*fontheight(p);
info->var.vmode |= FB_VMODE_YWRAP;
- gen_update_var(unit, info);
+ update_var(unit, info);
scrollback_max -= count;
if (scrollback_max < 0)
scrollback_max = 0;
@@ -1033,7 +1047,7 @@ static __inline__ void ypan_up(int unit, struct vc_data *conp,
info->var.xoffset = 0;
info->var.yoffset = p->yscroll*fontheight(p);
info->var.vmode &= ~FB_VMODE_YWRAP;
- gen_update_var(unit, info);
+ update_var(unit, info);
if (p->dispsw->clear_margins)
p->dispsw->clear_margins(conp, p, 1);
scrollback_max += count;
@@ -1057,7 +1071,7 @@ static __inline__ void ypan_down(int unit, struct vc_data *conp,
info->var.xoffset = 0;
info->var.yoffset = p->yscroll*fontheight(p);
info->var.vmode &= ~FB_VMODE_YWRAP;
- gen_update_var(unit, info);
+ update_var(unit, info);
if (p->dispsw->clear_margins)
p->dispsw->clear_margins(conp, p, 1);
scrollback_max -= count;
@@ -2148,7 +2162,7 @@ static int fbcon_scrolldelta(struct vc_data *conp, int lines)
offset -= limit;
info->var.xoffset = 0;
info->var.yoffset = offset*fontheight(p);
- gen_update_var(unit, info);
+ update_var(unit, info);
if (!scrollback_current)
fbcon_cursor(conp, CM_DRAW);
return 0;
diff --git a/drivers/video/font_6x11.c b/drivers/video/console/font_6x11.c
index aa95f8863830..aa95f8863830 100644
--- a/drivers/video/font_6x11.c
+++ b/drivers/video/console/font_6x11.c
diff --git a/drivers/video/font_8x16.c b/drivers/video/console/font_8x16.c
index 786619712560..786619712560 100644
--- a/drivers/video/font_8x16.c
+++ b/drivers/video/console/font_8x16.c
diff --git a/drivers/video/font_8x8.c b/drivers/video/console/font_8x8.c
index 6358e671f1ce..6358e671f1ce 100644
--- a/drivers/video/font_8x8.c
+++ b/drivers/video/console/font_8x8.c
diff --git a/drivers/video/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index 154d0fb39da7..154d0fb39da7 100644
--- a/drivers/video/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
diff --git a/drivers/video/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index 9fe2db2a6edc..9fe2db2a6edc 100644
--- a/drivers/video/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
diff --git a/drivers/video/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
index c8d7da5714c5..c8d7da5714c5 100644
--- a/drivers/video/font_pearl_8x8.c
+++ b/drivers/video/console/font_pearl_8x8.c
diff --git a/drivers/video/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
index 803b35ea8d72..803b35ea8d72 100644
--- a/drivers/video/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
diff --git a/drivers/video/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 9f5bc40b4762..9f5bc40b4762 100644
--- a/drivers/video/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
diff --git a/drivers/video/fonts.c b/drivers/video/console/fonts.c
index 436f3a5ec2fc..436f3a5ec2fc 100644
--- a/drivers/video/fonts.c
+++ b/drivers/video/console/fonts.c
diff --git a/drivers/video/mdacon.c b/drivers/video/console/mdacon.c
index f1c47bfaa270..f1c47bfaa270 100644
--- a/drivers/video/mdacon.c
+++ b/drivers/video/console/mdacon.c
diff --git a/drivers/video/newport_con.c b/drivers/video/console/newport_con.c
index 364874dff50d..364874dff50d 100644
--- a/drivers/video/newport_con.c
+++ b/drivers/video/console/newport_con.c
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..d72ce48cb3f1 100644
--- a/drivers/video/promcon.c
+++ b/drivers/video/console/promcon.c
diff --git a/drivers/video/sti-bmode.h b/drivers/video/console/sti-bmode.h
index 4aa38f6d9daa..4aa38f6d9daa 100644
--- a/drivers/video/sti-bmode.h
+++ b/drivers/video/console/sti-bmode.h
diff --git a/drivers/video/sticon-bmode.c b/drivers/video/console/sticon-bmode.c
index 3ab5077ac27a..3ab5077ac27a 100644
--- a/drivers/video/sticon-bmode.c
+++ b/drivers/video/console/sticon-bmode.c
diff --git a/drivers/video/sticon.c b/drivers/video/console/sticon.c
index 7dddbe42d40a..7dddbe42d40a 100644
--- a/drivers/video/sticon.c
+++ b/drivers/video/console/sticon.c
diff --git a/drivers/video/vgacon.c b/drivers/video/console/vgacon.c
index b798756cef74..b798756cef74 100644
--- a/drivers/video/vgacon.c
+++ b/drivers/video/console/vgacon.c
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index e10d65f53d69..a916cf5fdfcd 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -181,62 +181,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
@@ -353,7 +297,6 @@ void fb_invert_cmaps(void)
EXPORT_SYMBOL(fb_alloc_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/fbgen.c b/drivers/video/fbgen.c
index 9c055a0bb39b..3f9c2b28bc4e 100644
--- a/drivers/video/fbgen.c
+++ b/drivers/video/fbgen.c
@@ -20,13 +20,11 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <video/fbcon.h>
-
-int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
int err;
- if (con < 0 || (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo)))) {
+ if (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
if (!info->fbops->fb_check_var) {
*var = info->var;
return 0;
@@ -38,20 +36,18 @@ int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
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_set_par)
+ info->fbops->fb_set_par(info);
- if (info->fbops->fb_pan_display)
- info->fbops->fb_pan_display(&info->var, info);
- fb_set_cmap(&info->cmap, 1, info);
- }
+ if (info->fbops->fb_pan_display)
+ info->fbops->fb_pan_display(&info->var, info);
+ fb_set_cmap(&info->cmap, 1, info);
}
}
return 0;
}
-int fbgen_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+int fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
int xoffset = var->xoffset;
int yoffset = var->yoffset;
@@ -79,21 +75,8 @@ int fbgen_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
/* ---- Helper functions --------------------------------------------------- */
-int gen_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;
-}
-
/**
- * fbgen_blank - blank the screen
+ * fb_blank - blank the screen
* @blank: boolean, 0 unblank, 1 blank
* @info: frame buffer info structure
*
@@ -101,7 +84,7 @@ int gen_update_var(int con, struct fb_info *info)
*
*/
-int fbgen_blank(int blank, struct fb_info *info)
+int fb_blank(int blank, struct fb_info *info)
{
struct fb_cmap cmap;
u16 black[16];
@@ -129,10 +112,8 @@ int fbgen_blank(int blank, struct fb_info *info)
}
/* generic frame buffer operations */
-EXPORT_SYMBOL(gen_set_var);
-EXPORT_SYMBOL(fbgen_pan_display);
-/* helper functions */
-EXPORT_SYMBOL(gen_update_var);
-EXPORT_SYMBOL(fbgen_blank);
+EXPORT_SYMBOL(fb_set_var);
+EXPORT_SYMBOL(fb_pan_display);
+EXPORT_SYMBOL(fb_blank);
MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index a0f671c84323..c3217085ee32 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -466,10 +466,10 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
int fbidx = GET_FB_IDX(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;
struct fb_con2fbmap con2fb;
+ struct fb_cmap cmap;
int i;
if (! fb)
@@ -485,9 +485,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
i = set_all_vcs(fbidx, fb, &var, info);
if (i) return i;
} else {
- i = gen_set_var(&var, PROC_CONSOLE(info), info);
+ i = fb_set_var(&var, info);
if (i) return i;
- gen_set_disp(PROC_CONSOLE(info), info);
}
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
@@ -512,6 +511,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
return i;
+#ifdef CONFIG_VT
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
return -EFAULT;
@@ -540,6 +540,7 @@ 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
case FBIOBLANK:
if (fb->fb_blank == NULL)
return -EINVAL;
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index d659e07782de..f33874aa81af 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1870,8 +1870,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
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 7fad95ecea2d..4582175b2648 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -99,7 +99,6 @@ 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_check_var = sgivwfb_check_var,
.fb_set_par = sgivwfb_set_par,
.fb_setcolreg = sgivwfb_setcolreg,
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/include/linux/fb.h b/include/linux/fb.h
index 5f1dd158fe42..d6ba52c1e461 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -317,6 +317,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);
+ /* 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 */
@@ -336,6 +339,8 @@ struct fb_ops {
void (*fb_imageblit)(struct fb_info *info, struct fb_image *image);
/* perform polling on fb device */
int (*fb_poll)(struct fb_info *info, poll_table *wait);
+ /* wait for blit idle, optional */
+ void (*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, struct fb_info *info);
@@ -414,23 +419,13 @@ struct fb_info {
* `Generic' versions of the frame buffer device operations
*/
-extern int gen_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-extern int fb_pan_display(struct fb_var_screeninfo *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 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);
- /*
- * Helper functions
- */
-
-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_blank(int blank, struct fb_info *info);
-extern void gen_set_disp(int con, struct fb_info *info);
-
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
extern int unregister_framebuffer(struct fb_info *fb_info);
@@ -447,10 +442,6 @@ extern int fbmon_dpms(const struct fb_info *fb_info);
extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
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);
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;