diff options
Diffstat (limited to 'drivers/video')
113 files changed, 7874 insertions, 1424 deletions
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c index 6a3cfbdc6dc..3b0ddc55236 100644 --- a/drivers/video/68328fb.c +++ b/drivers/video/68328fb.c @@ -113,7 +113,6 @@ static struct fb_ops mc68x328fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, .fb_mmap = mc68x328fb_mmap, }; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 7192b770bfb..25b6ca6ad08 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -65,15 +65,6 @@ config FB_CFB_IMAGEBLIT blitting. This is used by drivers that don't provide their own (accelerated) version. -config FB_SOFT_CURSOR - tristate - depends on FB - default n - ---help--- - Include the soft_cursor function for generic software cursor support. - This is used by drivers that don't provide their own (accelerated) - version. - config FB_MACMODES tristate depends on FB @@ -114,7 +105,6 @@ config FB_CIRRUS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. @@ -133,7 +123,6 @@ config FB_PM2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the Permedia2 AGP frame buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a @@ -152,7 +141,6 @@ config FB_ARMCLCD select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This framebuffer device driver is for the ARM PrimeCell PL110 Colour LCD controller. ARM PrimeCells provide the building @@ -169,7 +157,6 @@ config FB_ACORN select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the Acorn VIDC graphics hardware found in Acorn RISC PCs and other ARM-based machines. If @@ -181,7 +168,9 @@ config FB_CLPS711X select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR + help + Say Y to enable the Framebuffer driver for the CLPS7111 and + EP7212 processors. config FB_SA1100 bool "SA-1100 LCD support" @@ -189,7 +178,6 @@ config FB_SA1100 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is a framebuffer device for the SA-1100 LCD Controller. See <http://www.linux-fbdev.org/> for information on framebuffer @@ -204,7 +192,6 @@ config FB_IMX select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR config FB_CYBER2000 tristate "CyberPro 2000/2010/5000 support" @@ -212,7 +199,6 @@ config FB_CYBER2000 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This enables support for the Integraphics CyberPro 20x0 and 5000 VGA chips used in the Rebel.com Netwinder and other machines. @@ -225,7 +211,6 @@ config FB_APOLLO default y select FB_CFB_FILLRECT select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR config FB_Q40 bool @@ -234,12 +219,10 @@ config FB_Q40 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR config FB_AMIGA tristate "Amiga native chipset support" depends on FB && AMIGA - select FB_SOFT_CURSOR help This is the frame buffer device driver for the builtin graphics chipset found in Amigas. @@ -279,7 +262,6 @@ config FB_CYBER select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This enables support for the Cybervision 64 graphics card from Phase5. Please note that its use is not all that intuitive (i.e. if @@ -294,7 +276,6 @@ config FB_VIRGE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This enables support for the Cybervision 64/3D graphics card from Phase5. Please note that its use is not all that intuitive (i.e. if @@ -317,7 +298,6 @@ config FB_FM2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the Amiga FrameMaster card from BSC (exhibited 1992 but not shipped as a CBM product). @@ -328,7 +308,6 @@ config FB_ARC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This enables support for the Arc Monochrome LCD board. The board is based on the KS-108 lcd controller and is typically a matrix @@ -351,7 +330,6 @@ config FB_OF select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES help Say Y if you want support with Open Firmware for your graphics @@ -363,7 +341,6 @@ config FB_CONTROL select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES help This driver supports a frame buffer for the graphics adapter in the @@ -375,7 +352,6 @@ config FB_PLATINUM select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES help This driver supports a frame buffer for the "platinum" graphics @@ -387,7 +363,6 @@ config FB_VALKYRIE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES help This driver supports a frame buffer for the "valkyrie" graphics @@ -399,42 +374,32 @@ config FB_CT65550 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the Chips & Technologies 65550 graphics chip in PowerBooks. config FB_ASILIANT - bool "Chips 69000 display support" + bool "Asiliant (Chips) 69000 display support" depends on (FB = y) && PCI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR config FB_IMSTT bool "IMS Twin Turbo display support" depends on (FB = y) && PCI select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES if PPC help The IMS Twin Turbo is a PCI-based frame buffer card bundled with many Macintosh and compatible computers. -config FB_S3TRIO - bool "S3 Trio display support" - depends on (FB = y) && PPC && BROKEN - help - If you have a S3 Trio say Y. Say N for S3 Virge. - config FB_VGA16 tristate "VGA 16-color graphics support" depends on FB && (X86 || PPC) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for VGA 16 color graphic cards. Say Y if you have such a card. @@ -448,7 +413,6 @@ config FB_STI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR default y ---help--- STI refers to the HP "Standard Text Interface" which is a set of @@ -469,7 +433,6 @@ config FB_MAC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES # bool ' Apple DAFB display support' CONFIG_FB_DAFB @@ -478,7 +441,6 @@ config FB_HP300 depends on (FB = y) && HP300 select FB_CFB_FILLRECT select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR default y config FB_TGA @@ -487,7 +449,6 @@ config FB_TGA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for generic TGA graphic cards. Say Y if you have one of those. @@ -498,7 +459,6 @@ config FB_VESA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for generic VESA 2.0 compliant graphic cards. The older VESA 1.2 cards are not supported. @@ -516,7 +476,6 @@ config FB_HGA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Say Y here if you have a Hercules mono graphics card. @@ -545,7 +504,6 @@ config FB_SGIVW select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help SGI Visual Workstation support for framebuffer graphics. @@ -555,7 +513,6 @@ config FB_GBE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for SGI Graphics Backend. This chip is used in SGI O2 and Visual Workstation 320/540. @@ -583,7 +540,6 @@ config FB_BW2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the BWtwo frame buffer. @@ -592,7 +548,6 @@ config FB_CG3 depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the CGthree frame buffer. @@ -601,7 +556,6 @@ config FB_CG6 depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the CGsix (GX, TurboGX) frame buffer. @@ -612,7 +566,6 @@ config FB_PVR2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- Say Y here if you have a PowerVR 2 card in your box. If you plan to run linux on your Dreamcast, you will have to say Y here. @@ -634,13 +587,23 @@ config FB_EPSON1355 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Build in support for the SED1355 Epson Research Embedded RAMDAC LCD/CRT Controller (since redesignated as the S1D13505) as a framebuffer. Product specs at <http://www.erd.epson.com/vdc/html/products.htm>. +config FB_S1D13XXX + tristate "Epson S1D13XXX framebuffer support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for S1D13XXX framebuffer device family (currently only + working with S1D13806). Product specs at + <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm> + config FB_NVIDIA tristate "nVidia Framebuffer Support" depends on FB && PCI @@ -650,7 +613,6 @@ config FB_NVIDIA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This driver supports graphics boards with the nVidia chips, TNT and newer. For very old chipsets, such as the RIVA128, then use @@ -662,7 +624,7 @@ config FB_NVIDIA config FB_NVIDIA_I2C bool "Enable DDC Support" - depends on FB_NVIDIA && !PPC_OF + depends on FB_NVIDIA help This enables I2C support for nVidia Chipsets. This is used only for getting EDID information from the attached display @@ -768,7 +730,6 @@ config FB_INTEL select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This driver supports the on-board graphics built in to the Intel 830M/845G/852GM/855GM/865G chipsets. @@ -791,7 +752,6 @@ config FB_MATROX select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_TILEBLITTING select FB_MACMODES if PPC_PMAC ---help--- @@ -932,7 +892,6 @@ config FB_RADEON_OLD select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES if PPC help Choose this option if you want to use an ATI Radeon graphics card as @@ -950,7 +909,6 @@ config FB_RADEON select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES if PPC_OF help Choose this option if you want to use an ATI Radeon graphics card as @@ -988,7 +946,6 @@ config FB_ATY128 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES if PPC_PMAC help This driver supports graphics boards with the ATI Rage128 chips. @@ -1004,7 +961,6 @@ config FB_ATY select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select FB_MACMODES if PPC help This driver supports graphics boards with the ATI Mach64 chips. @@ -1047,6 +1003,12 @@ config FB_ATY_GX is at <http://support.ati.com/products/pc/mach64/graphics_xpression.html>. +config FB_S3TRIO + bool "S3 Trio display support" + depends on (FB = y) && PPC && BROKEN + help + If you have a S3 Trio say Y. Say N for S3 Virge. + config FB_SAVAGE tristate "S3 Savage support" depends on FB && PCI && EXPERIMENTAL @@ -1056,7 +1018,6 @@ config FB_SAVAGE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This driver supports notebooks and computers with S3 Savage PCI/AGP chips. @@ -1093,7 +1054,6 @@ config FB_SIS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the SiS 300, 315, 330 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. @@ -1123,7 +1083,6 @@ config FB_NEOMAGIC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This driver supports notebooks with NeoMagic PCI chips. Say Y if you have such a graphics card. @@ -1137,7 +1096,6 @@ config FB_KYRO select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Say Y here if you have a STG4000 / Kyro / PowerVR 3 based graphics board. @@ -1151,7 +1109,6 @@ config FB_3DFX select FB_CFB_IMAGEBLIT select FB_CFB_FILLRECT select FB_CFB_COPYAREA - select FB_SOFT_CURSOR help This driver supports graphics boards with the 3Dfx Banshee/Voodoo3 chips. Say Y if you have such a graphics board. @@ -1173,7 +1130,6 @@ config FB_VOODOO1 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or Voodoo2 (cvg) based graphics card. @@ -1190,7 +1146,6 @@ config FB_CYBLA tristate "Cyberblade/i1 support" depends on FB && PCI select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR select VIDEO_SELECT ---help--- This driver is supposed to support the Trident Cyberblade/i1 @@ -1218,7 +1173,6 @@ config FB_TRIDENT select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- This driver is supposed to support graphics boards with the Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops @@ -1250,38 +1204,6 @@ config FB_PM3 similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 and maybe other boards. -config FB_E1356 - tristate "Epson SED1356 framebuffer support" - depends on FB && EXPERIMENTAL && PCI && MIPS - -config PB1000_CRT - bool "Use CRT on Pb1000 (J65)" - depends on MIPS_PB1000=y && FB_E1356 - -config PB1000_NTSC - bool "Use Compsite NTSC on Pb1000 (J63)" - depends on MIPS_PB1000=y && FB_E1356 - -config PB1000_TFT - bool "Use TFT Panel on Pb1000 (J64)" - depends on MIPS_PB1000=y && FB_E1356 - -config PB1500_CRT - bool "Use CRT on Pb1500 " if MIPS_PB1500=y - depends on FB_E1356 - -config PB1500_CRT - prompt "Use CRT on Pb1100 " - depends on FB_E1356 && MIPS_PB1100=y - -config PB1500_TFT - bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y - depends on FB_E1356 - -config PB1500_TFT - prompt "Use TFT Panel on Pb1100 " - depends on FB_E1356 && MIPS_PB1100=y - config FB_AU1100 bool "Au1100 LCD Driver" depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y @@ -1299,7 +1221,6 @@ config FB_FFB depends on FB_SBUS && SPARC64 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the Creator, Creator3D, and Elite3D graphics boards. @@ -1310,7 +1231,6 @@ config FB_TCX select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the TCX 24/8bit frame buffer. @@ -1321,7 +1241,6 @@ config FB_CG14 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the CGfourteen frame buffer on Desktop SPARCsystems with the SX graphics option. @@ -1332,7 +1251,6 @@ config FB_P9100 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the P9100 card supported on Sparcbook 3 machines. @@ -1343,7 +1261,6 @@ config FB_LEO select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the SBUS-based Sun ZX (leo) frame buffer cards. @@ -1358,7 +1275,6 @@ config FB_IGA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the framebuffer device for the INTERGRAPHICS 1680 and successor frame buffer cards. @@ -1369,7 +1285,6 @@ config FB_HIT select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help This is the frame buffer device driver for the Hitachi HD64461 LCD frame buffer card. @@ -1380,7 +1295,6 @@ config FB_PMAG_AA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) used mainly in the MIPS-based DECstation series. @@ -1391,7 +1305,6 @@ config FB_PMAG_BA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) used mainly in the MIPS-based DECstation series. @@ -1402,7 +1315,6 @@ config FB_PMAGB_B select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Support for the PMAGB-B TURBOchannel framebuffer card used mainly in the MIPS-based DECstation series. The card is currently only @@ -1414,7 +1326,6 @@ config FB_MAXINE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Support for the onboard framebuffer (1024x768x8) in the Personal DECstation series (Personal DECstation 5000/20, /25, /33, /50, @@ -1426,7 +1337,6 @@ config FB_TX3912 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>. @@ -1439,7 +1349,6 @@ config FB_G364 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help The G364 driver is the framebuffer used in MIPS Magnum 4000 and Olivetti M700-10 systems. @@ -1450,7 +1359,6 @@ config FB_68328 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR help Say Y here if you want to support the built-in frame buffer of the Motorola 68328 CPU family. @@ -1461,7 +1369,6 @@ config FB_PXA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- Frame buffer driver for the built-in LCD controller in the Intel PXA2x0 processor. @@ -1473,23 +1380,6 @@ config FB_PXA If unsure, say N. -config FB_W100 - tristate "W100 frame buffer support" - depends on FB && PXA_SHARPSL - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR - ---help--- - Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called vfb. If you want to compile it as a module, - say M here and read <file:Documentation/modules.txt>. - - If unsure, say N. - config FB_PXA_PARAMETERS bool "PXA LCD command line parameters" default n @@ -1507,17 +1397,21 @@ config FB_PXA_PARAMETERS <file:Documentation/fb/pxafb.txt> describes the available parameters. -config FB_S1D13XXX - tristate "Epson S1D13XXX framebuffer support" - depends on FB - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR - help - Support for S1D13XXX framebuffer device family (currently only - working with S1D13806). Product specs at - <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm> +config FB_W100 + tristate "W100 frame buffer support" + depends on FB && PXA_SHARPSL + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called vfb. If you want to compile it as a module, + say M here and read <file:Documentation/modules.txt>. + + If unsure, say N. config FB_S3C2410 tristate "S3C2410 LCD framebuffer support" @@ -1525,7 +1419,6 @@ config FB_S3C2410 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- Frame buffer driver for the built-in LCD controller in the Samsung S3C2410 processor. @@ -1549,7 +1442,6 @@ config FB_VIRTUAL select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- This is a `virtual' frame buffer device. It operates on a chunk of unswappable kernel memory instead of on the memory of a graphics diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 97c5d03ac8d..aa434e725c0 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -16,7 +16,6 @@ fb-objs := $(fb-y) obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o -obj-$(CONFIG_FB_SOFT_CURSOR) += softcursor.o obj-$(CONFIG_FB_MACMODES) += macmodes.o # Hardware specific drivers go first diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 9b6a39348f8..193b482570c 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -926,7 +926,6 @@ static struct fb_ops acornfb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_mmap = acornfb_mmap, - .fb_cursor = soft_cursor, }; /* diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index 4fc93dc2b4d..a3c2c45e29e 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c @@ -333,7 +333,6 @@ static struct fb_ops clcdfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, .fb_mmap = clcdfb_mmap, }; @@ -519,7 +518,7 @@ static struct amba_driver clcd_driver = { .id_table = clcdfb_id_table, }; -int __init amba_clcdfb_init(void) +static int __init amba_clcdfb_init(void) { if (fb_get_options("ambafb", NULL)) return -ENODEV; diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index cf8bb67462d..d549e215f3c 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -1185,7 +1185,6 @@ static struct fb_ops amifb_ops = { .fb_fillrect = amifb_fillrect, .fb_copyarea = amifb_copyarea, .fb_imageblit = amifb_imageblit, - .fb_cursor = soft_cursor, .fb_ioctl = amifb_ioctl, }; diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 126daff1c84..a1fc8bbb109 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -502,10 +502,6 @@ static ssize_t arcfb_write(struct file *file, const char *buf, size_t count, return err; } -static void arcfb_platform_release(struct device *device) -{ -} - static struct fb_ops arcfb_ops = { .owner = THIS_MODULE, .fb_open = arcfb_open, @@ -515,7 +511,6 @@ static struct fb_ops arcfb_ops = { .fb_fillrect = arcfb_fillrect, .fb_copyarea = arcfb_copyarea, .fb_imageblit = arcfb_imageblit, - .fb_cursor = soft_cursor, .fb_ioctl = arcfb_ioctl, }; @@ -624,13 +619,7 @@ static struct device_driver arcfb_driver = { .remove = arcfb_remove, }; -static struct platform_device arcfb_device = { - .name = "arcfb", - .id = 0, - .dev = { - .release = arcfb_platform_release, - } -}; +static struct platform_device *arcfb_device; static int __init arcfb_init(void) { @@ -641,9 +630,16 @@ static int __init arcfb_init(void) ret = driver_register(&arcfb_driver); if (!ret) { - ret = platform_device_register(&arcfb_device); - if (ret) + arcfb_device = platform_device_alloc("arcfb", 0); + if (arcfb_device) { + ret = platform_device_add(arcfb_device); + } else { + ret = -ENOMEM; + } + if (ret) { + platform_device_put(arcfb_device); driver_unregister(&arcfb_driver); + } } return ret; @@ -651,7 +647,7 @@ static int __init arcfb_init(void) static void __exit arcfb_exit(void) { - platform_device_unregister(&arcfb_device); + platform_device_unregister(arcfb_device); driver_unregister(&arcfb_driver); } diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index f4729f4df8c..c64de59398f 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c @@ -106,7 +106,6 @@ static struct fb_ops asiliantfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; /* Calculate the ratios for the dot clocks without using a single long long diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h index 13321c689cf..39ab483fc25 100644 --- a/drivers/video/aty/ati_ids.h +++ b/drivers/video/aty/ati_ids.h @@ -150,6 +150,7 @@ #define PCI_CHIP_RV200_QX 0x5158 #define PCI_CHIP_RV100_QY 0x5159 #define PCI_CHIP_RV100_QZ 0x515A +#define PCI_CHIP_RN50 0x515E #define PCI_CHIP_RAGE128RE 0x5245 #define PCI_CHIP_RAGE128RF 0x5246 #define PCI_CHIP_RAGE128RG 0x5247 diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index e380ee8b024..e686185a076 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -478,7 +478,6 @@ static struct fb_ops aty128fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; #ifdef CONFIG_PMAC_BACKLIGHT diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 037fe9d32fe..08edbfcfca5 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -292,7 +292,6 @@ static struct fb_ops atyfb_ops = { .fb_fillrect = atyfb_fillrect, .fb_copyarea = atyfb_copyarea, .fb_imageblit = atyfb_imageblit, - .fb_cursor = soft_cursor, #ifdef __sparc__ .fb_mmap = atyfb_mmap, #endif @@ -2157,11 +2156,38 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) static struct fb_info *fb_list = NULL; +#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) +static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par, + struct fb_var_screeninfo *var) +{ + int ret = -EINVAL; + + if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { + *var = default_var; + var->xres = var->xres_virtual = par->lcd_hdisp; + var->right_margin = par->lcd_right_margin; + var->left_margin = par->lcd_hblank_len - + (par->lcd_right_margin + par->lcd_hsync_dly + + par->lcd_hsync_len); + var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly; + var->yres = var->yres_virtual = par->lcd_vdisp; + var->lower_margin = par->lcd_lower_margin; + var->upper_margin = par->lcd_vblank_len - + (par->lcd_lower_margin + par->lcd_vsync_len); + var->vsync_len = par->lcd_vsync_len; + var->pixclock = par->lcd_pixclock; + ret = 0; + } + + return ret; +} +#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ + static int __init aty_init(struct fb_info *info, const char *name) { struct atyfb_par *par = (struct atyfb_par *) info->par; const char *ramname = NULL, *xtal; - int gtb_memsize; + int gtb_memsize, has_var = 0; struct fb_var_screeninfo var; u8 pll_ref_div; u32 i; @@ -2469,8 +2495,8 @@ static int __init aty_init(struct fb_info *info, const char *name) * applies to all Mac video cards */ if (mode) { - if (!mac_find_mode(&var, info, mode, 8)) - var = default_var; + if (mac_find_mode(&var, info, mode, 8)) + has_var = 1; } else { if (default_vmode == VMODE_CHOOSE) { if (M64_HAS(G3_PB_1024x768)) @@ -2492,20 +2518,23 @@ static int __init aty_init(struct fb_info *info, const char *name) default_vmode = VMODE_640_480_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; + if (!mac_vmode_to_var(default_vmode, default_cmode, + &var)) + has_var = 1; } - } else + } + #endif /* !CONFIG_PPC */ - if ( -#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) - /* On Sparc, unless the user gave a specific mode - * specification, use the PROM probed values in - * default_var. - */ - !mode || + +#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) + if (!atyfb_get_timings_from_lcd(par, &var)) + has_var = 1; #endif - !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8)) + + if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8)) + has_var = 1; + + if (!has_var) var = default_var; if (noaccel) diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 8a24a66d9ba..4f01ccc02aa 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -69,7 +69,6 @@ #include <linux/pci.h> #include <linux/vmalloc.h> #include <linux/device.h> -#include <linux/i2c.h> #include <asm/io.h> #include <asm/uaccess.h> @@ -113,6 +112,7 @@ static struct pci_device_id radeonfb_pci_table[] = { /* Radeon VE/7000 */ CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RN50, RV100, CHIP_HAS_CRTC2), /* Radeon IGP320M (U1) */ CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), /* Radeon IGP320 (A3) */ @@ -1874,7 +1874,6 @@ static struct fb_ops radeonfb_ops = { .fb_fillrect = radeonfb_fillrect, .fb_copyarea = radeonfb_copyarea, .fb_imageblit = radeonfb_imageblit, - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index 01b8b2f7851..217e00ab4a2 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h @@ -10,9 +10,10 @@ #include <linux/fb.h> +#ifdef CONFIG_FB_RADEON_I2C #include <linux/i2c.h> -#include <linux/i2c-id.h> #include <linux/i2c-algo-bit.h> +#endif #include <asm/io.h> diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index acc81cb01d5..9d5015e9937 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -5,7 +5,6 @@ * */ -#include <linux/version.h> #include <linux/module.h> #include <linux/init.h> #include <linux/device.h> diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 4867498f68e..bd9a6996aee 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -48,6 +48,12 @@ static void corgibl_send_intensity(int intensity) corgibl_mach_set_intensity(intensity); spin_unlock_irqrestore(&bl_lock, flags); + + corgi_kick_batt = symbol_get(sharpsl_battery_kick); + if (corgi_kick_batt) { + corgi_kick_batt(); + symbol_put(sharpsl_battery_kick); + } } static void corgibl_blank(int blank) diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 470e6f0ee4d..68c690605aa 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -5,7 +5,6 @@ * */ -#include <linux/version.h> #include <linux/module.h> #include <linux/init.h> #include <linux/device.h> diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 3d20b2d47d4..f53bf3ba127 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -51,7 +51,6 @@ static struct fb_ops bw2_ops = { .fb_imageblit = cfb_imageblit, .fb_mmap = bw2_mmap, .fb_ioctl = bw2_ioctl, - .fb_cursor = soft_cursor, }; /* OBio addresses for the bwtwo registers */ diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c index 67711f7b11b..cdc71572cf3 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/cfbcopyarea.c @@ -349,46 +349,10 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) unsigned long __iomem *dst = NULL, *src = NULL; int bits = BITS_PER_LONG, bytes = bits >> 3; int dst_idx = 0, src_idx = 0, rev_copy = 0; - int x2, y2, vxres, vyres; if (p->state != FBINFO_STATE_RUNNING) return; - /* We want rotation but lack hardware to do it for us. */ - if (!p->fbops->fb_rotate && p->var.rotate) { - } - - vxres = p->var.xres_virtual; - vyres = p->var.yres_virtual; - - if (area->dx > vxres || area->sx > vxres || - area->dy > vyres || area->sy > vyres) - return; - - /* clip the destination - * We could use hardware clipping but on many cards you get around - * hardware clipping by writing to framebuffer directly. - */ - x2 = area->dx + area->width; - y2 = area->dy + area->height; - dx = area->dx > 0 ? area->dx : 0; - dy = area->dy > 0 ? area->dy : 0; - x2 = x2 < vxres ? x2 : vxres; - y2 = y2 < vyres ? y2 : vyres; - width = x2 - dx; - height = y2 - dy; - - if ((width==0) ||(height==0)) - return; - - /* update sx1,sy1 */ - sx += (dx - area->dx); - sy += (dy - area->dy); - - /* the source must be completely inside the virtual screen */ - if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres) - return; - /* if the beginning of the target area might overlap with the end of the source area, be have to copy the area reverse. */ if ((dy == sy && dx > sx) || (dy > sy)) { diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c index e4fc42b013e..167d9314e6e 100644 --- a/drivers/video/cfbfillrect.c +++ b/drivers/video/cfbfillrect.c @@ -344,7 +344,8 @@ bitfill_unaligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) { - unsigned long x2, y2, vxres, vyres, height, width, pat, fg; + unsigned long pat, fg; + unsigned long width = rect->width, height = rect->height; int bits = BITS_PER_LONG, bytes = bits >> 3; u32 bpp = p->var.bits_per_pixel; unsigned long __iomem *dst; @@ -353,27 +354,6 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) if (p->state != FBINFO_STATE_RUNNING) return; - /* We want rotation but lack hardware to do it for us. */ - if (!p->fbops->fb_rotate && p->var.rotate) { - } - - vxres = p->var.xres_virtual; - vyres = p->var.yres_virtual; - - if (!rect->width || !rect->height || - rect->dx > vxres || rect->dy > vyres) - return; - - /* We could use hardware clipping but on many cards you get around - * hardware clipping by writing to framebuffer directly. */ - - x2 = rect->dx + rect->width; - y2 = rect->dy + rect->height; - x2 = x2 < vxres ? x2 : vxres; - y2 = y2 < vyres ? y2 : vyres; - width = x2 - rect->dx; - height = y2 - rect->dy; - if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR ) fg = ((u32 *) (p->pseudo_palette))[rect->color]; diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c index 4c123abaa84..a7770c4f17d 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/cfbimgblt.c @@ -80,10 +80,12 @@ static u32 cfb_tab32[] = { #define LEFT_POS(bpp) (32 - bpp) #define SHIFT_HIGH(val, bits) ((val) >> (bits)) #define SHIFT_LOW(val, bits) ((val) << (bits)) +#define BIT_NR(b) (7 - (b)) #else #define LEFT_POS(bpp) (0) #define SHIFT_HIGH(val, bits) ((val) << (bits)) #define SHIFT_LOW(val, bits) ((val) >> (bits)) +#define BIT_NR(b) (b) #endif static inline void color_imageblit(const struct fb_image *image, @@ -177,7 +179,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * while (j--) { l--; - color = (*s & (1 << l)) ? fgcolor : bgcolor; + color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor; color <<= LEFT_POS(bpp); val |= SHIFT_HIGH(color, shift); @@ -272,33 +274,13 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) { u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; - u32 width = image->width, height = image->height; + u32 width = image->width; u32 dx = image->dx, dy = image->dy; - int x2, y2, vxres, vyres; u8 __iomem *dst1; if (p->state != FBINFO_STATE_RUNNING) return; - vxres = p->var.xres_virtual; - vyres = p->var.yres_virtual; - /* - * We could use hardware clipping but on many cards you get around - * hardware clipping by writing to framebuffer directly like we are - * doing here. - */ - if (image->dx > vxres || image->dy > vyres) - return; - - x2 = image->dx + image->width; - y2 = image->dy + image->height; - dx = image->dx > 0 ? image->dx : 0; - dy = image->dy > 0 ? image->dy : 0; - x2 = x2 < vxres ? x2 : vxres; - y2 = y2 < vyres ? y2 : vyres; - width = x2 - dx; - height = y2 - dy; - bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); start_index = bitstart & (32 - 1); pitch_index = (p->fix.line_length & (bpl - 1)) * 8; diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 18e60b941e2..030d4b13b1c 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -49,7 +49,6 @@ static struct fb_ops cg14_ops = { .fb_imageblit = cfb_imageblit, .fb_mmap = cg14_mmap, .fb_ioctl = cg14_ioctl, - .fb_cursor = soft_cursor, }; #define CG14_MCR_INTENABLE_SHIFT 7 diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 6e7d8d45dc6..b94eee8c42d 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -50,7 +50,6 @@ static struct fb_ops cg3_ops = { .fb_imageblit = cfb_imageblit, .fb_mmap = cg3_mmap, .fb_ioctl = cg3_ioctl, - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 49a2545671d..414c4409e92 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -54,7 +54,6 @@ static struct fb_ops cg6_ops = { .fb_sync = cg6_sync, .fb_mmap = cg6_mmap, .fb_ioctl = cg6_ioctl, - .fb_cursor = soft_cursor, }; /* Offset of interesting structures in the OBIO space */ @@ -654,12 +653,6 @@ static void cg6_chip_init(struct fb_info *info) sbus_writel(0, &fbc->clipminy); sbus_writel(info->var.xres - 1, &fbc->clipmaxx); sbus_writel(info->var.yres - 1, &fbc->clipmaxy); - - /* Disable cursor in Brooktree DAC. */ - sbus_writel(0x06 << 24, &par->bt->addr); - tmp = sbus_readl(&par->bt->control); - tmp &= ~(0x03 << 24); - sbus_writel(tmp, &par->bt->control); } struct all_info { diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index 4131243cfdf..bc061d4ec78 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -91,7 +91,6 @@ static struct fb_ops chipsfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static int chipsfb_check_var(struct fb_var_screeninfo *var, diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 3a26f9cc858..2858c5c8ba3 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -548,7 +548,6 @@ static struct fb_ops cirrusfb_ops = { .fb_fillrect = cirrusfb_fillrect, .fb_copyarea = cirrusfb_copyarea, .fb_imageblit = cirrusfb_imageblit, - .fb_cursor = soft_cursor, }; /*--- Hardware Specific Routines -------------------------------------------*/ diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c index 8692e002986..50b78af0fa2 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/clps711xfb.c @@ -219,7 +219,6 @@ static struct fb_ops clps7111fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static int diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 6a9ae2b3d1a..94c5f1392cc 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -98,6 +98,18 @@ config FRAMEBUFFER_CONSOLE tristate "Framebuffer Console support" depends on FB select CRC32 + help + Low-level framebuffer-based console driver. + +config FRAMEBUFFER_CONSOLE_ROTATION + bool "Framebuffer Console Rotation" + depends on FRAMEBUFFER_CONSOLE + help + Enable display rotation for the framebuffer console. This is done + in software and may be significantly slower than a normally oriented + display. Note that the rotation is done at the console level only + such that other users of the framebuffer will remain normally + oriented. config STI_CONSOLE tristate "STI text console" @@ -203,5 +215,12 @@ config FONT_10x18 big letters. It fits between the sun 12x22 and the normal 8x16 font. If other fonts are too big or too small for you, say Y, otherwise say N. +config FONT_RL + bool "console Roman Large 8x16 font" if FONTS + depends on FRAMEBUFFER_CONSOLE + help + This is the visually-appealing "RL" console font that is + included with the kbd package. + endmenu diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index 42c7b8dcd22..fed600c9ca5 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile @@ -15,6 +15,7 @@ font-objs-$(CONFIG_FONT_10x18) += font_10x18.o font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o +font-objs-$(CONFIG_FONT_RL) += font_rl.o font-objs += $(font-objs-y) @@ -26,10 +27,14 @@ obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o obj-$(CONFIG_VGA_CONSOLE) += vgacon.o obj-$(CONFIG_MDA_CONSOLE) += mdacon.o -obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o +obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o ifeq ($(CONFIG_FB_TILEBLITTING),y) obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o endif +ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y) +obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ + fbcon_ccw.o +endif obj-$(CONFIG_FB_STI) += sticore.o font.o diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 9f70e512b88..e65fc3ef763 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -22,35 +22,6 @@ /* * Accelerated handlers. */ -#define FBCON_ATTRIBUTE_UNDERLINE 1 -#define FBCON_ATTRIBUTE_REVERSE 2 -#define FBCON_ATTRIBUTE_BOLD 4 - -static inline int real_y(struct display *p, int ypos) -{ - int rows = p->vrows; - - ypos += p->yscroll; - return ypos < rows ? ypos : ypos - rows; -} - - -static inline int get_attribute(struct fb_info *info, u16 c) -{ - int attribute = 0; - - if (fb_get_color_depth(&info->var, &info->fix) == 1) { - if (attr_underline(c)) - attribute |= FBCON_ATTRIBUTE_UNDERLINE; - if (attr_reverse(c)) - attribute |= FBCON_ATTRIBUTE_REVERSE; - if (attr_bold(c)) - attribute |= FBCON_ATTRIBUTE_BOLD; - } - - return attribute; -} - static inline void update_attr(u8 *dst, u8 *src, int attribute, struct vc_data *vc) { @@ -272,6 +243,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int w = (vc->vc_font.width + 7) >> 3, c; int y = real_y(p, vc->vc_y); int attribute, use_sw = (vc->vc_cursor_type & 0x10); + int err = 1; char *src; cursor.set = 0; @@ -408,11 +380,27 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, cursor.image.depth = 1; cursor.rop = ROP_XOR; - info->fbops->fb_cursor(info, &cursor); + if (info->fbops->fb_cursor) + err = info->fbops->fb_cursor(info, &cursor); + + if (err) + soft_cursor(info, &cursor); ops->cursor_reset = 0; } +static int bit_update_start(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + int err; + + err = fb_pan_display(info, &ops->var); + ops->var.xoffset = info->var.xoffset; + ops->var.yoffset = info->var.yoffset; + ops->var.vmode = info->var.vmode; + return err; +} + void fbcon_set_bitops(struct fbcon_ops *ops) { ops->bmove = bit_bmove; @@ -420,6 +408,11 @@ void fbcon_set_bitops(struct fbcon_ops *ops) ops->putcs = bit_putcs; ops->clear_margins = bit_clear_margins; ops->cursor = bit_cursor; + ops->update_start = bit_update_start; + ops->rotate_font = NULL; + + if (ops->rotate) + fbcon_set_rotate(ops); } EXPORT_SYMBOL(fbcon_set_bitops); diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 0fc8bb499c3..e7802ffe549 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -107,6 +107,8 @@ enum { }; struct display fb_display[MAX_NR_CONSOLES]; +EXPORT_SYMBOL(fb_display); + static signed char con2fb_map[MAX_NR_CONSOLES]; static signed char con2fb_map_boot[MAX_NR_CONSOLES]; static int logo_height; @@ -130,6 +132,9 @@ static char fontname[40]; /* current fb_info */ static int info_idx = -1; +/* console rotation */ +static int rotate; + static const struct consw fb_con; #define CM_SOFTBACK (8) @@ -176,7 +181,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines); /* * Internal routines */ -static __inline__ int real_y(struct display *p, int ypos); static __inline__ void ywrap_up(struct vc_data *vc, int count); static __inline__ void ywrap_down(struct vc_data *vc, int count); static __inline__ void ypan_up(struct vc_data *vc, int count); @@ -189,6 +193,8 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va int unit); static void fbcon_redraw_move(struct vc_data *vc, struct display *p, int line, int count, int dy); +static void fbcon_modechanged(struct fb_info *info); +static void fbcon_set_all_vcs(struct fb_info *info); #ifdef CONFIG_MAC /* @@ -203,6 +209,88 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) } #endif +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION +static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) +{ + struct fbcon_ops *ops = info->fbcon_par; + + if (!(info->flags & FBINFO_MISC_TILEBLITTING) && + p->con_rotate < 4) + ops->rotate = p->con_rotate; + else + ops->rotate = 0; +} + +static void fbcon_rotate(struct fb_info *info, u32 rotate) +{ + struct fbcon_ops *ops= info->fbcon_par; + struct fb_info *fb_info; + + if (!ops || ops->currcon == -1) + return; + + fb_info = registered_fb[con2fb_map[ops->currcon]]; + + if (info == fb_info) { + struct display *p = &fb_display[ops->currcon]; + + if (rotate < 4) + p->con_rotate = rotate; + else + p->con_rotate = 0; + + fbcon_modechanged(info); + } +} + +static void fbcon_rotate_all(struct fb_info *info, u32 rotate) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data *vc; + struct display *p; + int i; + + if (!ops || ops->currcon < 0 || rotate > 3) + return; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + vc = vc_cons[i].d; + if (!vc || vc->vc_mode != KD_TEXT || + registered_fb[con2fb_map[i]] != info) + continue; + + p = &fb_display[vc->vc_num]; + p->con_rotate = rotate; + } + + fbcon_set_all_vcs(info); +} +#else +static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) +{ + struct fbcon_ops *ops = info->fbcon_par; + + ops->rotate = FB_ROTATE_UR; +} + +static void fbcon_rotate(struct fb_info *info, u32 rotate) +{ + return; +} + +static void fbcon_rotate_all(struct fb_info *info, u32 rotate) +{ + return; +} +#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */ + +static int fbcon_get_rotate(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + + return (ops) ? ops->rotate : 0; +} + static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; @@ -281,6 +369,18 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info, return color; } +static void fbcon_update_softback(struct vc_data *vc) +{ + int l = fbcon_softback_size / vc->vc_size_row; + + if (l > 5) + softback_end = softback_buf + l * vc->vc_size_row; + else + /* Smaller scrollback makes no sense, and 0 would screw + the operation totally */ + softback_top = 0; +} + static void fb_flashcursor(void *private) { struct fb_info *info = private; @@ -410,6 +510,14 @@ static int __init fb_console_setup(char *this_opt) last_fb_vc = simple_strtoul(options, &options, 10) - 1; fbcon_is_default = 0; } + + if (!strncmp(options, "rotate:", 7)) { + options += 7; + if (*options) + rotate = simple_strtoul(options, &options, 0); + if (rotate > 3) + rotate = 0; + } } return 0; } @@ -468,6 +576,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, int cols, int rows, int new_cols, int new_rows) { /* Need to make room for the logo */ + struct fbcon_ops *ops = info->fbcon_par; int cnt, erase = vc->vc_video_erase_char, step; unsigned short *save = NULL, *r, *q; @@ -477,7 +586,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, */ if (fb_get_color_depth(&info->var, &info->fix) == 1) erase &= ~0x400; - logo_height = fb_prepare_logo(info); + logo_height = fb_prepare_logo(info, ops->rotate); logo_lines = (logo_height + vc->vc_font.height - 1) / vc->vc_font.height; q = (unsigned short *) (vc->vc_origin + @@ -546,16 +655,24 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info, if ((info->flags & FBINFO_MISC_TILEBLITTING)) fbcon_set_tileops(vc, info, p, ops); - else + else { + struct display *disp; + + disp = (p) ? p : &fb_display[vc->vc_num]; + fbcon_set_rotation(info, disp); fbcon_set_bitops(ops); + } } #else static void set_blitting_type(struct vc_data *vc, struct fb_info *info, struct display *p) { struct fbcon_ops *ops = info->fbcon_par; + struct display *disp; info->flags &= ~FBINFO_MISC_TILEBLITTING; + disp = (p) ? p : &fb_display[vc->vc_num]; + fbcon_set_rotation(info, disp); fbcon_set_bitops(ops); } #endif /* CONFIG_MISC_TILEBLITTING */ @@ -615,9 +732,19 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, fbcon_del_cursor_timer(oldinfo); kfree(ops->cursor_state.mask); kfree(ops->cursor_data); + kfree(ops->fontbuffer); kfree(oldinfo->fbcon_par); oldinfo->fbcon_par = NULL; module_put(oldinfo->fbops->owner); + /* + If oldinfo and newinfo are driving the same hardware, + the fb_release() method of oldinfo may attempt to + restore the hardware state. This will leave the + newinfo in an undefined state. Thus, a call to + fb_set_par() may be needed for the newinfo. + */ + if (newinfo->fbops->fb_set_par) + newinfo->fbops->fb_set_par(newinfo); } return err; @@ -806,7 +933,9 @@ static const char *fbcon_startup(void) memset(ops, 0, sizeof(struct fbcon_ops)); ops->currcon = -1; ops->graphics = 1; + ops->cur_rotate = -1; info->fbcon_par = ops; + p->con_rotate = rotate; set_blitting_type(vc, info, NULL); if (info->fix.type != FB_TYPE_TEXT) { @@ -845,8 +974,10 @@ static const char *fbcon_startup(void) vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ } - cols = info->var.xres / vc->vc_font.width; - rows = info->var.yres / vc->vc_font.height; + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; vc_resize(vc, cols, rows); DPRINTK("mode: %s\n", info->fix.id); @@ -932,8 +1063,6 @@ static void fbcon_init(struct vc_data *vc, int init) (info->fix.type == FB_TYPE_TEXT)) logo = 0; - info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */ - if (var_to_display(p, &info->var, info)) return; @@ -965,13 +1094,18 @@ static void fbcon_init(struct vc_data *vc, int init) if (!*vc->vc_uni_pagedir_loc) con_copy_unimap(vc, svc); + ops = info->fbcon_par; + p->con_rotate = rotate; + set_blitting_type(vc, info, NULL); + cols = vc->vc_cols; rows = vc->vc_rows; - new_cols = info->var.xres / vc->vc_font.width; - new_rows = info->var.yres / vc->vc_font.height; + new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + new_cols /= vc->vc_font.width; + new_rows /= vc->vc_font.height; vc_resize(vc, new_cols, new_rows); - ops = info->fbcon_par; /* * We must always set the mode. The mode of the previous console * driver could be in the same resolution but we are using different @@ -1007,16 +1141,14 @@ static void fbcon_init(struct vc_data *vc, int init) if (logo) fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); - if (vc == svc && softback_buf) { - int l = fbcon_softback_size / vc->vc_size_row; - if (l > 5) - softback_end = softback_buf + l * vc->vc_size_row; - else { - /* Smaller scrollback makes no sense, and 0 would screw - the operation totally */ - softback_top = 0; - } + if (vc == svc && softback_buf) + fbcon_update_softback(vc); + + if (ops->rotate_font && ops->rotate_font(info, vc, p)) { + ops->rotate = FB_ROTATE_UR; + set_blitting_type(vc, info, p); } + } static void fbcon_deinit(struct vc_data *vc) @@ -1053,15 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc) * restriction is simplicity & efficiency at the moment. */ -static __inline__ int real_y(struct display *p, int ypos) -{ - int rows = p->vrows; - - ypos += p->yscroll; - return ypos < rows ? ypos : ypos - rows; -} - - static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, int width) { @@ -1149,13 +1272,6 @@ static int scrollback_phys_max = 0; static int scrollback_max = 0; static int scrollback_current = 0; -static int update_var(int con, struct fb_info *info) -{ - if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon) - return fb_pan_display(info, &info->var); - return 0; -} - /* * If no vc is existent yet, just set struct display */ @@ -1165,7 +1281,6 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va struct display *p = &fb_display[unit]; struct display *t = &fb_display[fg_console]; - var->xoffset = var->yoffset = p->yscroll = 0; if (var_to_display(p, var, info)) return; @@ -1181,9 +1296,9 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, struct display *p = &fb_display[vc->vc_num], *t; struct vc_data **default_mode = vc->vc_display_fg; struct vc_data *svc = *default_mode; + struct fbcon_ops *ops = info->fbcon_par; int rows, cols, charcnt = 256; - var->xoffset = var->yoffset = p->yscroll = 0; if (var_to_display(p, var, info)) return; t = &fb_display[svc->vc_num]; @@ -1200,9 +1315,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, var->activate = FB_ACTIVATE_NOW; info->var.activate = var->activate; - info->var.yoffset = info->var.xoffset = 0; + var->yoffset = info->var.yoffset; + var->xoffset = info->var.xoffset; fb_set_var(info, var); - + ops->var = info->var; vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { @@ -1218,38 +1334,32 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, if (!*vc->vc_uni_pagedir_loc) con_copy_unimap(vc, svc); - cols = var->xres / vc->vc_font.width; - rows = var->yres / vc->vc_font.height; + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; vc_resize(vc, cols, rows); + if (CON_IS_VISIBLE(vc)) { update_screen(vc); - if (softback_buf) { - int l = fbcon_softback_size / vc->vc_size_row; - - if (l > 5) - softback_end = softback_buf + l * - vc->vc_size_row; - else { - /* Smaller scrollback makes no sense, and 0 - would screw the operation totally */ - softback_top = 0; - } - } + if (softback_buf) + fbcon_update_softback(vc); } } static __inline__ void ywrap_up(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; p->yscroll += count; if (p->yscroll >= p->vrows) /* Deal with wrap */ p->yscroll -= p->vrows; - info->var.xoffset = 0; - info->var.yoffset = p->yscroll * vc->vc_font.height; - info->var.vmode |= FB_VMODE_YWRAP; - update_var(vc->vc_num, info); + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode |= FB_VMODE_YWRAP; + ops->update_start(info); scrollback_max += count; if (scrollback_max > scrollback_phys_max) scrollback_max = scrollback_phys_max; @@ -1259,15 +1369,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count) static __inline__ void ywrap_down(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; p->yscroll -= count; if (p->yscroll < 0) /* Deal with wrap */ p->yscroll += p->vrows; - info->var.xoffset = 0; - info->var.yoffset = p->yscroll * vc->vc_font.height; - info->var.vmode |= FB_VMODE_YWRAP; - update_var(vc->vc_num, info); + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode |= FB_VMODE_YWRAP; + ops->update_start(info); scrollback_max -= count; if (scrollback_max < 0) scrollback_max = 0; @@ -1286,10 +1397,11 @@ static __inline__ void ypan_up(struct vc_data *vc, int count) 0, 0, 0, vc->vc_rows, vc->vc_cols); p->yscroll -= p->vrows - vc->vc_rows; } - info->var.xoffset = 0; - info->var.yoffset = p->yscroll * vc->vc_font.height; - info->var.vmode &= ~FB_VMODE_YWRAP; - update_var(vc->vc_num, info); + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); fbcon_clear_margins(vc, 1); scrollback_max += count; if (scrollback_max > scrollback_phys_max) @@ -1300,6 +1412,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count) static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; int redraw = 0; @@ -1309,12 +1422,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) redraw = 1; } - info->var.xoffset = 0; - info->var.yoffset = p->yscroll * vc->vc_font.height; - info->var.vmode &= ~FB_VMODE_YWRAP; if (redraw) fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); - update_var(vc->vc_num, info); + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); fbcon_clear_margins(vc, 1); scrollback_max += count; if (scrollback_max > scrollback_phys_max) @@ -1334,10 +1448,11 @@ static __inline__ void ypan_down(struct vc_data *vc, int count) 0, vc->vc_rows, vc->vc_cols); p->yscroll += p->vrows - vc->vc_rows; } - info->var.xoffset = 0; - info->var.yoffset = p->yscroll * vc->vc_font.height; - info->var.vmode &= ~FB_VMODE_YWRAP; - update_var(vc->vc_num, info); + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); fbcon_clear_margins(vc, 1); scrollback_max -= count; if (scrollback_max < 0) @@ -1348,6 +1463,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count) static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; int redraw = 0; @@ -1356,12 +1472,14 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) p->yscroll += p->vrows - vc->vc_rows; redraw = 1; } - info->var.xoffset = 0; - info->var.yoffset = p->yscroll * vc->vc_font.height; - info->var.vmode &= ~FB_VMODE_YWRAP; + if (redraw) fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); - update_var(vc->vc_num, info); + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); fbcon_clear_margins(vc, 1); scrollback_max -= count; if (scrollback_max < 0) @@ -1835,31 +1953,41 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s height, width); } -static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, +static __inline__ void updatescrollmode(struct display *p, + struct fb_info *info, struct vc_data *vc) { + struct fbcon_ops *ops = info->fbcon_par; int fh = vc->vc_font.height; int cap = info->flags; - int good_pan = (cap & FBINFO_HWACCEL_YPAN) - && divides(info->fix.ypanstep, vc->vc_font.height) - && info->var.yres_virtual > info->var.yres; - int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) - && divides(info->fix.ywrapstep, vc->vc_font.height) - && divides(vc->vc_font.height, info->var.yres_virtual); + u16 t = 0; + int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep, + info->fix.xpanstep); + int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t); + int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual, + info->var.xres_virtual); + int good_pan = (cap & FBINFO_HWACCEL_YPAN) && + divides(ypan, vc->vc_font.height) && vyres > yres; + int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) && + divides(ywrap, vc->vc_font.height) && + divides(vc->vc_font.height, vyres); int reading_fast = cap & FBINFO_READS_FAST; - int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED); - int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && !(cap & FBINFO_HWACCEL_DISABLED); - - p->vrows = info->var.yres_virtual/fh; - if (info->var.yres > (fh * (vc->vc_rows + 1))) - p->vrows -= (info->var.yres - (fh * vc->vc_rows)) / fh; - if ((info->var.yres % fh) && (info->var.yres_virtual % fh < - info->var.yres % fh)) + int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && + !(cap & FBINFO_HWACCEL_DISABLED); + int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && + !(cap & FBINFO_HWACCEL_DISABLED); + + p->vrows = vyres/fh; + if (yres > (fh * (vc->vc_rows + 1))) + p->vrows -= (yres - (fh * vc->vc_rows)) / fh; + if ((yres % fh) && (vyres % fh < yres % fh)) p->vrows--; if (good_wrap || good_pan) { if (reading_fast || fast_copyarea) - p->scrollmode = good_wrap ? SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; + p->scrollmode = good_wrap ? + SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; else p->scrollmode = good_wrap ? SCROLL_REDRAW : SCROLL_PAN_REDRAW; @@ -1875,41 +2003,34 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, unsigned int height) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; struct fb_var_screeninfo var = info->var; - int x_diff, y_diff; - int fw = vc->vc_font.width; - int fh = vc->vc_font.height; - - var.xres = width * fw; - var.yres = height * fh; + int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh; + + virt_w = FBCON_SWAP(ops->rotate, width, height); + virt_h = FBCON_SWAP(ops->rotate, height, width); + virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width, + vc->vc_font.height); + virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height, + vc->vc_font.width); + var.xres = virt_w * virt_fw; + var.yres = virt_h * virt_fh; x_diff = info->var.xres - var.xres; y_diff = info->var.yres - var.yres; - if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) { + if (x_diff < 0 || x_diff > virt_fw || + y_diff < 0 || y_diff > virt_fh) { struct fb_videomode *mode; DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); mode = fb_find_best_mode(&var, &info->modelist); if (mode == NULL) return -EINVAL; + display_to_var(&var, p); fb_videomode_to_var(&var, mode); - if (width > var.xres/fw || height > var.yres/fh) + + if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh) return -EINVAL; - /* - * The following can probably have any value... Do we need to - * set all of them? - */ - var.bits_per_pixel = p->bits_per_pixel; - var.xres_virtual = p->xres_virtual; - var.yres_virtual = p->yres_virtual; - var.accel_flags = p->accel_flags; - var.width = p->width; - var.height = p->height; - var.red = p->red; - var.green = p->green; - var.blue = p->blue; - var.transp = p->transp; - var.nonstd = p->nonstd; DPRINTK("resize now %ix%i\n", var.xres, var.yres); if (CON_IS_VISIBLE(vc)) { @@ -1918,6 +2039,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, fb_set_var(info, &var); } var_to_display(p, &info->var, info); + ops->var = info->var; } updatescrollmode(p, info, vc); return 0; @@ -1926,26 +2048,20 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, static int fbcon_switch(struct vc_data *vc) { struct fb_info *info, *old_info = NULL; + struct fbcon_ops *ops; struct display *p = &fb_display[vc->vc_num]; struct fb_var_screeninfo var; int i, prev_console; info = registered_fb[con2fb_map[vc->vc_num]]; + ops = info->fbcon_par; if (softback_top) { - int l = fbcon_softback_size / vc->vc_size_row; if (softback_lines) fbcon_set_origin(vc); softback_top = softback_curr = softback_in = softback_buf; softback_lines = 0; - - if (l > 5) - softback_end = softback_buf + l * vc->vc_size_row; - else { - /* Smaller scrollback makes no sense, and 0 would screw - the operation totally */ - softback_top = 0; - } + fbcon_update_softback(vc); } if (logo_shown >= 0) { @@ -1957,7 +2073,7 @@ static int fbcon_switch(struct vc_data *vc) logo_shown = FBCON_LOGO_CANSHOW; } - prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; + prev_console = ops->currcon; if (prev_console != -1) old_info = registered_fb[con2fb_map[prev_console]]; /* @@ -1970,9 +2086,9 @@ static int fbcon_switch(struct vc_data *vc) */ for (i = 0; i < FB_MAX; i++) { if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { - struct fbcon_ops *ops = registered_fb[i]->fbcon_par; + struct fbcon_ops *o = registered_fb[i]->fbcon_par; - ops->currcon = vc->vc_num; + o->currcon = vc->vc_num; } } memset(&var, 0, sizeof(struct fb_var_screeninfo)); @@ -1984,8 +2100,11 @@ static int fbcon_switch(struct vc_data *vc) * in fb_set_var() */ info->var.activate = var.activate; - info->var.yoffset = info->var.xoffset = p->yscroll = 0; + var.yoffset = info->var.yoffset; + var.xoffset = info->var.xoffset; + var.vmode = info->var.vmode; fb_set_var(info, &var); + ops->var = info->var; if (old_info != NULL && old_info != info) { if (info->fbops->fb_set_par) @@ -1995,7 +2114,12 @@ static int fbcon_switch(struct vc_data *vc) } set_blitting_type(vc, info, p); - ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; + ops->cursor_reset = 1; + + if (ops->rotate_font && ops->rotate_font(info, vc, p)) { + ops->rotate = FB_ROTATE_UR; + set_blitting_type(vc, info, p); + } vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; @@ -2015,10 +2139,11 @@ static int fbcon_switch(struct vc_data *vc) scrollback_phys_max = 0; break; } + scrollback_max = 0; scrollback_current = 0; - - update_var(vc->vc_num, info); + ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; + ops->update_start(info); fbcon_set_palette(vc, color_table); fbcon_clear_margins(vc, 0); @@ -2026,7 +2151,7 @@ static int fbcon_switch(struct vc_data *vc) logo_shown = fg_console; /* This is protected above by initmem_freed */ - fb_show_logo(info); + fb_show_logo(info, ops->rotate); update_region(vc, vc->vc_origin + vc->vc_size_row * vc->vc_top, vc->vc_size_row * (vc->vc_bottom - @@ -2065,6 +2190,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; fb_set_var(info, &var); ops->graphics = 0; + ops->var = info->var; } } @@ -2153,6 +2279,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, const u8 * data, int userfont) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; int resize; int cnt; @@ -2232,20 +2359,15 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, } if (resize) { - /* reset wrap/pan */ - info->var.xoffset = info->var.yoffset = p->yscroll = 0; - vc_resize(vc, info->var.xres / w, info->var.yres / h); - if (CON_IS_VISIBLE(vc) && softback_buf) { - int l = fbcon_softback_size / vc->vc_size_row; - if (l > 5) - softback_end = - softback_buf + l * vc->vc_size_row; - else { - /* Smaller scrollback makes no sense, and 0 would screw - the operation totally */ - softback_top = 0; - } - } + int cols, rows; + + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= w; + rows /= h; + vc_resize(vc, cols, rows); + if (CON_IS_VISIBLE(vc) && softback_buf) + fbcon_update_softback(vc); } else if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { fbcon_clear_margins(vc, 0); @@ -2471,6 +2593,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt) static int fbcon_scrolldelta(struct vc_data *vc, int lines) { struct fb_info *info = registered_fb[con2fb_map[fg_console]]; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[fg_console]; int offset, limit, scrollback_old; @@ -2547,9 +2670,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) offset += limit; else if (offset >= limit) offset -= limit; - info->var.xoffset = 0; - info->var.yoffset = offset * vc->vc_font.height; - update_var(vc->vc_num, info); + + ops->var.xoffset = 0; + ops->var.yoffset = offset * vc->vc_font.height; + ops->update_start(info); + if (!scrollback_current) fbcon_cursor(vc, CM_DRAW); return 0; @@ -2597,34 +2722,29 @@ static void fbcon_modechanged(struct fb_info *info) if (!ops || ops->currcon < 0) return; vc = vc_cons[ops->currcon].d; - if (vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info) + if (vc->vc_mode != KD_TEXT || + registered_fb[con2fb_map[ops->currcon]] != info) return; p = &fb_display[vc->vc_num]; - - info->var.xoffset = info->var.yoffset = p->yscroll = 0; + set_blitting_type(vc, info, p); if (CON_IS_VISIBLE(vc)) { var_to_display(p, &info->var, info); - cols = info->var.xres / vc->vc_font.width; - rows = info->var.yres / vc->vc_font.height; + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; vc_resize(vc, cols, rows); updatescrollmode(p, info, vc); scrollback_max = 0; scrollback_current = 0; - update_var(vc->vc_num, info); + ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; + ops->update_start(info); fbcon_set_palette(vc, color_table); update_screen(vc); - if (softback_buf) { - int l = fbcon_softback_size / vc->vc_size_row; - if (l > 5) - softback_end = softback_buf + l * vc->vc_size_row; - else { - /* Smaller scrollback makes no sense, and 0 - would screw the operation totally */ - softback_top = 0; - } - } + if (softback_buf) + fbcon_update_softback(vc); } } @@ -2645,30 +2765,24 @@ static void fbcon_set_all_vcs(struct fb_info *info) continue; p = &fb_display[vc->vc_num]; - - info->var.xoffset = info->var.yoffset = p->yscroll = 0; + set_blitting_type(vc, info, p); var_to_display(p, &info->var, info); - cols = info->var.xres / vc->vc_font.width; - rows = info->var.yres / vc->vc_font.height; + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; vc_resize(vc, cols, rows); if (CON_IS_VISIBLE(vc)) { updatescrollmode(p, info, vc); scrollback_max = 0; scrollback_current = 0; - update_var(vc->vc_num, info); + ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; + ops->update_start(info); fbcon_set_palette(vc, color_table); update_screen(vc); - if (softback_buf) { - int l = fbcon_softback_size / vc->vc_size_row; - if (l > 5) - softback_end = softback_buf + l * vc->vc_size_row; - else { - /* Smaller scrollback makes no sense, and 0 - would screw the operation totally */ - softback_top = 0; - } - } + if (softback_buf) + fbcon_update_softback(vc); } } } @@ -2758,7 +2872,8 @@ static void fbcon_new_modelist(struct fb_info *info) continue; vc = vc_cons[i].d; display_to_var(&var, &fb_display[i]); - mode = fb_find_nearest_mode(&var, &info->modelist); + mode = fb_find_nearest_mode(fb_display[i].mode, + &info->modelist); fb_videomode_to_var(&var, mode); if (vc) @@ -2813,6 +2928,14 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_NEW_MODELIST: fbcon_new_modelist(info); break; + case FB_EVENT_SET_CON_ROTATE: + fbcon_rotate(info, *(int *)event->data); + break; + case FB_EVENT_GET_CON_ROTATE: + ret = fbcon_get_rotate(info); + break; + case FB_EVENT_SET_CON_ROTATE_ALL: + fbcon_rotate_all(info, *(int *)event->data); } return ret; diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index 0738cd62def..accfd7bd8e9 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -27,15 +27,15 @@ */ struct display { - /* Filled in by the frame buffer device */ - u_short inverse; /* != 0 text black on white as default */ /* Filled in by the low-level console driver */ const u_char *fontdata; int userfont; /* != 0 if fontdata kmalloc()ed */ u_short scrollmode; /* Scroll Method */ + u_short inverse; /* != 0 text black on white as default */ short yscroll; /* Hardware scrolling */ int vrows; /* number of virtual rows */ int cursor_shape; + int con_rotate; u32 xres_virtual; u32 yres_virtual; u32 height; @@ -52,6 +52,8 @@ struct display { struct fb_videomode *mode; }; +extern struct display fb_display[]; + struct fbcon_ops { void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, int sx, int dy, int dx, int height, int width); @@ -63,8 +65,12 @@ struct fbcon_ops { void (*clear_margins)(struct vc_data *vc, struct fb_info *info, int bottom_only); void (*cursor)(struct vc_data *vc, struct fb_info *info, - struct display *p, int mode, int softback_lines, int fg, int bg); - + struct display *p, int mode, int softback_lines, + int fg, int bg); + int (*update_start)(struct fb_info *info); + int (*rotate_font)(struct fb_info *info, struct vc_data *vc, + struct display *p); + struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ struct timer_list cursor_timer; /* Cursor timer */ struct fb_cursor cursor_state; int currcon; /* Current VC. */ @@ -73,7 +79,12 @@ struct fbcon_ops { int blank_state; int graphics; int flags; + int rotate; + int cur_rotate; char *cursor_data; + u8 *fontbuffer; + u8 *fontdata; + u32 fd_size; }; /* * Attribute Decoding @@ -167,5 +178,48 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, struct display *p, struct fbcon_ops *ops); #endif extern void fbcon_set_bitops(struct fbcon_ops *ops); +extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); + +#define FBCON_ATTRIBUTE_UNDERLINE 1 +#define FBCON_ATTRIBUTE_REVERSE 2 +#define FBCON_ATTRIBUTE_BOLD 4 + +static inline int real_y(struct display *p, int ypos) +{ + int rows = p->vrows; + + ypos += p->yscroll; + return ypos < rows ? ypos : ypos - rows; +} + + +static inline int get_attribute(struct fb_info *info, u16 c) +{ + int attribute = 0; + + if (fb_get_color_depth(&info->var, &info->fix) == 1) { + if (attr_underline(c)) + attribute |= FBCON_ATTRIBUTE_UNDERLINE; + if (attr_reverse(c)) + attribute |= FBCON_ATTRIBUTE_REVERSE; + if (attr_bold(c)) + attribute |= FBCON_ATTRIBUTE_BOLD; + } + + return attribute; +} + +#define FBCON_SWAP(i,r,v) ({ \ + typeof(r) _r = (r); \ + typeof(v) _v = (v); \ + (void) (&_r == &_v); \ + (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; }) + +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION +extern void fbcon_set_rotate(struct fbcon_ops *ops); +#else +#define fbcon_set_rotate(x) do {} while(0) +#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */ #endif /* _VIDEO_FBCON_H */ + diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c new file mode 100644 index 00000000000..680aabab73c --- /dev/null +++ b/drivers/video/console/fbcon_ccw.c @@ -0,0 +1,428 @@ +/* + * linux/drivers/video/console/fbcon_ccw.c -- Software Rotation - 270 degrees + * + * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/fb.h> +#include <linux/vt_kern.h> +#include <linux/console.h> +#include <asm/types.h> +#include "fbcon.h" +#include "fbcon_rotate.h" + +/* + * Rotation 270 degrees + */ + +static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute, + struct vc_data *vc) +{ + int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2; + int width = (vc->vc_font.height + 7) >> 3; + int mod = vc->vc_font.height % 8; + u8 c, msk = ~(0xff << offset), msk1 = 0; + + if (mod) + msk <<= (8 - mod); + + if (offset > mod) + set_bit(FBCON_BIT(7), (void *)&msk1); + + for (i = 0; i < vc->vc_font.width; i++) { + for (j = 0; j < width; j++) { + c = *src; + + if (attribute & FBCON_ATTRIBUTE_UNDERLINE) { + if (j == width - 1) + c |= msk; + + if (msk1 && j == width - 2) + c |= msk1; + } + + if (attribute & FBCON_ATTRIBUTE_BOLD && i) + *(dst - width) |= c; + + if (attribute & FBCON_ATTRIBUTE_REVERSE) + c = ~c; + src++; + *dst++ = c; + } + } +} + + +static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy, + int sx, int dy, int dx, int height, int width) +{ + struct display *p = &fb_display[vc->vc_num]; + struct fb_copyarea area; + u32 vyres = GETVYRES(p->scrollmode, info); + + area.sx = sy * vc->vc_font.height; + area.sy = vyres - ((sx + width) * vc->vc_font.width); + area.dx = dy * vc->vc_font.height; + area.dy = vyres - ((dx + width) * vc->vc_font.width); + area.width = height * vc->vc_font.height; + area.height = width * vc->vc_font.width; + + info->fbops->fb_copyarea(info, &area); +} + +static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy, + int sx, int height, int width) +{ + struct display *p = &fb_display[vc->vc_num]; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + u32 vyres = GETVYRES(p->scrollmode, info); + + region.color = attr_bgcol_ec(bgshift,vc); + region.dx = sy * vc->vc_font.height; + region.dy = vyres - ((sx + width) * vc->vc_font.width); + region.height = width * vc->vc_font.width; + region.width = height * vc->vc_font.height; + region.rop = ROP_COPY; + + info->fbops->fb_fillrect(info, ®ion); +} + +static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info, + const u16 *s, u32 attr, u32 cnt, + u32 d_pitch, u32 s_pitch, u32 cellsize, + struct fb_image *image, u8 *buf, u8 *dst) +{ + struct fbcon_ops *ops = info->fbcon_par; + u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + u32 idx = (vc->vc_font.height + 7) >> 3; + u8 *src; + + while (cnt--) { + src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize; + + if (attr) { + ccw_update_attr(buf, src, attr, vc); + src = buf; + } + + if (likely(idx == 1)) + __fb_pad_aligned_buffer(dst, d_pitch, src, idx, + vc->vc_font.width); + else + fb_pad_aligned_buffer(dst, d_pitch, src, idx, + vc->vc_font.width); + + dst += d_pitch * vc->vc_font.width; + } + + info->fbops->fb_imageblit(info, image); +} + +static void ccw_putcs(struct vc_data *vc, struct fb_info *info, + const unsigned short *s, int count, int yy, int xx, + int fg, int bg) +{ + struct fb_image image; + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + u32 width = (vc->vc_font.height + 7)/8; + u32 cellsize = width * vc->vc_font.width; + u32 maxcnt = info->pixmap.size/cellsize; + u32 scan_align = info->pixmap.scan_align - 1; + u32 buf_align = info->pixmap.buf_align - 1; + u32 cnt, pitch, size; + u32 attribute = get_attribute(info, scr_readw(s)); + u8 *dst, *buf = NULL; + u32 vyres = GETVYRES(p->scrollmode, info); + + if (!ops->fontbuffer) + return; + + image.fg_color = fg; + image.bg_color = bg; + image.dx = yy * vc->vc_font.height; + image.dy = vyres - ((xx + count) * vc->vc_font.width); + image.width = vc->vc_font.height; + image.depth = 1; + + if (attribute) { + buf = kmalloc(cellsize, GFP_KERNEL); + if (!buf) + return; + } + + s += count - 1; + + while (count) { + if (count > maxcnt) + cnt = maxcnt; + else + cnt = count; + + image.height = vc->vc_font.width * cnt; + pitch = ((image.width + 7) >> 3) + scan_align; + pitch &= ~scan_align; + size = pitch * image.height + buf_align; + size &= ~buf_align; + dst = fb_get_buffer_offset(info, &info->pixmap, size); + image.data = dst; + ccw_putcs_aligned(vc, info, s, attribute, cnt, pitch, + width, cellsize, &image, buf, dst); + image.dy += image.height; + count -= cnt; + s -= cnt; + } + + /* buf is always NULL except when in monochrome mode, so in this case + it's a gain to check buf against NULL even though kfree() handles + NULL pointers just fine */ + if (unlikely(buf)) + kfree(buf); + +} + +static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only) +{ + unsigned int cw = vc->vc_font.width; + unsigned int ch = vc->vc_font.height; + unsigned int rw = info->var.yres - (vc->vc_cols*cw); + unsigned int bh = info->var.xres - (vc->vc_rows*ch); + unsigned int bs = vc->vc_rows*ch; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + + region.color = attr_bgcol_ec(bgshift,vc); + region.rop = ROP_COPY; + + if (rw && !bottom_only) { + region.dx = 0; + region.dy = info->var.yoffset; + region.height = rw; + region.width = info->var.xres_virtual; + info->fbops->fb_fillrect(info, ®ion); + } + + if (bh) { + region.dx = info->var.xoffset + bs; + region.dy = 0; + region.height = info->var.yres_virtual; + region.width = bh; + info->fbops->fb_fillrect(info, ®ion); + } +} + +static void ccw_cursor(struct vc_data *vc, struct fb_info *info, + struct display *p, int mode, int softback_lines, + int fg, int bg) +{ + struct fb_cursor cursor; + struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + int w = (vc->vc_font.height + 7) >> 3, c; + int y = real_y(p, vc->vc_y); + int attribute, use_sw = (vc->vc_cursor_type & 0x10); + int err = 1, dx, dy; + char *src; + u32 vyres = GETVYRES(p->scrollmode, info); + + if (!ops->fontbuffer) + return; + + cursor.set = 0; + + if (softback_lines) { + if (y + softback_lines >= vc->vc_rows) { + mode = CM_ERASE; + ops->cursor_flash = 0; + return; + } else + y += softback_lines; + } + + c = scr_readw((u16 *) vc->vc_pos); + attribute = get_attribute(info, c); + src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width)); + + if (ops->cursor_state.image.data != src || + ops->cursor_reset) { + ops->cursor_state.image.data = src; + cursor.set |= FB_CUR_SETIMAGE; + } + + if (attribute) { + u8 *dst; + + dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC); + if (!dst) + return; + kfree(ops->cursor_data); + ops->cursor_data = dst; + ccw_update_attr(dst, src, attribute, vc); + src = dst; + } + + if (ops->cursor_state.image.fg_color != fg || + ops->cursor_state.image.bg_color != bg || + ops->cursor_reset) { + ops->cursor_state.image.fg_color = fg; + ops->cursor_state.image.bg_color = bg; + cursor.set |= FB_CUR_SETCMAP; + } + + if (ops->cursor_state.image.height != vc->vc_font.width || + ops->cursor_state.image.width != vc->vc_font.height || + ops->cursor_reset) { + ops->cursor_state.image.height = vc->vc_font.width; + ops->cursor_state.image.width = vc->vc_font.height; + cursor.set |= FB_CUR_SETSIZE; + } + + dx = y * vc->vc_font.height; + dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width); + + if (ops->cursor_state.image.dx != dx || + ops->cursor_state.image.dy != dy || + ops->cursor_reset) { + ops->cursor_state.image.dx = dx; + ops->cursor_state.image.dy = dy; + cursor.set |= FB_CUR_SETPOS; + } + + if (ops->cursor_state.hot.x || ops->cursor_state.hot.y || + ops->cursor_reset) { + ops->cursor_state.hot.x = cursor.hot.y = 0; + cursor.set |= FB_CUR_SETHOT; + } + + if (cursor.set & FB_CUR_SETSIZE || + vc->vc_cursor_type != p->cursor_shape || + ops->cursor_state.mask == NULL || + ops->cursor_reset) { + char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); + int cur_height, size, i = 0; + int width = (vc->vc_font.width + 7)/8; + + if (!mask) + return; + + tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC); + + if (!tmp) { + kfree(mask); + return; + } + + kfree(ops->cursor_state.mask); + ops->cursor_state.mask = mask; + + p->cursor_shape = vc->vc_cursor_type; + cursor.set |= FB_CUR_SETSHAPE; + + switch (p->cursor_shape & CUR_HWMASK) { + case CUR_NONE: + cur_height = 0; + break; + case CUR_UNDERLINE: + cur_height = (vc->vc_font.height < 10) ? 1 : 2; + break; + case CUR_LOWER_THIRD: + cur_height = vc->vc_font.height/3; + break; + case CUR_LOWER_HALF: + cur_height = vc->vc_font.height >> 1; + break; + case CUR_TWO_THIRDS: + cur_height = (vc->vc_font.height << 1)/3; + break; + case CUR_BLOCK: + default: + cur_height = vc->vc_font.height; + break; + } + + size = (vc->vc_font.height - cur_height) * width; + while (size--) + tmp[i++] = 0; + size = cur_height * width; + while (size--) + tmp[i++] = 0xff; + memset(mask, 0, w * vc->vc_font.width); + rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height); + kfree(tmp); + } + + switch (mode) { + case CM_ERASE: + ops->cursor_state.enable = 0; + break; + case CM_DRAW: + case CM_MOVE: + default: + ops->cursor_state.enable = (use_sw) ? 0 : 1; + break; + } + + cursor.image.data = src; + cursor.image.fg_color = ops->cursor_state.image.fg_color; + cursor.image.bg_color = ops->cursor_state.image.bg_color; + cursor.image.dx = ops->cursor_state.image.dx; + cursor.image.dy = ops->cursor_state.image.dy; + cursor.image.height = ops->cursor_state.image.height; + cursor.image.width = ops->cursor_state.image.width; + cursor.hot.x = ops->cursor_state.hot.x; + cursor.hot.y = ops->cursor_state.hot.y; + cursor.mask = ops->cursor_state.mask; + cursor.enable = ops->cursor_state.enable; + cursor.image.depth = 1; + cursor.rop = ROP_XOR; + + if (info->fbops->fb_cursor) + err = info->fbops->fb_cursor(info, &cursor); + + if (err) + soft_cursor(info, &cursor); + + ops->cursor_reset = 0; +} + +int ccw_update_start(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[ops->currcon]; + u32 yoffset; + u32 vyres = GETVYRES(p->scrollmode, info); + int err; + + yoffset = (vyres - info->var.yres) - ops->var.xoffset; + ops->var.xoffset = ops->var.yoffset; + ops->var.yoffset = yoffset; + err = fb_pan_display(info, &ops->var); + ops->var.xoffset = info->var.xoffset; + ops->var.yoffset = info->var.yoffset; + ops->var.vmode = info->var.vmode; + return err; +} + +void fbcon_rotate_ccw(struct fbcon_ops *ops) +{ + ops->bmove = ccw_bmove; + ops->clear = ccw_clear; + ops->putcs = ccw_putcs; + ops->clear_margins = ccw_clear_margins; + ops->cursor = ccw_cursor; + ops->update_start = ccw_update_start; +} +EXPORT_SYMBOL(fbcon_rotate_ccw); + +MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); +MODULE_DESCRIPTION("Console Rotation (270 degrees) Support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c new file mode 100644 index 00000000000..6c6f3b6dd17 --- /dev/null +++ b/drivers/video/console/fbcon_cw.c @@ -0,0 +1,412 @@ +/* + * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 90 degrees + * + * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/fb.h> +#include <linux/vt_kern.h> +#include <linux/console.h> +#include <asm/types.h> +#include "fbcon.h" +#include "fbcon_rotate.h" + +/* + * Rotation 90 degrees + */ + +static inline void cw_update_attr(u8 *dst, u8 *src, int attribute, + struct vc_data *vc) +{ + int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2; + int width = (vc->vc_font.height + 7) >> 3; + u8 c, t = 0, msk = ~(0xff >> offset); + + for (i = 0; i < vc->vc_font.width; i++) { + for (j = 0; j < width; j++) { + c = *src; + if (attribute & FBCON_ATTRIBUTE_UNDERLINE && !j) + c |= msk; + if (attribute & FBCON_ATTRIBUTE_BOLD && i) + c |= *(src-width); + if (attribute & FBCON_ATTRIBUTE_REVERSE) + c = ~c; + src++; + *dst++ = c; + t = c; + } + } +} + + +static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy, + int sx, int dy, int dx, int height, int width) +{ + struct display *p = &fb_display[vc->vc_num]; + struct fb_copyarea area; + u32 vxres = GETVXRES(p->scrollmode, info); + + area.sx = vxres - ((sy + height) * vc->vc_font.height); + area.sy = sx * vc->vc_font.width; + area.dx = vxres - ((dy + height) * vc->vc_font.height); + area.dy = dx * vc->vc_font.width; + area.width = height * vc->vc_font.height; + area.height = width * vc->vc_font.width; + + info->fbops->fb_copyarea(info, &area); +} + +static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy, + int sx, int height, int width) +{ + struct display *p = &fb_display[vc->vc_num]; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + u32 vxres = GETVXRES(p->scrollmode, info); + + region.color = attr_bgcol_ec(bgshift,vc); + region.dx = vxres - ((sy + height) * vc->vc_font.height); + region.dy = sx * vc->vc_font.width; + region.height = width * vc->vc_font.width; + region.width = height * vc->vc_font.height; + region.rop = ROP_COPY; + + info->fbops->fb_fillrect(info, ®ion); +} + +static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info, + const u16 *s, u32 attr, u32 cnt, + u32 d_pitch, u32 s_pitch, u32 cellsize, + struct fb_image *image, u8 *buf, u8 *dst) +{ + struct fbcon_ops *ops = info->fbcon_par; + u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + u32 idx = (vc->vc_font.height + 7) >> 3; + u8 *src; + + while (cnt--) { + src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize; + + if (attr) { + cw_update_attr(buf, src, attr, vc); + src = buf; + } + + if (likely(idx == 1)) + __fb_pad_aligned_buffer(dst, d_pitch, src, idx, + vc->vc_font.width); + else + fb_pad_aligned_buffer(dst, d_pitch, src, idx, + vc->vc_font.width); + + dst += d_pitch * vc->vc_font.width; + } + + info->fbops->fb_imageblit(info, image); +} + +static void cw_putcs(struct vc_data *vc, struct fb_info *info, + const unsigned short *s, int count, int yy, int xx, + int fg, int bg) +{ + struct fb_image image; + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + u32 width = (vc->vc_font.height + 7)/8; + u32 cellsize = width * vc->vc_font.width; + u32 maxcnt = info->pixmap.size/cellsize; + u32 scan_align = info->pixmap.scan_align - 1; + u32 buf_align = info->pixmap.buf_align - 1; + u32 cnt, pitch, size; + u32 attribute = get_attribute(info, scr_readw(s)); + u8 *dst, *buf = NULL; + u32 vxres = GETVXRES(p->scrollmode, info); + + if (!ops->fontbuffer) + return; + + image.fg_color = fg; + image.bg_color = bg; + image.dx = vxres - ((yy + 1) * vc->vc_font.height); + image.dy = xx * vc->vc_font.width; + image.width = vc->vc_font.height; + image.depth = 1; + + if (attribute) { + buf = kmalloc(cellsize, GFP_KERNEL); + if (!buf) + return; + } + + while (count) { + if (count > maxcnt) + cnt = maxcnt; + else + cnt = count; + + image.height = vc->vc_font.width * cnt; + pitch = ((image.width + 7) >> 3) + scan_align; + pitch &= ~scan_align; + size = pitch * image.height + buf_align; + size &= ~buf_align; + dst = fb_get_buffer_offset(info, &info->pixmap, size); + image.data = dst; + cw_putcs_aligned(vc, info, s, attribute, cnt, pitch, + width, cellsize, &image, buf, dst); + image.dy += image.height; + count -= cnt; + s += cnt; + } + + /* buf is always NULL except when in monochrome mode, so in this case + it's a gain to check buf against NULL even though kfree() handles + NULL pointers just fine */ + if (unlikely(buf)) + kfree(buf); + +} + +static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only) +{ + unsigned int cw = vc->vc_font.width; + unsigned int ch = vc->vc_font.height; + unsigned int rw = info->var.yres - (vc->vc_cols*cw); + unsigned int bh = info->var.xres - (vc->vc_rows*ch); + unsigned int rs = info->var.yres - rw; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + + region.color = attr_bgcol_ec(bgshift,vc); + region.rop = ROP_COPY; + + if (rw && !bottom_only) { + region.dx = 0; + region.dy = info->var.yoffset + rs; + region.height = rw; + region.width = info->var.xres_virtual; + info->fbops->fb_fillrect(info, ®ion); + } + + if (bh) { + region.dx = info->var.xoffset; + region.dy = info->var.yoffset; + region.height = info->var.yres; + region.width = bh; + info->fbops->fb_fillrect(info, ®ion); + } +} + +static void cw_cursor(struct vc_data *vc, struct fb_info *info, + struct display *p, int mode, int softback_lines, + int fg, int bg) +{ + struct fb_cursor cursor; + struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + int w = (vc->vc_font.height + 7) >> 3, c; + int y = real_y(p, vc->vc_y); + int attribute, use_sw = (vc->vc_cursor_type & 0x10); + int err = 1, dx, dy; + char *src; + u32 vxres = GETVXRES(p->scrollmode, info); + + if (!ops->fontbuffer) + return; + + cursor.set = 0; + + if (softback_lines) { + if (y + softback_lines >= vc->vc_rows) { + mode = CM_ERASE; + ops->cursor_flash = 0; + return; + } else + y += softback_lines; + } + + c = scr_readw((u16 *) vc->vc_pos); + attribute = get_attribute(info, c); + src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width)); + + if (ops->cursor_state.image.data != src || + ops->cursor_reset) { + ops->cursor_state.image.data = src; + cursor.set |= FB_CUR_SETIMAGE; + } + + if (attribute) { + u8 *dst; + + dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC); + if (!dst) + return; + kfree(ops->cursor_data); + ops->cursor_data = dst; + cw_update_attr(dst, src, attribute, vc); + src = dst; + } + + if (ops->cursor_state.image.fg_color != fg || + ops->cursor_state.image.bg_color != bg || + ops->cursor_reset) { + ops->cursor_state.image.fg_color = fg; + ops->cursor_state.image.bg_color = bg; + cursor.set |= FB_CUR_SETCMAP; + } + + if (ops->cursor_state.image.height != vc->vc_font.width || + ops->cursor_state.image.width != vc->vc_font.height || + ops->cursor_reset) { + ops->cursor_state.image.height = vc->vc_font.width; + ops->cursor_state.image.width = vc->vc_font.height; + cursor.set |= FB_CUR_SETSIZE; + } + + dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height); + dy = vc->vc_x * vc->vc_font.width; + + if (ops->cursor_state.image.dx != dx || + ops->cursor_state.image.dy != dy || + ops->cursor_reset) { + ops->cursor_state.image.dx = dx; + ops->cursor_state.image.dy = dy; + cursor.set |= FB_CUR_SETPOS; + } + + if (ops->cursor_state.hot.x || ops->cursor_state.hot.y || + ops->cursor_reset) { + ops->cursor_state.hot.x = cursor.hot.y = 0; + cursor.set |= FB_CUR_SETHOT; + } + + if (cursor.set & FB_CUR_SETSIZE || + vc->vc_cursor_type != p->cursor_shape || + ops->cursor_state.mask == NULL || + ops->cursor_reset) { + char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); + int cur_height, size, i = 0; + int width = (vc->vc_font.width + 7)/8; + + if (!mask) + return; + + tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC); + + if (!tmp) { + kfree(mask); + return; + } + + kfree(ops->cursor_state.mask); + ops->cursor_state.mask = mask; + + p->cursor_shape = vc->vc_cursor_type; + cursor.set |= FB_CUR_SETSHAPE; + + switch (p->cursor_shape & CUR_HWMASK) { + case CUR_NONE: + cur_height = 0; + break; + case CUR_UNDERLINE: + cur_height = (vc->vc_font.height < 10) ? 1 : 2; + break; + case CUR_LOWER_THIRD: + cur_height = vc->vc_font.height/3; + break; + case CUR_LOWER_HALF: + cur_height = vc->vc_font.height >> 1; + break; + case CUR_TWO_THIRDS: + cur_height = (vc->vc_font.height << 1)/3; + break; + case CUR_BLOCK: + default: + cur_height = vc->vc_font.height; + break; + } + + size = (vc->vc_font.height - cur_height) * width; + while (size--) + tmp[i++] = 0; + size = cur_height * width; + while (size--) + tmp[i++] = 0xff; + memset(mask, 0, w * vc->vc_font.width); + rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height); + kfree(tmp); + } + + switch (mode) { + case CM_ERASE: + ops->cursor_state.enable = 0; + break; + case CM_DRAW: + case CM_MOVE: + default: + ops->cursor_state.enable = (use_sw) ? 0 : 1; + break; + } + + cursor.image.data = src; + cursor.image.fg_color = ops->cursor_state.image.fg_color; + cursor.image.bg_color = ops->cursor_state.image.bg_color; + cursor.image.dx = ops->cursor_state.image.dx; + cursor.image.dy = ops->cursor_state.image.dy; + cursor.image.height = ops->cursor_state.image.height; + cursor.image.width = ops->cursor_state.image.width; + cursor.hot.x = ops->cursor_state.hot.x; + cursor.hot.y = ops->cursor_state.hot.y; + cursor.mask = ops->cursor_state.mask; + cursor.enable = ops->cursor_state.enable; + cursor.image.depth = 1; + cursor.rop = ROP_XOR; + + if (info->fbops->fb_cursor) + err = info->fbops->fb_cursor(info, &cursor); + + if (err) + soft_cursor(info, &cursor); + + ops->cursor_reset = 0; +} + +int cw_update_start(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[ops->currcon]; + u32 vxres = GETVXRES(p->scrollmode, info); + u32 xoffset; + int err; + + xoffset = vxres - (info->var.xres + ops->var.yoffset); + ops->var.yoffset = ops->var.xoffset; + ops->var.xoffset = xoffset; + err = fb_pan_display(info, &ops->var); + ops->var.xoffset = info->var.xoffset; + ops->var.yoffset = info->var.yoffset; + ops->var.vmode = info->var.vmode; + return err; +} + +void fbcon_rotate_cw(struct fbcon_ops *ops) +{ + ops->bmove = cw_bmove; + ops->clear = cw_clear; + ops->putcs = cw_putcs; + ops->clear_margins = cw_clear_margins; + ops->cursor = cw_cursor; + ops->update_start = cw_update_start; +} +EXPORT_SYMBOL(fbcon_rotate_cw); + +MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); +MODULE_DESCRIPTION("Console Rotation (90 degrees) Support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c new file mode 100644 index 00000000000..ec0dd8fe241 --- /dev/null +++ b/drivers/video/console/fbcon_rotate.c @@ -0,0 +1,117 @@ +/* + * linux/drivers/video/console/fbcon_rotate.c -- Software Rotation + * + * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/fb.h> +#include <linux/vt_kern.h> +#include <linux/console.h> +#include <asm/types.h> +#include "fbcon.h" +#include "fbcon_rotate.h" + +static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc, + struct display *p) +{ + struct fbcon_ops *ops = info->fbcon_par; + int len, err = 0; + int s_cellsize, d_cellsize, i; + const u8 *src; + u8 *dst; + + if (vc->vc_font.data == ops->fontdata && + p->con_rotate == ops->cur_rotate) + goto finished; + + src = ops->fontdata = vc->vc_font.data; + ops->cur_rotate = p->con_rotate; + len = (!p->userfont) ? 256 : FNTCHARCNT(src); + s_cellsize = ((vc->vc_font.width + 7)/8) * + vc->vc_font.height; + d_cellsize = s_cellsize; + + if (ops->rotate == FB_ROTATE_CW || + ops->rotate == FB_ROTATE_CCW) + d_cellsize = ((vc->vc_font.height + 7)/8) * + vc->vc_font.width; + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + if (ops->fd_size < d_cellsize * len) { + dst = kmalloc(d_cellsize * len, GFP_KERNEL); + + if (dst == NULL) { + err = -ENOMEM; + goto finished; + } + + ops->fd_size = d_cellsize * len; + kfree(ops->fontbuffer); + ops->fontbuffer = dst; + } + + dst = ops->fontbuffer; + memset(dst, 0, ops->fd_size); + + switch (ops->rotate) { + case FB_ROTATE_UD: + for (i = len; i--; ) { + rotate_ud(src, dst, vc->vc_font.width, + vc->vc_font.height); + + src += s_cellsize; + dst += d_cellsize; + } + break; + case FB_ROTATE_CW: + for (i = len; i--; ) { + rotate_cw(src, dst, vc->vc_font.width, + vc->vc_font.height); + src += s_cellsize; + dst += d_cellsize; + } + break; + case FB_ROTATE_CCW: + for (i = len; i--; ) { + rotate_ccw(src, dst, vc->vc_font.width, + vc->vc_font.height); + src += s_cellsize; + dst += d_cellsize; + } + break; + } + +finished: + return err; +} + +void fbcon_set_rotate(struct fbcon_ops *ops) +{ + ops->rotate_font = fbcon_rotate_font; + + switch(ops->rotate) { + case FB_ROTATE_CW: + fbcon_rotate_cw(ops); + break; + case FB_ROTATE_UD: + fbcon_rotate_ud(ops); + break; + case FB_ROTATE_CCW: + fbcon_rotate_ccw(ops); + break; + } +} +EXPORT_SYMBOL(fbcon_set_rotate); + +MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); +MODULE_DESCRIPTION("Console Rotation Support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h new file mode 100644 index 00000000000..90c672096c2 --- /dev/null +++ b/drivers/video/console/fbcon_rotate.h @@ -0,0 +1,105 @@ +/* + * linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation + * + * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _FBCON_ROTATE_H +#define _FBCON_ROTATE_H + +#define FNTCHARCNT(fd) (((int *)(fd))[-3]) + +#define GETVYRES(s,i) ({ \ + (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \ + (i)->var.yres : (i)->var.yres_virtual; }) + +#define GETVXRES(s,i) ({ \ + (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \ + (i)->var.xres : (i)->var.xres_virtual; }) + +/* + * The bitmap is always big endian + */ +#if defined(__LITTLE_ENDIAN) +#define FBCON_BIT(b) (7 - (b)) +#else +#define FBCON_BIT(b) (b) +#endif + +static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat) +{ + u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; + + pat +=index; + return (test_bit(FBCON_BIT(bit), (void *)pat)); +} + +static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat) +{ + u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; + + pat += index; + set_bit(FBCON_BIT(bit), (void *)pat); +} + +static inline void rotate_ud(const char *in, char *out, u32 width, u32 height) +{ + int i, j; + int shift = width % 8; + + width = (width + 7) & ~7; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + if (pattern_test_bit(j, i, width, in)) + pattern_set_bit(width - (1 + j + shift), + height - (1 + i), + width, out); + } + + } +} + +static inline void rotate_cw(const char *in, char *out, u32 width, u32 height) +{ + int i, j, h = height, w = width; + int shift = (8 - (height % 8)) & 7; + + width = (width + 7) & ~7; + height = (height + 7) & ~7; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + if (pattern_test_bit(j, i, width, in)) + pattern_set_bit(height - 1 - i - shift, j, + height, out); + + } + } +} + +static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height) +{ + int i, j, h = height, w = width; + int shift = width % 8; + + width = (width + 7) & ~7; + height = (height + 7) & ~7; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + if (pattern_test_bit(j, i, width, in)) + pattern_set_bit(i, width - 1 - j - shift, + height, out); + } + } +} + +extern void fbcon_rotate_cw(struct fbcon_ops *ops); +extern void fbcon_rotate_ud(struct fbcon_ops *ops); +extern void fbcon_rotate_ccw(struct fbcon_ops *ops); +#endif diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c new file mode 100644 index 00000000000..2e1d9d4249c --- /dev/null +++ b/drivers/video/console/fbcon_ud.c @@ -0,0 +1,454 @@ +/* + * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 180 degrees + * + * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/fb.h> +#include <linux/vt_kern.h> +#include <linux/console.h> +#include <asm/types.h> +#include "fbcon.h" +#include "fbcon_rotate.h" + +/* + * Rotation 180 degrees + */ + +static inline void ud_update_attr(u8 *dst, u8 *src, int attribute, + struct vc_data *vc) +{ + int i, offset = (vc->vc_font.height < 10) ? 1 : 2; + int width = (vc->vc_font.width + 7) >> 3; + unsigned int cellsize = vc->vc_font.height * width; + u8 c; + + offset = offset * width; + + for (i = 0; i < cellsize; i++) { + c = src[i]; + if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i < offset) + c = 0xff; + if (attribute & FBCON_ATTRIBUTE_BOLD) + c |= c << 1; + if (attribute & FBCON_ATTRIBUTE_REVERSE) + c = ~c; + dst[i] = c; + } +} + + +static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy, + int sx, int dy, int dx, int height, int width) +{ + struct display *p = &fb_display[vc->vc_num]; + struct fb_copyarea area; + u32 vyres = GETVYRES(p->scrollmode, info); + u32 vxres = GETVXRES(p->scrollmode, info); + + area.sy = vyres - ((sy + height) * vc->vc_font.height); + area.sx = vxres - ((sx + width) * vc->vc_font.width); + area.dy = vyres - ((dy + height) * vc->vc_font.height); + area.dx = vxres - ((dx + width) * vc->vc_font.width); + area.height = height * vc->vc_font.height; + area.width = width * vc->vc_font.width; + + info->fbops->fb_copyarea(info, &area); +} + +static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy, + int sx, int height, int width) +{ + struct display *p = &fb_display[vc->vc_num]; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + u32 vyres = GETVYRES(p->scrollmode, info); + u32 vxres = GETVXRES(p->scrollmode, info); + + region.color = attr_bgcol_ec(bgshift,vc); + region.dy = vyres - ((sy + height) * vc->vc_font.height); + region.dx = vxres - ((sx + width) * vc->vc_font.width); + region.width = width * vc->vc_font.width; + region.height = height * vc->vc_font.height; + region.rop = ROP_COPY; + + info->fbops->fb_fillrect(info, ®ion); +} + +static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info, + const u16 *s, u32 attr, u32 cnt, + u32 d_pitch, u32 s_pitch, u32 cellsize, + struct fb_image *image, u8 *buf, u8 *dst) +{ + struct fbcon_ops *ops = info->fbcon_par; + u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + u32 idx = vc->vc_font.width >> 3; + u8 *src; + + while (cnt--) { + src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize; + + if (attr) { + ud_update_attr(buf, src, attr, vc); + src = buf; + } + + if (likely(idx == 1)) + __fb_pad_aligned_buffer(dst, d_pitch, src, idx, + image->height); + else + fb_pad_aligned_buffer(dst, d_pitch, src, idx, + image->height); + + dst += s_pitch; + } + + info->fbops->fb_imageblit(info, image); +} + +static inline void ud_putcs_unaligned(struct vc_data *vc, + struct fb_info *info, const u16 *s, + u32 attr, u32 cnt, u32 d_pitch, + u32 s_pitch, u32 cellsize, + struct fb_image *image, u8 *buf, + u8 *dst) +{ + struct fbcon_ops *ops = info->fbcon_par; + u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + u32 shift_low = 0, mod = vc->vc_font.width % 8; + u32 shift_high = 8; + u32 idx = vc->vc_font.width >> 3; + u8 *src; + + while (cnt--) { + src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize; + + if (attr) { + ud_update_attr(buf, src, attr, vc); + src = buf; + } + + fb_pad_unaligned_buffer(dst, d_pitch, src, idx, + image->height, shift_high, + shift_low, mod); + shift_low += mod; + dst += (shift_low >= 8) ? s_pitch : s_pitch - 1; + shift_low &= 7; + shift_high = 8 - shift_low; + } + + info->fbops->fb_imageblit(info, image); + +} + +static void ud_putcs(struct vc_data *vc, struct fb_info *info, + const unsigned short *s, int count, int yy, int xx, + int fg, int bg) +{ + struct fb_image image; + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + u32 width = (vc->vc_font.width + 7)/8; + u32 cellsize = width * vc->vc_font.height; + u32 maxcnt = info->pixmap.size/cellsize; + u32 scan_align = info->pixmap.scan_align - 1; + u32 buf_align = info->pixmap.buf_align - 1; + u32 mod = vc->vc_font.width % 8, cnt, pitch, size; + u32 attribute = get_attribute(info, scr_readw(s)); + u8 *dst, *buf = NULL; + u32 vyres = GETVYRES(p->scrollmode, info); + u32 vxres = GETVXRES(p->scrollmode, info); + + if (!ops->fontbuffer) + return; + + image.fg_color = fg; + image.bg_color = bg; + image.dy = vyres - ((yy * vc->vc_font.height) + vc->vc_font.height); + image.dx = vxres - ((xx + count) * vc->vc_font.width); + image.height = vc->vc_font.height; + image.depth = 1; + + if (attribute) { + buf = kmalloc(cellsize, GFP_KERNEL); + if (!buf) + return; + } + + s += count - 1; + + while (count) { + if (count > maxcnt) + cnt = maxcnt; + else + cnt = count; + + image.width = vc->vc_font.width * cnt; + pitch = ((image.width + 7) >> 3) + scan_align; + pitch &= ~scan_align; + size = pitch * image.height + buf_align; + size &= ~buf_align; + dst = fb_get_buffer_offset(info, &info->pixmap, size); + image.data = dst; + + if (!mod) + ud_putcs_aligned(vc, info, s, attribute, cnt, pitch, + width, cellsize, &image, buf, dst); + else + ud_putcs_unaligned(vc, info, s, attribute, cnt, pitch, + width, cellsize, &image, + buf, dst); + + image.dx += image.width; + count -= cnt; + s -= cnt; + xx += cnt; + } + + /* buf is always NULL except when in monochrome mode, so in this case + it's a gain to check buf against NULL even though kfree() handles + NULL pointers just fine */ + if (unlikely(buf)) + kfree(buf); + +} + +static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only) +{ + unsigned int cw = vc->vc_font.width; + unsigned int ch = vc->vc_font.height; + unsigned int rw = info->var.xres - (vc->vc_cols*cw); + unsigned int bh = info->var.yres - (vc->vc_rows*ch); + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + + region.color = attr_bgcol_ec(bgshift,vc); + region.rop = ROP_COPY; + + if (rw && !bottom_only) { + region.dy = 0; + region.dx = info->var.xoffset; + region.width = rw; + region.height = info->var.yres_virtual; + info->fbops->fb_fillrect(info, ®ion); + } + + if (bh) { + region.dy = info->var.yoffset; + region.dx = info->var.xoffset; + region.height = bh; + region.width = info->var.xres; + info->fbops->fb_fillrect(info, ®ion); + } +} + +static void ud_cursor(struct vc_data *vc, struct fb_info *info, + struct display *p, int mode, int softback_lines, + int fg, int bg) +{ + struct fb_cursor cursor; + struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + int w = (vc->vc_font.width + 7) >> 3, c; + int y = real_y(p, vc->vc_y); + int attribute, use_sw = (vc->vc_cursor_type & 0x10); + int err = 1, dx, dy; + char *src; + u32 vyres = GETVYRES(p->scrollmode, info); + u32 vxres = GETVXRES(p->scrollmode, info); + + if (!ops->fontbuffer) + return; + + cursor.set = 0; + + if (softback_lines) { + if (y + softback_lines >= vc->vc_rows) { + mode = CM_ERASE; + ops->cursor_flash = 0; + return; + } else + y += softback_lines; + } + + c = scr_readw((u16 *) vc->vc_pos); + attribute = get_attribute(info, c); + src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height)); + + if (ops->cursor_state.image.data != src || + ops->cursor_reset) { + ops->cursor_state.image.data = src; + cursor.set |= FB_CUR_SETIMAGE; + } + + if (attribute) { + u8 *dst; + + dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC); + if (!dst) + return; + kfree(ops->cursor_data); + ops->cursor_data = dst; + ud_update_attr(dst, src, attribute, vc); + src = dst; + } + + if (ops->cursor_state.image.fg_color != fg || + ops->cursor_state.image.bg_color != bg || + ops->cursor_reset) { + ops->cursor_state.image.fg_color = fg; + ops->cursor_state.image.bg_color = bg; + cursor.set |= FB_CUR_SETCMAP; + } + + if (ops->cursor_state.image.height != vc->vc_font.height || + ops->cursor_state.image.width != vc->vc_font.width || + ops->cursor_reset) { + ops->cursor_state.image.height = vc->vc_font.height; + ops->cursor_state.image.width = vc->vc_font.width; + cursor.set |= FB_CUR_SETSIZE; + } + + dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height); + dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width); + + if (ops->cursor_state.image.dx != dx || + ops->cursor_state.image.dy != dy || + ops->cursor_reset) { + ops->cursor_state.image.dx = dx; + ops->cursor_state.image.dy = dy; + cursor.set |= FB_CUR_SETPOS; + } + + if (ops->cursor_state.hot.x || ops->cursor_state.hot.y || + ops->cursor_reset) { + ops->cursor_state.hot.x = cursor.hot.y = 0; + cursor.set |= FB_CUR_SETHOT; + } + + if (cursor.set & FB_CUR_SETSIZE || + vc->vc_cursor_type != p->cursor_shape || + ops->cursor_state.mask == NULL || + ops->cursor_reset) { + char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); + int cur_height, size, i = 0; + u8 msk = 0xff; + + if (!mask) + return; + + kfree(ops->cursor_state.mask); + ops->cursor_state.mask = mask; + + p->cursor_shape = vc->vc_cursor_type; + cursor.set |= FB_CUR_SETSHAPE; + + switch (p->cursor_shape & CUR_HWMASK) { + case CUR_NONE: + cur_height = 0; + break; + case CUR_UNDERLINE: + cur_height = (vc->vc_font.height < 10) ? 1 : 2; + break; + case CUR_LOWER_THIRD: + cur_height = vc->vc_font.height/3; + break; + case CUR_LOWER_HALF: + cur_height = vc->vc_font.height >> 1; + break; + case CUR_TWO_THIRDS: + cur_height = (vc->vc_font.height << 1)/3; + break; + case CUR_BLOCK: + default: + cur_height = vc->vc_font.height; + break; + } + + size = cur_height * w; + + while (size--) + mask[i++] = msk; + + size = (vc->vc_font.height - cur_height) * w; + + while (size--) + mask[i++] = ~msk; + } + + switch (mode) { + case CM_ERASE: + ops->cursor_state.enable = 0; + break; + case CM_DRAW: + case CM_MOVE: + default: + ops->cursor_state.enable = (use_sw) ? 0 : 1; + break; + } + + cursor.image.data = src; + cursor.image.fg_color = ops->cursor_state.image.fg_color; + cursor.image.bg_color = ops->cursor_state.image.bg_color; + cursor.image.dx = ops->cursor_state.image.dx; + cursor.image.dy = ops->cursor_state.image.dy; + cursor.image.height = ops->cursor_state.image.height; + cursor.image.width = ops->cursor_state.image.width; + cursor.hot.x = ops->cursor_state.hot.x; + cursor.hot.y = ops->cursor_state.hot.y; + cursor.mask = ops->cursor_state.mask; + cursor.enable = ops->cursor_state.enable; + cursor.image.depth = 1; + cursor.rop = ROP_XOR; + + if (info->fbops->fb_cursor) + err = info->fbops->fb_cursor(info, &cursor); + + if (err) + soft_cursor(info, &cursor); + + ops->cursor_reset = 0; +} + +int ud_update_start(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[ops->currcon]; + u32 xoffset, yoffset; + u32 vyres = GETVYRES(p->scrollmode, info); + u32 vxres = GETVXRES(p->scrollmode, info); + int err; + + xoffset = (vxres - info->var.xres) - ops->var.xoffset; + yoffset = (vyres - info->var.yres) - ops->var.yoffset; + ops->var.xoffset = xoffset; + ops->var.yoffset = yoffset; + err = fb_pan_display(info, &ops->var); + ops->var.xoffset = info->var.xoffset; + ops->var.yoffset = info->var.yoffset; + ops->var.vmode = info->var.vmode; + return err; +} + +void fbcon_rotate_ud(struct fbcon_ops *ops) +{ + ops->bmove = ud_bmove; + ops->clear = ud_clear; + ops->putcs = ud_putcs; + ops->clear_margins = ud_clear_margins; + ops->cursor = ud_cursor; + ops->update_start = ud_update_start; +} +EXPORT_SYMBOL(fbcon_rotate_ud); + +MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); +MODULE_DESCRIPTION("Console Rotation (180 degrees) Support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c new file mode 100644 index 00000000000..dfecc27d8de --- /dev/null +++ b/drivers/video/console/font_rl.c @@ -0,0 +1,4374 @@ + +/* This font is simply the "rl.fnt" console font from the kbd utility. + * Converted by Zack T Smith, fbui@comcast.net. + * The original binary file is covered under the GNU Public License. + */ + +#include <linux/font.h> + +#define FONTDATAMAX 4096 + +static unsigned char patterns[4096] = { +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x3c, +0x42, +0x81, +0xe7, +0xa5, +0x99, +0x81, +0x81, +0x99, +0x42, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x3c, +0x7e, +0xff, +0x99, +0xdb, +0xe7, +0xff, +0xff, +0xe7, +0x7e, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x6c, +0xfe, +0xfe, +0xfe, +0xfe, +0xfe, +0x7c, +0x38, +0x10, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x10, +0x38, +0x7c, +0xfe, +0x7c, +0x38, +0x10, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x38, +0x38, +0x10, +0xd6, +0xfe, +0xd6, +0x10, +0x10, +0x38, +0x7c, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x10, +0x38, +0x7c, +0xfe, +0xfe, +0x54, +0x10, +0x10, +0x38, +0x7c, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x18, +0x3c, +0x3c, +0x18, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xe7, +0xc3, +0xc3, +0xe7, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x3c, +0x66, +0x42, +0x42, +0x66, +0x3c, +0x00, +0x00, +0x00, +0x00, +0x00, + +0xff, +0xff, +0xff, +0xff, +0xff, +0xc3, +0x99, +0xbd, +0xbd, +0x99, +0xc3, +0xff, +0xff, +0xff, +0xff, +0xff, + +0x00, +0x00, +0x0f, +0x07, +0x0d, +0x18, +0x78, +0xcc, +0xcc, +0xcc, +0xcc, +0x78, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x3c, +0x66, +0x66, +0x66, +0x3c, +0x18, +0x7e, +0x18, +0x18, +0x18, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x08, +0x0c, +0x0a, +0x0a, +0x0a, +0x08, +0x08, +0x08, +0x38, +0x78, +0x30, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x10, +0x18, +0x1c, +0x1e, +0x1e, +0x16, +0x12, +0x72, +0xf2, +0x62, +0x0e, +0x1e, +0x0c, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x10, +0x92, +0x54, +0x38, +0xfe, +0x38, +0x54, +0x92, +0x10, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x80, +0xc0, +0xe0, +0xb8, +0x8e, +0xb8, +0xe0, +0xc0, +0x80, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x02, +0x06, +0x0e, +0x3a, +0xe2, +0x3a, +0x0e, +0x06, +0x02, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x10, +0x38, +0x7c, +0xd6, +0x10, +0x10, +0x10, +0x10, +0xd6, +0x7c, +0x38, +0x10, +0x00, +0x00, + +0x00, +0x42, +0xe7, +0xe7, +0xe7, +0xe7, +0x42, +0x42, +0x42, +0x00, +0x66, +0x66, +0x66, +0x00, +0x00, +0x00, + +0x00, +0x7f, +0xca, +0xca, +0xca, +0xca, +0x7a, +0x0a, +0x0a, +0x0a, +0x0a, +0x0a, +0x1b, +0x00, +0x00, +0x00, + +0x00, +0x1e, +0x31, +0x78, +0xcc, +0xc6, +0xc3, +0x63, +0x33, +0x1e, +0x8c, +0x78, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xfe, +0xfe, +0xfe, +0xfe, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x10, +0x38, +0x7c, +0xd6, +0x10, +0x10, +0x10, +0x10, +0xd6, +0x7c, +0x38, +0x10, +0xfe, +0x00, + +0x00, +0x00, +0x10, +0x38, +0x7c, +0xd6, +0x10, +0x10, +0x10, +0x10, +0x10, +0x10, +0x10, +0x10, +0x00, +0x00, + +0x00, +0x00, +0x10, +0x10, +0x10, +0x10, +0x10, +0x10, +0x10, +0x10, +0xd6, +0x7c, +0x38, +0x10, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x08, +0x0c, +0x06, +0xff, +0x06, +0x0c, +0x08, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x10, +0x30, +0x60, +0xff, +0x60, +0x30, +0x10, +0x00, +0x00, +0x00, +0x00, + +0x22, +0x44, +0x88, +0xcc, +0xee, +0x44, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x24, +0x42, +0xff, +0x42, +0x24, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x10, +0x38, +0x38, +0x6c, +0x6c, +0xc6, +0xfe, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0xfe, +0xc6, +0x6c, +0x6c, +0x38, +0x38, +0x10, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x18, +0x3c, +0x3c, +0x3c, +0x3c, +0x18, +0x18, +0x18, +0x10, +0x00, +0x18, +0x18, +0x00, +0x00, +0x00, + +0x22, +0x77, +0x33, +0x11, +0x22, +0x44, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x12, +0x12, +0x12, +0x7f, +0x24, +0x24, +0x24, +0xfe, +0x48, +0x48, +0x48, +0x00, +0x00, +0x00, + +0x10, +0x10, +0x7c, +0xd2, +0xd0, +0xd0, +0xd0, +0x7c, +0x16, +0x16, +0x16, +0x96, +0x7c, +0x10, +0x10, +0x00, + +0x00, +0x42, +0xbe, +0x44, +0x0c, +0x08, +0x18, +0x10, +0x30, +0x20, +0x64, +0x4a, +0xc4, +0x00, +0x00, +0x00, + +0x00, +0x38, +0x6c, +0x6c, +0x6c, +0x38, +0x37, +0x72, +0xdc, +0xcc, +0xcc, +0xcc, +0x77, +0x00, +0x00, +0x00, + +0x10, +0x38, +0x18, +0x08, +0x10, +0x20, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x04, +0x08, +0x10, +0x10, +0x30, +0x30, +0x30, +0x30, +0x30, +0x10, +0x10, +0x08, +0x04, +0x00, +0x00, + +0x00, +0x20, +0x10, +0x08, +0x08, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x08, +0x08, +0x10, +0x20, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x44, +0x28, +0x38, +0xfe, +0x38, +0x28, +0x44, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x18, +0x18, +0x7e, +0x18, +0x18, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x10, +0x38, +0x18, +0x08, +0x10, +0x20, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x7e, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x10, +0x38, +0x10, +0x00, +0x00, +0x00, + +0x00, +0x06, +0x06, +0x0c, +0x0c, +0x18, +0x18, +0x30, +0x30, +0x60, +0x60, +0xc0, +0xc0, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x3c, +0x46, +0xc6, +0xc6, +0xc6, +0xc6, +0xc6, +0xc4, +0x78, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x08, +0x18, +0x78, +0x18, +0x18, +0x18, +0x18, +0x18, +0x7e, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x7c, +0x86, +0x06, +0x0c, +0x18, +0x20, +0x40, +0xc1, +0xfe, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x3c, +0x46, +0x04, +0x08, +0x1c, +0x06, +0x06, +0x06, +0x06, +0x0c, +0x70, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x04, +0x08, +0x10, +0x2c, +0x4c, +0x8c, +0x8c, +0xfe, +0x0c, +0x0c, +0x0c, +0x00, + +0x00, +0x00, +0x00, +0x02, +0x3c, +0x20, +0x20, +0x70, +0x0c, +0x06, +0x06, +0x06, +0x06, +0x0c, +0x70, +0x00, + +0x00, +0x00, +0x18, +0x20, +0x40, +0xc0, +0xdc, +0xc6, +0xc6, +0xc6, +0xc6, +0x44, +0x38, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x40, +0x7e, +0x82, +0x06, +0x04, +0x0c, +0x18, +0x18, +0x30, +0x30, +0x30, +0x30, +0x00, + +0x00, +0x00, +0x7c, +0xc6, +0xc6, +0x64, +0x38, +0x4c, +0xc6, +0xc6, +0xc6, +0xc6, +0x7c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x38, +0x44, +0xc6, +0xc6, +0x76, +0x06, +0x06, +0x06, +0x04, +0x08, +0x30, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x10, +0x38, +0x10, +0x00, +0x00, +0x00, +0x10, +0x38, +0x10, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x10, +0x38, +0x10, +0x00, +0x00, +0x00, +0x10, +0x38, +0x18, +0x08, +0x10, +0x20, + +0x00, +0x06, +0x0c, +0x18, +0x30, +0x60, +0xa0, +0xa0, +0x60, +0x30, +0x18, +0x0c, +0x06, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x7e, +0x00, +0x00, +0x7e, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x60, +0x30, +0x18, +0x0c, +0x06, +0x05, +0x05, +0x06, +0x0c, +0x18, +0x30, +0x60, +0x00, +0x00, +0x00, + +0x00, +0x7c, +0x86, +0xc6, +0x06, +0x04, +0x08, +0x10, +0x10, +0x18, +0x00, +0x18, +0x18, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x3c, +0x46, +0xc6, +0xce, +0xd6, +0xd6, +0xd6, +0xdc, +0xc0, +0xc4, +0x78, +0x00, +0x00, +0x00, + +0x00, +0x18, +0x18, +0x18, +0x3c, +0x2c, +0x2c, +0x2c, +0x7e, +0x46, +0x46, +0x46, +0xef, +0x00, +0x00, +0x00, + +0x00, +0xfc, +0x66, +0x66, +0x66, +0x66, +0x7c, +0x66, +0x66, +0x66, +0x66, +0x66, +0xfc, +0x00, +0x00, +0x00, + +0x00, +0x3a, +0x66, +0xc2, +0xc0, +0xc0, +0xc0, +0xc0, +0xc0, +0xc0, +0xc0, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0xfc, +0x66, +0x63, +0x63, +0x63, +0x63, +0x63, +0x63, +0x63, +0x63, +0x66, +0xfc, +0x00, +0x00, +0x00, + +0x00, +0xff, +0x61, +0x60, +0x60, +0x64, +0x7c, +0x64, +0x60, +0x60, +0x60, +0x61, +0xfe, +0x00, +0x00, +0x00, + +0x00, +0xff, +0x61, +0x61, +0x60, +0x64, +0x7c, +0x64, +0x60, +0x60, +0x60, +0x60, +0xf0, +0x00, +0x00, +0x00, + +0x00, +0x3a, +0x66, +0xc2, +0xc0, +0xc0, +0xc0, +0xcf, +0xc6, +0xc6, +0xc6, +0x66, +0x38, +0x00, +0x00, +0x00, + +0x00, +0xf7, +0x62, +0x62, +0x62, +0x62, +0x7e, +0x62, +0x62, +0x62, +0x62, +0x62, +0xf7, +0x00, +0x00, +0x00, + +0x00, +0x3c, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x1e, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x08, +0xf0, + +0x00, +0xf7, +0x64, +0x6c, +0x68, +0x68, +0x78, +0x6c, +0x6c, +0x6c, +0x66, +0x66, +0xf7, +0x00, +0x00, +0x00, + +0x00, +0xf8, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0x61, +0xfe, +0x00, +0x00, +0x00, + +0x00, +0xc3, +0x66, +0x76, +0x7e, +0x56, +0x56, +0x46, +0x46, +0x46, +0x46, +0x46, +0xef, +0x00, +0x00, +0x00, + +0x00, +0xe7, +0x62, +0x62, +0x72, +0x52, +0x5a, +0x4a, +0x4e, +0x46, +0x46, +0x42, +0xe2, +0x00, +0x00, +0x00, + +0x00, +0x3c, +0x66, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0xfc, +0x66, +0x66, +0x66, +0x66, +0x6c, +0x60, +0x60, +0x60, +0x60, +0x60, +0xf0, +0x00, +0x00, +0x00, + +0x00, +0x3c, +0x66, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0x66, +0x3c, +0x10, +0x39, +0x0e, + +0x00, +0xfc, +0x66, +0x66, +0x66, +0x66, +0x7c, +0x6c, +0x66, +0x66, +0x66, +0x66, +0xf3, +0x00, +0x00, +0x00, + +0x00, +0x7a, +0xc6, +0xc2, +0xc0, +0x70, +0x3c, +0x0e, +0x06, +0x06, +0x86, +0xc6, +0xbc, +0x00, +0x00, +0x00, + +0x00, +0xff, +0x99, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0xf7, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0xf7, +0x62, +0x62, +0x62, +0x76, +0x34, +0x34, +0x34, +0x3c, +0x18, +0x18, +0x18, +0x00, +0x00, +0x00, + +0x00, +0xf7, +0x62, +0x62, +0x62, +0x62, +0x6a, +0x6a, +0x6a, +0x6a, +0x7e, +0x7e, +0x34, +0x00, +0x00, +0x00, + +0x00, +0xf7, +0x62, +0x62, +0x34, +0x34, +0x18, +0x18, +0x2c, +0x2c, +0x46, +0x46, +0xef, +0x00, +0x00, +0x00, + +0x00, +0xf7, +0x62, +0x62, +0x62, +0x34, +0x34, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x7f, +0x46, +0x86, +0x0c, +0x0c, +0x18, +0x18, +0x30, +0x30, +0x61, +0x62, +0xfe, +0x00, +0x00, +0x00, + +0x00, +0x3c, +0x30, +0x30, +0x30, +0x30, +0x30, +0x30, +0x30, +0x30, +0x30, +0x30, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0xc0, +0xc0, +0x60, +0x60, +0x30, +0x30, +0x18, +0x18, +0x0c, +0x0c, +0x06, +0x06, +0x00, +0x00, +0x00, + +0x00, +0x3c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x10, +0x38, +0x4c, +0x86, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0x00, +0x00, + +0x00, +0x18, +0x20, +0x30, +0x38, +0x10, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x78, +0x8c, +0x0c, +0x3c, +0xcc, +0xcc, +0xcd, +0x76, +0x00, +0x00, +0x00, + +0x00, +0x20, +0xe0, +0x60, +0x60, +0x6c, +0x76, +0x66, +0x66, +0x66, +0x66, +0x76, +0x6c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x3c, +0x66, +0x60, +0x60, +0x60, +0x60, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x04, +0x1c, +0x0c, +0x0c, +0x6c, +0xdc, +0xcc, +0xcc, +0xcc, +0xcc, +0xdc, +0x66, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x3c, +0x66, +0x7e, +0x60, +0x60, +0x60, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x1e, +0x31, +0x33, +0x30, +0x30, +0x78, +0x30, +0x30, +0x30, +0x30, +0x30, +0x78, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x7b, +0xce, +0xcc, +0xcc, +0xcc, +0x78, +0x60, +0x7c, +0x86, +0xc6, +0x7c, + +0x00, +0x20, +0xe0, +0x60, +0x60, +0x6c, +0x76, +0x66, +0x66, +0x66, +0x66, +0x66, +0xf7, +0x00, +0x00, +0x00, + +0x00, +0x10, +0x38, +0x10, +0x00, +0x18, +0x38, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x08, +0x1c, +0x08, +0x00, +0x0c, +0x1c, +0x0c, +0x0c, +0x0c, +0x0c, +0x0c, +0x6c, +0x4c, +0x38, +0x00, + +0x00, +0x20, +0xe0, +0x60, +0x60, +0x67, +0x66, +0x6c, +0x78, +0x6c, +0x6c, +0x66, +0xe7, +0x00, +0x00, +0x00, + +0x00, +0x08, +0x38, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x6a, +0xfe, +0x6a, +0x6a, +0x6a, +0x62, +0x62, +0xf7, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x5c, +0xf6, +0x66, +0x66, +0x66, +0x66, +0x66, +0xf7, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x3c, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x5c, +0xe6, +0x66, +0x66, +0x66, +0x66, +0x66, +0x7c, +0x60, +0x60, +0xf0, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x76, +0xcc, +0xcc, +0xcc, +0xcc, +0xcc, +0xcc, +0x7c, +0x0c, +0x0c, +0x1e, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x5e, +0xf6, +0x60, +0x60, +0x60, +0x60, +0x60, +0xf0, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x7a, +0xc6, +0x72, +0x1c, +0x06, +0x86, +0xc6, +0xbc, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x10, +0x30, +0x7c, +0x30, +0x30, +0x30, +0x30, +0x30, +0x34, +0x18, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0xee, +0x66, +0x66, +0x66, +0x66, +0x66, +0x67, +0x3a, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0xf7, +0x62, +0x76, +0x34, +0x34, +0x3c, +0x18, +0x18, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0xf7, +0x62, +0x6a, +0x6a, +0x6a, +0x6a, +0x7e, +0x24, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0xf7, +0x62, +0x34, +0x18, +0x2c, +0x46, +0x46, +0xef, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0xf7, +0x62, +0x62, +0x34, +0x34, +0x18, +0x18, +0x18, +0x10, +0xb0, +0xe0, + +0x00, +0x00, +0x00, +0x00, +0x00, +0xfe, +0x8c, +0x18, +0x30, +0x30, +0x60, +0xc2, +0xfe, +0x00, +0x00, +0x00, + +0x00, +0x0e, +0x18, +0x10, +0x10, +0x08, +0x70, +0x70, +0x08, +0x10, +0x10, +0x18, +0x0e, +0x00, +0x00, +0x00, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x00, +0x00, + +0x00, +0x70, +0x18, +0x08, +0x08, +0x10, +0x0e, +0x0e, +0x10, +0x08, +0x08, +0x18, +0x70, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x76, +0xdc, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x10, +0x38, +0x6c, +0xc6, +0xc6, +0xc6, +0xfe, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x3a, +0x66, +0xc2, +0xc0, +0xc0, +0xc0, +0xc0, +0xc0, +0x62, +0x3c, +0x18, +0x0c, +0x24, +0x18, + +0x00, +0x00, +0x66, +0x00, +0x00, +0xee, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3b, +0x00, +0x00, +0x00, + +0x00, +0x0c, +0x18, +0x20, +0x00, +0x3c, +0x66, +0x7e, +0x60, +0x60, +0x60, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x30, +0x58, +0x8c, +0x00, +0x78, +0x8c, +0x0c, +0x3c, +0xcc, +0xcc, +0xcd, +0x76, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x66, +0x00, +0x00, +0x78, +0x8c, +0x0c, +0x3c, +0xcc, +0xcc, +0xcd, +0x76, +0x00, +0x00, +0x00, + +0x00, +0x30, +0x18, +0x04, +0x00, +0x78, +0x8c, +0x0c, +0x3c, +0xcc, +0xcc, +0xcd, +0x76, +0x00, +0x00, +0x00, + +0x38, +0x44, +0x44, +0x38, +0x00, +0x78, +0x8c, +0x0c, +0x3c, +0xcc, +0xcc, +0xcd, +0x76, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x3c, +0x66, +0x60, +0x60, +0x60, +0x60, +0x62, +0x3c, +0x08, +0x24, +0x18, + +0x00, +0x18, +0x2c, +0x46, +0x00, +0x3c, +0x66, +0x7e, +0x60, +0x60, +0x60, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x66, +0x00, +0x00, +0x3c, +0x66, +0x7e, +0x60, +0x60, +0x60, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x30, +0x18, +0x04, +0x00, +0x3c, +0x66, +0x7e, +0x60, +0x60, +0x60, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x66, +0x00, +0x00, +0x38, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x18, +0x2c, +0x46, +0x00, +0x38, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x60, +0x30, +0x08, +0x00, +0x38, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x66, +0x18, +0x18, +0x18, +0x3c, +0x2c, +0x2c, +0x2c, +0x7e, +0x46, +0x46, +0x46, +0xef, +0x00, +0x00, +0x00, + +0x18, +0x24, +0x18, +0x18, +0x3c, +0x2c, +0x2c, +0x2c, +0x7e, +0x46, +0x46, +0x46, +0xef, +0x00, +0x00, +0x00, + +0x0c, +0x18, +0xff, +0x61, +0x60, +0x60, +0x64, +0x7c, +0x64, +0x60, +0x60, +0x61, +0xfe, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x76, +0x9b, +0x1b, +0x3f, +0xd8, +0xd8, +0xd9, +0x6e, +0x00, +0x00, +0x00, + +0x00, +0x1f, +0x1d, +0x1d, +0x3c, +0x2c, +0x2e, +0x2c, +0x7c, +0x4c, +0x4c, +0x4d, +0xef, +0x00, +0x00, +0x00, + +0x00, +0x18, +0x2c, +0x46, +0x00, +0x3c, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x66, +0x00, +0x00, +0x3c, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x30, +0x18, +0x04, +0x00, +0x3c, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x18, +0x2c, +0x46, +0x00, +0xee, +0x66, +0x66, +0x66, +0x66, +0x66, +0x67, +0x3a, +0x00, +0x00, +0x00, + +0x00, +0x30, +0x18, +0x04, +0x00, +0xee, +0x66, +0x66, +0x66, +0x66, +0x66, +0x67, +0x3a, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x66, +0x00, +0x00, +0xf7, +0x62, +0x62, +0x34, +0x34, +0x18, +0x18, +0x18, +0x10, +0xb0, +0xe0, + +0x66, +0x00, +0x3c, +0x66, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x66, +0x00, +0xf7, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x62, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x10, +0x10, +0x10, +0x7c, +0xc6, +0xc0, +0xc0, +0xc0, +0xc0, +0xc2, +0x7c, +0x10, +0x10, +0x00, + +0x00, +0x38, +0x64, +0x6c, +0x60, +0x60, +0xf0, +0x60, +0x60, +0x60, +0x60, +0x66, +0xfc, +0x00, +0x00, +0x00, + +0x00, +0x81, +0xc3, +0x66, +0x3c, +0x18, +0xff, +0x18, +0x18, +0xff, +0x18, +0x18, +0x18, +0x00, +0x00, +0x00, + +0x00, +0xfe, +0x63, +0x63, +0x63, +0x63, +0x6e, +0x60, +0x64, +0x6e, +0x64, +0x64, +0xf5, +0x06, +0x00, +0x00, + +0x00, +0x0e, +0x19, +0x1b, +0x18, +0x18, +0x3c, +0x18, +0x18, +0x18, +0x18, +0xd8, +0x98, +0x70, +0x00, +0x00, + +0x00, +0x0c, +0x18, +0x20, +0x00, +0x78, +0x8c, +0x0c, +0x3c, +0xcc, +0xcc, +0xcd, +0x76, +0x00, +0x00, +0x00, + +0x00, +0x06, +0x0c, +0x10, +0x00, +0x38, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x0c, +0x18, +0x20, +0x00, +0x3c, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x0c, +0x18, +0x20, +0x00, +0xee, +0x66, +0x66, +0x66, +0x66, +0x66, +0x67, +0x3a, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x32, +0x4c, +0x00, +0x5c, +0xf6, +0x66, +0x66, +0x66, +0x66, +0x66, +0xf7, +0x00, +0x00, +0x00, + +0x32, +0x4c, +0x00, +0xe7, +0x72, +0x52, +0x5a, +0x4a, +0x4e, +0x46, +0x46, +0x42, +0xe2, +0x00, +0x00, +0x00, + +0x00, +0x78, +0x8c, +0x0c, +0x3c, +0xcc, +0xcc, +0xcd, +0x76, +0x00, +0xfe, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x3c, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3c, +0x00, +0x7e, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x30, +0x30, +0x00, +0x30, +0x10, +0x10, +0x20, +0x40, +0xc0, +0xc6, +0xc2, +0x7c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xfe, +0xc0, +0xc0, +0xc0, +0xc0, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xfe, +0x06, +0x06, +0x06, +0x06, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x20, +0xe0, +0x63, +0x66, +0xfc, +0x18, +0x30, +0x60, +0xce, +0x93, +0x06, +0x0c, +0x1f, +0x00, +0x00, + +0x00, +0x20, +0xe0, +0x63, +0x66, +0xfc, +0x18, +0x30, +0x64, +0xc8, +0x96, +0x3f, +0x06, +0x06, +0x00, +0x00, + +0x00, +0x18, +0x18, +0x00, +0x08, +0x18, +0x18, +0x18, +0x3c, +0x3c, +0x3c, +0x3c, +0x18, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x36, +0x6c, +0xd8, +0xd8, +0x6c, +0x36, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0xd8, +0x6c, +0x36, +0x36, +0x6c, +0xd8, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x82, +0x10, +0x82, +0x10, +0x82, +0x10, +0x82, +0x10, +0x82, +0x10, +0x82, +0x10, +0x82, +0x10, +0x82, +0x10, + +0x00, +0x95, +0x00, +0xa9, +0x00, +0x95, +0x00, +0xa9, +0x00, +0x95, +0x00, +0xa9, +0x00, +0x95, +0x00, +0xa9, + +0x92, +0x49, +0x92, +0x49, +0x92, +0x49, +0x92, +0x49, +0x92, +0x49, +0x92, +0x49, +0x92, +0x49, +0x92, +0x49, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xf8, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xf8, +0x18, +0x18, +0xf8, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xe6, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xfe, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xf8, +0x18, +0x18, +0xf8, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xe6, +0x06, +0x06, +0xe6, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xfe, +0x06, +0x06, +0xe6, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xe6, +0x06, +0x06, +0xfe, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xfe, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xf8, +0x18, +0x18, +0xf8, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xf8, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x1f, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xff, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x1f, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xff, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x1f, +0x18, +0x18, +0x1f, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x67, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x67, +0x60, +0x60, +0x7f, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x7f, +0x60, +0x60, +0x67, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xe7, +0x00, +0x00, +0xff, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0x00, +0x00, +0xe7, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x67, +0x60, +0x60, +0x67, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0x00, +0x00, +0xff, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xe7, +0x00, +0x00, +0xe7, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xff, +0x00, +0x00, +0xff, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xff, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0x00, +0x00, +0xff, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x7f, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x1f, +0x18, +0x18, +0x1f, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x1f, +0x18, +0x18, +0x1f, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x7f, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0xff, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, +0x66, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xff, +0x00, +0x00, +0xff, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xf8, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x1f, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, + +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, +0xf0, + +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, +0x0f, + +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x77, +0xcc, +0xcc, +0xcc, +0xcc, +0xde, +0x73, +0x00, +0x00, +0x00, + +0x00, +0x7c, +0xc6, +0xc6, +0xc6, +0xc4, +0xc8, +0xc4, +0xc6, +0xc6, +0xc6, +0xc6, +0xdc, +0xc0, +0xc0, +0x00, + +0x00, +0xff, +0x61, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0x60, +0xf0, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x01, +0x7e, +0xa4, +0x24, +0x2c, +0x6c, +0x6c, +0x6c, +0x48, +0x00, +0x00, +0x00, + +0x00, +0xff, +0xc1, +0x60, +0x30, +0x18, +0x0c, +0x18, +0x30, +0x60, +0xc0, +0xc1, +0xfe, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x7f, +0xc8, +0xc8, +0xc8, +0xc8, +0xc8, +0xc8, +0x70, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x22, +0x66, +0x66, +0x66, +0x66, +0x66, +0x7c, +0x60, +0x60, +0x60, +0xc0, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x76, +0xdc, +0x18, +0x18, +0x18, +0x18, +0x18, +0x10, +0x00, +0x00, +0x00, + +0x00, +0x38, +0x10, +0x7c, +0xd6, +0xd6, +0xd6, +0xd6, +0xd6, +0xd6, +0x7c, +0x10, +0x38, +0x00, +0x00, +0x00, + +0x00, +0x38, +0x6c, +0xc6, +0xc6, +0xc6, +0xfe, +0xc6, +0xc6, +0xc6, +0xc6, +0x6c, +0x38, +0x00, +0x00, +0x00, + +0x00, +0x3c, +0x66, +0xc3, +0xc3, +0xc3, +0xc3, +0xc3, +0x66, +0x24, +0x24, +0xa5, +0xe7, +0x00, +0x00, +0x00, + +0x00, +0x1e, +0x31, +0x30, +0x18, +0x0c, +0x3e, +0x66, +0x66, +0x66, +0x66, +0x66, +0x3c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x6e, +0xff, +0x99, +0x99, +0x99, +0x99, +0xff, +0x76, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x02, +0x04, +0x7c, +0xca, +0x92, +0xa6, +0x7c, +0x40, +0x80, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x1c, +0x30, +0x60, +0x60, +0x60, +0x7c, +0x60, +0x60, +0x60, +0x60, +0x30, +0x1c, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x7c, +0xc6, +0xc6, +0xc6, +0xc6, +0xc6, +0xc6, +0xc6, +0xc6, +0xc6, +0xc6, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0xfe, +0x00, +0x00, +0x00, +0x7c, +0x00, +0x00, +0x00, +0xfe, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x18, +0x18, +0x7e, +0x18, +0x18, +0x00, +0x00, +0x7e, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x30, +0x18, +0x0c, +0x06, +0x0c, +0x18, +0x30, +0x00, +0x7e, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x0c, +0x18, +0x30, +0x60, +0x30, +0x18, +0x0c, +0x00, +0x7e, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x0e, +0x19, +0x1b, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, + +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0x18, +0xd8, +0x98, +0x70, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x18, +0x18, +0x00, +0x7e, +0x00, +0x18, +0x18, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x76, +0xdc, +0x00, +0x00, +0x76, +0xdc, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x38, +0x44, +0x44, +0x44, +0x38, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x18, +0x18, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x18, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x07, +0x06, +0x06, +0x0c, +0x0c, +0x08, +0x98, +0xd0, +0xf0, +0x60, +0x20, +0x00, +0x00, +0x00, + +0x00, +0xcc, +0x76, +0x66, +0x66, +0x66, +0x66, +0xf7, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x70, +0x98, +0x18, +0x30, +0x60, +0x88, +0xf8, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x7c, +0x64, +0x64, +0x64, +0x64, +0x64, +0x7c, +0x00, +0x00, +0x00, +0x00, + +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +}; + + +const struct font_desc font_rl = { + RL_IDX, + "RomanLarge", + 8, + 16, + patterns, + -1 +}; diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c index 4fd07d9eca0..9be83bed195 100644 --- a/drivers/video/console/fonts.c +++ b/drivers/video/console/fonts.c @@ -64,6 +64,10 @@ static const struct font_desc *fonts[] = { #undef NO_FONTS &font_mini_4x6, #endif +#ifdef CONFIG_FONT_RL +#undef NO_FONTS + &font_rl, +#endif }; #define num_fonts (sizeof(fonts)/sizeof(*fonts)) diff --git a/drivers/video/softcursor.c b/drivers/video/console/softcursor.c index 229c4bc3507..8529bf08db2 100644 --- a/drivers/video/softcursor.c +++ b/drivers/video/console/softcursor.c @@ -1,7 +1,7 @@ /* * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices * - * Created 14 Nov 2002 by James Simmons + * Created 14 Nov 2002 by James Simmons * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive @@ -55,9 +55,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) src[i] = image->data[i] & cursor->mask[i]; break; } - } else + } else memcpy(src, image->data, dsize); - + fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); image->data = dst; info->fbops->fb_imageblit(info, image); @@ -66,7 +66,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) } EXPORT_SYMBOL(soft_cursor); - + MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>"); MODULE_DESCRIPTION("Generic software cursor"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c index 7f76e2c6a4a..cb25324a563 100644 --- a/drivers/video/console/tileblit.c +++ b/drivers/video/console/tileblit.c @@ -118,6 +118,18 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, info->tileops->fb_tilecursor(info, &cursor); } +static int tile_update_start(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + int err; + + err = fb_pan_display(info, &ops->var); + ops->var.xoffset = info->var.xoffset; + ops->var.yoffset = info->var.yoffset; + ops->var.vmode = info->var.vmode; + return err; +} + void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, struct display *p, struct fbcon_ops *ops) { @@ -128,6 +140,7 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, ops->putcs = tile_putcs; ops->clear_margins = tile_clear_margins; ops->cursor = tile_cursor; + ops->update_start = tile_update_start; if (p) { map.width = vc->vc_font.width; diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 56cd199605f..274f90543e3 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -448,7 +448,8 @@ static void vgacon_cursor(struct vc_data *c, int mode) vgacon_scrolldelta(c, 0); switch (mode) { case CM_ERASE: - write_vga(14, (vga_vram_end - vga_vram_base - 1) / 2); + write_vga(14, (c->vc_pos - vga_vram_base) / 2); + vgacon_set_cursor_size(c->vc_x, 31, 30); break; case CM_MOVE: diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 989e700159e..403d17377f8 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c @@ -176,7 +176,6 @@ static struct fb_ops controlfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index 3894b2a501d..c589d23e7f9 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -1064,7 +1064,6 @@ static struct fb_ops cyber2000fb_ops = { .fb_fillrect = cyber2000fb_fillrect, .fb_copyarea = cyber2000fb_copyarea, .fb_imageblit = cyber2000fb_imageblit, - .fb_cursor = soft_cursor, .fb_sync = cyber2000fb_sync, }; diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c index 6992100a508..03fbe83d71a 100644 --- a/drivers/video/cyblafb.c +++ b/drivers/video/cyblafb.c @@ -968,7 +968,6 @@ static struct fb_ops cyblafb_ops __devinitdata = { .fb_fillrect = cyblafb_fillrect, .fb_copyarea= cyblafb_copyarea, .fb_imageblit = cyblafb_imageblit, - .fb_cursor = soft_cursor, }; //========================================================================== diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c index 1785686a7f1..957a3ada2b7 100644 --- a/drivers/video/dnfb.c +++ b/drivers/video/dnfb.c @@ -116,7 +116,6 @@ static struct fb_ops dn_fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = dnfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; struct fb_var_screeninfo dnfb_var __devinitdata = { diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 7363d0b25fd..6a81a1dd8f3 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -484,7 +484,6 @@ static struct fb_ops epson1355fb_fbops = { .fb_imageblit = cfb_imageblit, .fb_read = epson1355fb_read, .fb_write = epson1355fb_write, - .fb_cursor = soft_cursor, }; /* ------------------------------------------------------------------------- */ diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e2667ddab3f..9f180096c89 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -14,6 +14,7 @@ #include <linux/config.h> #include <linux/module.h> +#include <linux/compat.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/sched.h> @@ -323,9 +324,103 @@ static struct logo_data { const struct linux_logo *logo; } fb_logo; -int fb_prepare_logo(struct fb_info *info) +static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height) +{ + u32 size = width * height, i; + + out += size - 1; + + for (i = size; i--; ) + *out-- = *in++; +} + +static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height) +{ + int i, j, w = width - 1; + + for (i = 0; i < height; i++) + for (j = 0; j < width; j++) + out[height * j + w - i] = *in++; +} + +static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height) +{ + int i, j, w = width - 1; + + for (i = 0; i < height; i++) + for (j = 0; j < width; j++) + out[height * (w - j) + i] = *in++; +} + +static void fb_rotate_logo(struct fb_info *info, u8 *dst, + struct fb_image *image, int rotate) +{ + u32 tmp; + + if (rotate == FB_ROTATE_UD) { + image->dx = info->var.xres - image->width; + image->dy = info->var.yres - image->height; + fb_rotate_logo_ud(image->data, dst, image->width, + image->height); + } else if (rotate == FB_ROTATE_CW) { + tmp = image->width; + image->width = image->height; + image->height = tmp; + image->dx = info->var.xres - image->height; + fb_rotate_logo_cw(image->data, dst, image->width, + image->height); + } else if (rotate == FB_ROTATE_CCW) { + tmp = image->width; + image->width = image->height; + image->height = tmp; + image->dy = info->var.yres - image->width; + fb_rotate_logo_ccw(image->data, dst, image->width, + image->height); + } + + image->data = dst; +} + +static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, + int rotate) +{ + int x; + + if (rotate == FB_ROTATE_UR) { + for (x = 0; x < num_online_cpus() && + x * (fb_logo.logo->width + 8) <= + info->var.xres - fb_logo.logo->width; x++) { + info->fbops->fb_imageblit(info, image); + image->dx += fb_logo.logo->width + 8; + } + } else if (rotate == FB_ROTATE_UD) { + for (x = 0; x < num_online_cpus() && + x * (fb_logo.logo->width + 8) <= + info->var.xres - fb_logo.logo->width; x++) { + info->fbops->fb_imageblit(info, image); + image->dx -= fb_logo.logo->width + 8; + } + } else if (rotate == FB_ROTATE_CW) { + for (x = 0; x < num_online_cpus() && + x * (fb_logo.logo->width + 8) <= + info->var.yres - fb_logo.logo->width; x++) { + info->fbops->fb_imageblit(info, image); + image->dy += fb_logo.logo->width + 8; + } + } else if (rotate == FB_ROTATE_CCW) { + for (x = 0; x < num_online_cpus() && + x * (fb_logo.logo->width + 8) <= + info->var.yres - fb_logo.logo->width; x++) { + info->fbops->fb_imageblit(info, image); + image->dy -= fb_logo.logo->width + 8; + } + } +} + +int fb_prepare_logo(struct fb_info *info, int rotate) { int depth = fb_get_color_depth(&info->var, &info->fix); + int yres; memset(&fb_logo, 0, sizeof(struct logo_data)); @@ -358,10 +453,16 @@ int fb_prepare_logo(struct fb_info *info) /* Return if no suitable logo was found */ fb_logo.logo = fb_find_logo(depth); - if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { + if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD) + yres = info->var.yres; + else + yres = info->var.xres; + + if (fb_logo.logo && fb_logo.logo->height > yres) { fb_logo.logo = NULL; return 0; } + /* What depth we asked for might be different from what we get */ if (fb_logo.logo->type == LINUX_LOGO_CLUT224) fb_logo.depth = 8; @@ -372,12 +473,11 @@ int fb_prepare_logo(struct fb_info *info) return fb_logo.logo->height; } -int fb_show_logo(struct fb_info *info) +int fb_show_logo(struct fb_info *info, int rotate) { u32 *palette = NULL, *saved_pseudo_palette = NULL; - unsigned char *logo_new = NULL; + unsigned char *logo_new = NULL, *logo_rotate = NULL; struct fb_image image; - int x; /* Return if the frame buffer is not mapped or suspended */ if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) @@ -417,25 +517,30 @@ int fb_show_logo(struct fb_info *info) fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); } + image.dx = 0; + image.dy = 0; image.width = fb_logo.logo->width; image.height = fb_logo.logo->height; - image.dy = 0; - for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && - x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { - image.dx = x; - info->fbops->fb_imageblit(info, &image); + if (rotate) { + logo_rotate = kmalloc(fb_logo.logo->width * + fb_logo.logo->height, GFP_KERNEL); + if (logo_rotate) + fb_rotate_logo(info, logo_rotate, &image, rotate); } - + + fb_do_show_logo(info, &image, rotate); + kfree(palette); if (saved_pseudo_palette != NULL) info->pseudo_palette = saved_pseudo_palette; kfree(logo_new); + kfree(logo_rotate); return fb_logo.logo->height; } #else -int fb_prepare_logo(struct fb_info *info) { return 0; } -int fb_show_logo(struct fb_info *info) { return 0; } +int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; } +int fb_show_logo(struct fb_info *info, int rotate) { return 0; } #endif /* CONFIG_LOGO */ static int fbmem_read_proc(char *buf, char **start, off_t offset, @@ -829,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } #ifdef CONFIG_COMPAT +struct fb_fix_screeninfo32 { + char id[16]; + compat_caddr_t smem_start; + u32 smem_len; + u32 type; + u32 type_aux; + u32 visual; + u16 xpanstep; + u16 ypanstep; + u16 ywrapstep; + u32 line_length; + compat_caddr_t mmio_start; + u32 mmio_len; + u32 accel; + u16 reserved[3]; +}; + +struct fb_cmap32 { + u32 start; + u32 len; + compat_caddr_t red; + compat_caddr_t green; + compat_caddr_t blue; + compat_caddr_t transp; +}; + +static int fb_getput_cmap(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct fb_cmap_user __user *cmap; + struct fb_cmap32 __user *cmap32; + __u32 data; + int err; + + cmap = compat_alloc_user_space(sizeof(*cmap)); + cmap32 = compat_ptr(arg); + + if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32))) + return -EFAULT; + + if (get_user(data, &cmap32->red) || + put_user(compat_ptr(data), &cmap->red) || + get_user(data, &cmap32->green) || + put_user(compat_ptr(data), &cmap->green) || + get_user(data, &cmap32->blue) || + put_user(compat_ptr(data), &cmap->blue) || + get_user(data, &cmap32->transp) || + put_user(compat_ptr(data), &cmap->transp)) + return -EFAULT; + + err = fb_ioctl(inode, file, cmd, (unsigned long) cmap); + + if (!err) { + if (copy_in_user(&cmap32->start, + &cmap->start, + 2 * sizeof(__u32))) + err = -EFAULT; + } + return err; +} + +static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix, + struct fb_fix_screeninfo32 __user *fix32) +{ + __u32 data; + int err; + + err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id)); + + data = (__u32) (unsigned long) fix->smem_start; + err |= put_user(data, &fix32->smem_start); + + err |= put_user(fix->smem_len, &fix32->smem_len); + err |= put_user(fix->type, &fix32->type); + err |= put_user(fix->type_aux, &fix32->type_aux); + err |= put_user(fix->visual, &fix32->visual); + err |= put_user(fix->xpanstep, &fix32->xpanstep); + err |= put_user(fix->ypanstep, &fix32->ypanstep); + err |= put_user(fix->ywrapstep, &fix32->ywrapstep); + err |= put_user(fix->line_length, &fix32->line_length); + + data = (__u32) (unsigned long) fix->mmio_start; + err |= put_user(data, &fix32->mmio_start); + + err |= put_user(fix->mmio_len, &fix32->mmio_len); + err |= put_user(fix->accel, &fix32->accel); + err |= copy_to_user(fix32->reserved, fix->reserved, + sizeof(fix->reserved)); + + return err; +} + +static int fb_get_fscreeninfo(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + mm_segment_t old_fs; + struct fb_fix_screeninfo fix; + struct fb_fix_screeninfo32 __user *fix32; + int err; + + fix32 = compat_ptr(arg); + + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = fb_ioctl(inode, file, cmd, (unsigned long) &fix); + set_fs(old_fs); + + if (!err) + err = do_fscreeninfo_to_user(&fix, fix32); + + return err; +} + static long fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - int fbidx = iminor(file->f_dentry->d_inode); + struct inode *inode = file->f_dentry->d_inode; + int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; struct fb_ops *fb = info->fbops; - long ret; + long ret = -ENOIOCTLCMD; - if (fb->fb_compat_ioctl == NULL) - return -ENOIOCTLCMD; lock_kernel(); - ret = fb->fb_compat_ioctl(file, cmd, arg, info); + switch(cmd) { + case FBIOGET_VSCREENINFO: + case FBIOPUT_VSCREENINFO: + case FBIOPAN_DISPLAY: + case FBIOGET_CON2FBMAP: + case FBIOPUT_CON2FBMAP: + arg = (unsigned long) compat_ptr(arg); + case FBIOBLANK: + ret = fb_ioctl(inode, file, cmd, arg); + break; + + case FBIOGET_FSCREENINFO: + ret = fb_get_fscreeninfo(inode, file, cmd, arg); + break; + + case FBIOGETCMAP: + case FBIOPUTCMAP: + ret = fb_getput_cmap(inode, file, cmd, arg); + break; + + default: + if (fb->fb_compat_ioctl) + ret = fb->fb_compat_ioctl(file, cmd, arg, info); + break; + } unlock_kernel(); return ret; } @@ -1215,6 +1456,28 @@ int fb_new_modelist(struct fb_info *info) return err; } +/** + * fb_con_duit - user<->fbcon passthrough + * @info: struct fb_info + * @event: notification event to be passed to fbcon + * @data: private data + * + * DESCRIPTION + * This function is an fbcon-user event passing channel + * which bypasses fbdev. This is hopefully temporary + * until a user interface for fbcon is created + */ +int fb_con_duit(struct fb_info *info, int event, void *data) +{ + struct fb_event evnt; + + evnt.info = info; + evnt.data = data; + + return notifier_call_chain(&fb_notifier_list, event, &evnt); +} +EXPORT_SYMBOL(fb_con_duit); + static char *video_options[FB_MAX]; static int ofonly; diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 713226cdf3c..fc7965b6677 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -538,25 +538,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) *dbsize = 0; - DPRINTK(" Supported VESA Modes\n"); - block = edid + ESTABLISHED_TIMING_1; - num += get_est_timing(block, &mode[num]); - - DPRINTK(" Standard Timings\n"); - block = edid + STD_TIMING_DESCRIPTIONS_START; - for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) - num += get_std_timing(block, &mode[num]); - DPRINTK(" Detailed Timings\n"); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { int first = 1; - if (block[0] == 0x00 && block[1] == 0x00) { - if (block[3] == 0xfa) { - num += get_dst_timing(block + 5, &mode[num]); - } - } else { + if (!(block[0] == 0x00 && block[1] == 0x00)) { get_detailed_timing(block, &mode[num]); if (first) { mode[num].flag |= FB_MODE_IS_FIRST; @@ -565,6 +552,21 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) num++; } } + + DPRINTK(" Supported VESA Modes\n"); + block = edid + ESTABLISHED_TIMING_1; + num += get_est_timing(block, &mode[num]); + + DPRINTK(" Standard Timings\n"); + block = edid + STD_TIMING_DESCRIPTIONS_START; + for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) + num += get_std_timing(block, &mode[num]); + + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; + for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { + if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) + num += get_dst_timing(block + 5, &mode[num]); + } /* Yikes, EDID data is totally useless */ if (!num) { @@ -827,7 +829,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) { unsigned char *block; - int i; + int i, found = 0; if (edid == NULL) return; @@ -869,6 +871,22 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) get_monspecs(edid, specs); specs->modedb = fb_create_modedb(edid, &specs->modedb_len); + + /* + * Workaround for buggy EDIDs that sets that the first + * detailed timing is preferred but has not detailed + * timing specified + */ + for (i = 0; i < specs->modedb_len; i++) { + if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) { + found = 1; + break; + } + } + + if (!found) + specs->misc &= ~FB_MISC_1ST_DETAIL; + DPRINTK("========================================\n"); } diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 007c8e9b2b3..08dac9580d1 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -213,6 +213,70 @@ static ssize_t show_bpp(struct class_device *class_device, char *buf) return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); } +static ssize_t store_rotate(struct class_device *class_device, const char *buf, + size_t count) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + struct fb_var_screeninfo var; + char **last = NULL; + int err; + + var = fb_info->var; + var.rotate = simple_strtoul(buf, last, 0); + + if ((err = activate(fb_info, &var))) + return err; + + return count; +} + + +static ssize_t show_rotate(struct class_device *class_device, char *buf) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + + return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); +} + +static ssize_t store_con_rotate(struct class_device *class_device, + const char *buf, size_t count) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + int rotate; + char **last = NULL; + + acquire_console_sem(); + rotate = simple_strtoul(buf, last, 0); + fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate); + release_console_sem(); + return count; +} + +static ssize_t store_con_rotate_all(struct class_device *class_device, + const char *buf, size_t count) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + int rotate; + char **last = NULL; + + acquire_console_sem(); + rotate = simple_strtoul(buf, last, 0); + fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate); + release_console_sem(); + return count; +} + +static ssize_t show_con_rotate(struct class_device *class_device, char *buf) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + int rotate; + + acquire_console_sem(); + rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL); + release_console_sem(); + return snprintf(buf, PAGE_SIZE, "%d\n", rotate); +} + static ssize_t store_virtual(struct class_device *class_device, const char * buf, size_t count) { @@ -440,6 +504,9 @@ static struct class_device_attribute class_device_attrs[] = { __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), __ATTR(name, S_IRUGO, show_name, NULL), __ATTR(stride, S_IRUGO, show_stride, NULL), + __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), + __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate), + __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all), }; int fb_init_class_device(struct fb_info *fb_info) diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 10cd05059fe..04417dc16c2 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -57,9 +57,6 @@ static struct fb_ops ffb_ops = { .fb_sync = ffb_sync, .fb_mmap = ffb_mmap, .fb_ioctl = ffb_ioctl, - - /* XXX Use FFB hw cursor once fb cursor API is better understood... */ - .fb_cursor = soft_cursor, }; /* Register layout and definitions */ diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c index a0763283d77..998374cfae6 100644 --- a/drivers/video/fm2fb.c +++ b/drivers/video/fm2fb.c @@ -172,7 +172,6 @@ static struct fb_ops fm2fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; /* diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 316bfe99481..9d5e4f34211 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -1038,7 +1038,6 @@ static struct fb_ops gbefb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; /* @@ -1260,24 +1259,30 @@ static struct device_driver gbefb_driver = { .remove = __devexit_p(gbefb_remove), }; -static struct platform_device gbefb_device = { - .name = "gbefb", -}; +static struct platform_device *gbefb_device; int __init gbefb_init(void) { int ret = driver_register(&gbefb_driver); if (!ret) { - ret = platform_device_register(&gbefb_device); - if (ret) + gbefb_device = platform_device_alloc("gbefb", 0); + if (gbefb_device) { + ret = platform_device_add(gbefb_device); + } else { + ret = -ENOMEM; + } + if (ret) { + platform_device_put(gbefb_device); driver_unregister(&gbefb_driver); + } } return ret; } void __exit gbefb_exit(void) { - driver_unregister(&gbefb_driver); + platform_device_unregister(gbefb_device); + driver_unregister(&gbefb_driver); } module_init(gbefb_init); diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig index 5a9b89c3831..42fb9a89a79 100644 --- a/drivers/video/geode/Kconfig +++ b/drivers/video/geode/Kconfig @@ -14,7 +14,6 @@ config FB_GEODE_GX1 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR ---help--- Framebuffer driver for the display controller integrated into the AMD Geode GX1 processor. diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c index 74a5fca86b8..8e8da743399 100644 --- a/drivers/video/geode/gx1fb_core.c +++ b/drivers/video/geode/gx1fb_core.c @@ -275,7 +275,6 @@ static struct fb_ops gx1fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev) diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 0d376ba5481..f04ca721f94 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -262,7 +262,6 @@ static struct fb_ops hitfb_ops = { .fb_fillrect = hitfb_fillrect, .fb_copyarea = hitfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; int __init hitfb_init(void) diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c index e97fe8481d5..bebdac59d23 100644 --- a/drivers/video/hpfb.c +++ b/drivers/video/hpfb.c @@ -193,7 +193,6 @@ static struct fb_ops hpfb_ops = { .fb_fillrect = hpfb_fillrect, .fb_copyarea = hpfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, .fb_sync = hpfb_sync, }; diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index 689d2586366..c61bad0da20 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c @@ -46,92 +46,45 @@ static void i810i2c_setscl(void *data, int state) struct i810fb_par *par = chan->par; u8 __iomem *mmio = par->mmio_start_virtual; - i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR | + i810_writel(mmio, chan->ddc_base, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); - i810_readl(mmio, GPIOB); /* flush posted write */ + i810_readl(mmio, chan->ddc_base); /* flush posted write */ } static void i810i2c_setsda(void *data, int state) { - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; + struct i810fb_i2c_chan *chan = data; struct i810fb_par *par = chan->par; u8 __iomem *mmio = par->mmio_start_virtual; - i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR | + i810_writel(mmio, chan->ddc_base, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); - i810_readl(mmio, GPIOB); /* flush posted write */ + i810_readl(mmio, chan->ddc_base); /* flush posted write */ } static int i810i2c_getscl(void *data) { - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; + struct i810fb_i2c_chan *chan = data; struct i810fb_par *par = chan->par; u8 __iomem *mmio = par->mmio_start_virtual; - i810_writel(mmio, GPIOB, SCL_DIR_MASK); - i810_writel(mmio, GPIOB, 0); - return (0 != (i810_readl(mmio, GPIOB) & SCL_VAL_IN)); + i810_writel(mmio, chan->ddc_base, SCL_DIR_MASK); + i810_writel(mmio, chan->ddc_base, 0); + return ((i810_readl(mmio, chan->ddc_base) & SCL_VAL_IN) != 0); } static int i810i2c_getsda(void *data) { - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; + struct i810fb_i2c_chan *chan = data; struct i810fb_par *par = chan->par; u8 __iomem *mmio = par->mmio_start_virtual; - i810_writel(mmio, GPIOB, SDA_DIR_MASK); - i810_writel(mmio, GPIOB, 0); - return (0 != (i810_readl(mmio, GPIOB) & SDA_VAL_IN)); -} - -static void i810ddc_setscl(void *data, int state) -{ - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; - struct i810fb_par *par = chan->par; - u8 __iomem *mmio = par->mmio_start_virtual; - - i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR | - SCL_DIR_MASK | SCL_VAL_MASK); - i810_readl(mmio, GPIOA); /* flush posted write */ -} - -static void i810ddc_setsda(void *data, int state) -{ - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; - struct i810fb_par *par = chan->par; - u8 __iomem *mmio = par->mmio_start_virtual; - - i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR | - SDA_DIR_MASK | SDA_VAL_MASK); - i810_readl(mmio, GPIOA); /* flush posted write */ -} - -static int i810ddc_getscl(void *data) -{ - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; - struct i810fb_par *par = chan->par; - u8 __iomem *mmio = par->mmio_start_virtual; - - i810_writel(mmio, GPIOA, SCL_DIR_MASK); - i810_writel(mmio, GPIOA, 0); - return (0 != (i810_readl(mmio, GPIOA) & SCL_VAL_IN)); -} - -static int i810ddc_getsda(void *data) -{ - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; - struct i810fb_par *par = chan->par; - u8 __iomem *mmio = par->mmio_start_virtual; - - i810_writel(mmio, GPIOA, SDA_DIR_MASK); - i810_writel(mmio, GPIOA, 0); - return (0 != (i810_readl(mmio, GPIOA) & SDA_VAL_IN)); + i810_writel(mmio, chan->ddc_base, SDA_DIR_MASK); + i810_writel(mmio, chan->ddc_base, 0); + return ((i810_readl(mmio, chan->ddc_base) & SDA_VAL_IN) != 0); } -#define I2C_ALGO_DDC_I810 0x0e0000 -#define I2C_ALGO_I2C_I810 0x0f0000 -static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name, - int conn) +static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name) { int rc; @@ -139,22 +92,11 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name, chan->adapter.owner = THIS_MODULE; chan->adapter.algo_data = &chan->algo; chan->adapter.dev.parent = &chan->par->dev->dev; - switch (conn) { - case 1: - chan->adapter.id = I2C_ALGO_DDC_I810; - chan->algo.setsda = i810ddc_setsda; - chan->algo.setscl = i810ddc_setscl; - chan->algo.getsda = i810ddc_getsda; - chan->algo.getscl = i810ddc_getscl; - break; - case 2: - chan->adapter.id = I2C_ALGO_I2C_I810; - chan->algo.setsda = i810i2c_setsda; - chan->algo.setscl = i810i2c_setscl; - chan->algo.getsda = i810i2c_getsda; - chan->algo.getscl = i810i2c_getscl; - break; - } + chan->adapter.id = I2C_HW_B_I810; + chan->algo.setsda = i810i2c_setsda; + chan->algo.setscl = i810i2c_setscl; + chan->algo.getsda = i810i2c_getsda; + chan->algo.getscl = i810i2c_getscl; chan->algo.udelay = 10; chan->algo.mdelay = 10; chan->algo.timeout = (HZ/2); @@ -168,11 +110,15 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name, udelay(20); rc = i2c_bit_add_bus(&chan->adapter); + if (rc == 0) dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name); - else + else { dev_warn(&chan->par->dev->dev, "Failed to register I2C bus " "%s.\n", name); + chan->par = NULL; + } + return rc; } @@ -180,8 +126,14 @@ void i810_create_i2c_busses(struct i810fb_par *par) { par->chan[0].par = par; par->chan[1].par = par; - i810_setup_i2c_bus(&par->chan[0], "I810-DDC", 1); - i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 2); + par->chan[2].par = par; + + par->chan[0].ddc_base = GPIOA; + i810_setup_i2c_bus(&par->chan[0], "I810-DDC"); + par->chan[1].ddc_base = GPIOB; + i810_setup_i2c_bus(&par->chan[1], "I810-I2C"); + par->chan[2].ddc_base = GPIOC; + i810_setup_i2c_bus(&par->chan[2], "I810-GPIOC"); } void i810_delete_i2c_busses(struct i810fb_par *par) @@ -189,9 +141,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par) if (par->chan[0].par) i2c_bit_del_bus(&par->chan[0].adapter); par->chan[0].par = NULL; + if (par->chan[1].par) i2c_bit_del_bus(&par->chan[1].adapter); par->chan[1].par = NULL; + + if (par->chan[2].par) + i2c_bit_del_bus(&par->chan[2].adapter); + par->chan[2].par = NULL; } static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan) @@ -221,6 +178,7 @@ static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan) DPRINTK("i810-i2c: I2C Transfer successful\n"); return buf; } + DPRINTK("i810-i2c: Unable to read EDID block.\n"); kfree(buf); return NULL; @@ -233,7 +191,7 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn) int i; DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn); - if (conn < 3) { + if (conn < 4) { for (i = 0; i < 3; i++) { /* Do the real work */ edid = i810_do_probe_i2c_edid(&par->chan[conn-1]); @@ -241,11 +199,14 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn) break; } } else { - DPRINTK("i810-i2c: Getting EDID from BIOS\n"); - edid = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (edid) - memcpy(edid, fb_firmware_edid(info->device), - EDID_LENGTH); + const u8 *e = fb_firmware_edid(info->device); + + if (e != NULL) { + DPRINTK("i810-i2c: Getting EDID from BIOS\n"); + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (edid) + memcpy(edid, e, EDID_LENGTH); + } } if (out_edid) @@ -253,5 +214,3 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn) return (edid) ? 0 : 1; } - - diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h index d48949ceaac..6c187d5fe95 100644 --- a/drivers/video/i810/i810.h +++ b/drivers/video/i810/i810.h @@ -249,6 +249,7 @@ struct i810fb_i2c_chan { struct i810fb_par *par; struct i2c_adapter adapter; struct i2c_algo_bit_data algo; + unsigned long ddc_base; }; struct i810fb_par { @@ -262,7 +263,7 @@ struct i810fb_par { struct heap_data iring; struct heap_data cursor_heap; struct vgastate state; - struct i810fb_i2c_chan chan[2]; + struct i810fb_i2c_chan chan[3]; atomic_t use_count; u32 pseudo_palette[17]; unsigned long mmio_start_phys; diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 0dbc9ddb676..c0c974b1afa 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -1854,7 +1854,7 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info) #ifdef CONFIG_FB_I810_I2C i810_create_i2c_busses(par); - for (i = 0; i < 3; i++) { + for (i = 0; i < 4; i++) { err = i810_probe_i2c_connector(info, &par->edid, i+1); if (!err) break; @@ -1871,27 +1871,18 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info) fb_videomode_to_modelist(specs->modedb, specs->modedb_len, &info->modelist); if (specs->modedb != NULL) { - if (xres && yres) { - struct fb_videomode *m; + struct fb_videomode *m; + if (xres && yres) { if ((m = fb_find_best_mode(&var, &info->modelist))) { mode = *m; found = 1; } } - if (!found && specs->misc & FB_MISC_1ST_DETAIL) { - for (i = 0; i < specs->modedb_len; i++) { - if (specs->modedb[i].flag & FB_MODE_IS_FIRST) { - mode = specs->modedb[i]; - found = 1; - break; - } - } - } - if (!found) { - mode = specs->modedb[0]; + m = fb_find_best_display(&info->monspecs, &info->modelist); + mode = *m; found = 1; } @@ -2066,8 +2057,7 @@ static void i810fb_release_resource(struct fb_info *info, iounmap(par->mmio_start_virtual); if (par->aperture.virtual) iounmap(par->aperture.virtual); - if (par->edid) - kfree(par->edid); + kfree(par->edid); if (par->res_flags & FRAMEBUFFER_REQ) release_mem_region(par->aperture.physical, par->aperture.size); diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/i810/i810_regs.h index 6e4b9afa4d9..91c6bd9d0d0 100644 --- a/drivers/video/i810/i810_regs.h +++ b/drivers/video/i810/i810_regs.h @@ -70,6 +70,7 @@ #define HVSYNC 0x05000 #define GPIOA 0x05010 #define GPIOB 0x05014 +#define GPIOC 0x0501C /* Clock Control and Power Management Registers (06000h 06FFFh) */ #define DCLK_0D 0x06000 diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index 7b9bf45ab6f..7fbe24206b1 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -1344,7 +1344,6 @@ static struct fb_ops imsttfb_ops = { .fb_fillrect = imsttfb_fillrect, .fb_copyarea = imsttfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, .fb_ioctl = imsttfb_ioctl, }; diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 64d9bcc38da..e20b9f3a255 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -298,7 +298,6 @@ static struct fb_ops imxfb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_blank = imxfb_blank, - .fb_cursor = soft_cursor, /* FIXME: i.MX can do hardware cursor */ }; /* diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index 011e1162655..f077ca34fab 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h @@ -10,7 +10,7 @@ /*** Version/name ***/ #define INTELFB_VERSION "0.9.2" #define INTELFB_MODULE_NAME "intelfb" -#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G" +#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM" /*** Debug/feature defines ***/ @@ -47,6 +47,7 @@ #define PCI_DEVICE_ID_INTEL_85XGM 0x3582 #define PCI_DEVICE_ID_INTEL_865G 0x2572 #define PCI_DEVICE_ID_INTEL_915G 0x2582 +#define PCI_DEVICE_ID_INTEL_915GM 0x2592 /* Size of MMIO region */ #define INTEL_REG_SIZE 0x80000 @@ -119,7 +120,8 @@ enum intel_chips { INTEL_855GM, INTEL_855GME, INTEL_865G, - INTEL_915G + INTEL_915G, + INTEL_915GM }; struct intelfb_hwstate { diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 80a09344f1a..427689e584d 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -1,7 +1,7 @@ /* * intelfb * - * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G + * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM * integrated graphics chips. * * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> @@ -122,7 +122,6 @@ #include <linux/pci.h> #include <linux/vmalloc.h> #include <linux/pagemap.h> -#include <linux/version.h> #include <asm/io.h> @@ -186,6 +185,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, { 0, } }; @@ -549,10 +549,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Set base addresses. */ - if (ent->device == PCI_DEVICE_ID_INTEL_915G) { + if ((ent->device == PCI_DEVICE_ID_INTEL_915G) || + (ent->device == PCI_DEVICE_ID_INTEL_915GM)) { aperture_bar = 2; mmio_bar = 0; - /* Disable HW cursor on 915G (not implemented yet) */ + /* Disable HW cursor on 915G/M (not implemented yet) */ hwcursor = 0; } dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); @@ -1483,7 +1484,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) #endif if (!dinfo->hwcursor) - return soft_cursor(info, cursor); + return -ENODEV; intelfbhw_cursor_hide(dinfo); diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 5bafc3c54db..624c4bc96f0 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -34,7 +34,6 @@ #include <linux/pci.h> #include <linux/vmalloc.h> #include <linux/pagemap.h> -#include <linux/version.h> #include <asm/io.h> @@ -99,6 +98,11 @@ intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset, *chipset = INTEL_915G; *mobile = 0; return 0; + case PCI_DEVICE_ID_INTEL_915GM: + *name = "Intel(R) 915GM"; + *chipset = INTEL_915GM; + *mobile = 1; + return 0; default: return 1; } diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c index d8bac9e9784..5eb4d5c177b 100644 --- a/drivers/video/kyro/fbdev.c +++ b/drivers/video/kyro/fbdev.c @@ -669,7 +669,6 @@ static struct fb_ops kyrofb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static int __devinit kyrofb_probe(struct pci_dev *pdev, diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 7e1e7fb168b..84a7fe435bb 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -51,7 +51,6 @@ static struct fb_ops leo_ops = { .fb_imageblit = cfb_imageblit, .fb_mmap = leo_mmap, .fb_ioctl = leo_ioctl, - .fb_cursor = soft_cursor, }; #define LEO_OFF_LC_SS0_KRN 0x00200000UL diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig index 3e9ccf370ab..8cb7fb4db44 100644 --- a/drivers/video/logo/Kconfig +++ b/drivers/video/logo/Kconfig @@ -7,6 +7,8 @@ menu "Logo configuration" config LOGO bool "Bootup logo" depends on FB || SGI_NEWPORT_CONSOLE + help + Enable and select frame buffer bootup logos. config LOGO_LINUX_MONO bool "Standard black and white Linux logo" diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index 4945a4c0220..cfc748e9427 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c @@ -589,7 +589,6 @@ static struct fb_ops macfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; void __init macfb_setup(char *options) diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c index 149680f8bcf..0fbd9b5149f 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/matrox/matroxfb_DAC1064.c @@ -657,7 +657,6 @@ static int MGA1064_preinit(WPMINFO2) { /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ ACCESS_FBINFO(capable.text) = 1; ACCESS_FBINFO(capable.vxres) = vxres_mystique; - ACCESS_FBINFO(features.accel.has_cacheflush) = 1; ACCESS_FBINFO(outputs[0]).output = &m1064; ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; @@ -842,7 +841,6 @@ static int MGAG100_preinit(WPMINFO2) { /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ ACCESS_FBINFO(capable.text) = 1; ACCESS_FBINFO(capable.vxres) = vxres_g100; - ACCESS_FBINFO(features.accel.has_cacheflush) = 1; ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100 ? ACCESS_FBINFO(devflags.sgram) : 1; @@ -980,7 +978,7 @@ static void MGAG100_reset(WPMINFO2) { hw->MXoptionReg |= 0x40; /* FIXME... */ pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); } - mga_setr(M_EXTVGA_INDEX, 0x06, 0x50); + mga_setr(M_EXTVGA_INDEX, 0x06, 0x00); } } if (ACCESS_FBINFO(devflags.g450dac)) { diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c index c7f3e132122..a5c825d9946 100644 --- a/drivers/video/matrox/matroxfb_accel.c +++ b/drivers/video/matrox/matroxfb_accel.c @@ -122,7 +122,7 @@ void matrox_cfbX_init(WPMINFO2) { ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea; ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect; ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit; - ACCESS_FBINFO(fbops).fb_cursor = soft_cursor; + ACCESS_FBINFO(fbops).fb_cursor = NULL; accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT; diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index e02da41f1b2..1e74f4cca53 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -264,7 +264,6 @@ static void matroxfb_disable_irq(WPMINFO2) { } int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { - wait_queue_t __wait; struct matrox_vsync *vs; unsigned int cnt; int ret; @@ -286,7 +285,6 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { if (ret) { return ret; } - init_waitqueue_entry(&__wait, current); cnt = vs->cnt; ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10); @@ -500,10 +498,6 @@ static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) { } else { xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp); } - if (!xres_new) return 0; - if (xres != xres_new) { - printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new); - } return xres_new; } @@ -1285,7 +1279,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi vaddr_t vm; unsigned int offs; unsigned int offs2; - unsigned char store, orig; + unsigned char orig; unsigned char bytes[32]; unsigned char* tmp; @@ -1301,16 +1295,12 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi orig = mga_inb(M_EXTVGA_DATA); mga_outb(M_EXTVGA_DATA, orig | 0x80); - store = mga_readb(vm, 0x1234); tmp = bytes; for (offs = 0x100000; offs < maxSize; offs += 0x200000) *tmp++ = mga_readb(vm, offs); for (offs = 0x100000; offs < maxSize; offs += 0x200000) mga_writeb(vm, offs, 0x02); - if (ACCESS_FBINFO(features.accel.has_cacheflush)) - mga_outb(M_CACHEFLUSH, 0x00); - else - mga_writeb(vm, 0x1234, 0x99); + mga_outb(M_CACHEFLUSH, 0x00); for (offs = 0x100000; offs < maxSize; offs += 0x200000) { if (mga_readb(vm, offs) != 0x02) break; @@ -1321,7 +1311,6 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi tmp = bytes; for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000) mga_writeb(vm, offs2, *tmp++); - mga_writeb(vm, 0x1234, store); mga_outb(M_EXTVGA_INDEX, 0x03); mga_outb(M_EXTVGA_DATA, orig); @@ -1430,6 +1419,20 @@ static struct board { MGA_1164, &vbMystique, "Mystique 220 (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0x02, + 0, 0, + DEVF_VIDEO64BIT | DEVF_CROSS4MB, + 180000, + MGA_1064, + &vbMystique, + "Mystique (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0xFF, + 0, 0, + DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB, + 220000, + MGA_1164, + &vbMystique, + "Mystique 220 (AGP)"}, #endif #ifdef CONFIG_FB_MATROX_G {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index 85a0b255845..a8c47ad2cdb 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -272,10 +272,6 @@ struct matrox_DAC1064_features { u_int8_t xmiscctrl; }; -struct matrox_accel_features { - int has_cacheflush; -}; - /* current hardware status */ struct mavenregs { u_int8_t regs[256]; @@ -440,7 +436,6 @@ struct matrox_fb_info { struct { struct matrox_pll_features pll; struct matrox_DAC1064_features DAC1064; - struct matrox_accel_features accel; } features; struct { spinlock_t DAC; diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c index 429047ac615..d52d7d825c4 100644 --- a/drivers/video/matrox/matroxfb_crtc2.c +++ b/drivers/video/matrox/matroxfb_crtc2.c @@ -576,7 +576,6 @@ static struct fb_ops matroxfb_dh_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static struct fb_var_screeninfo matroxfb_dh_defined = { diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c index f192d995d03..743e7ad26ac 100644 --- a/drivers/video/maxinefb.c +++ b/drivers/video/maxinefb.c @@ -113,7 +113,6 @@ static struct fb_ops maxinefb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; int __init maxinefb_init(void) diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 47516c44a39..1da2f84bdc2 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -251,6 +251,10 @@ static const struct fb_videomode modedb[] = { NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ + NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, }; @@ -676,6 +680,8 @@ void fb_var_to_videomode(struct fb_videomode *mode, mode->sync = var->sync; mode->vmode = var->vmode & FB_VMODE_MASK; mode->flag = FB_MODE_IS_FROM_VAR; + mode->refresh = 0; + if (!var->pixclock) return; @@ -785,39 +791,39 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var, } /** - * fb_find_nearest_mode - find mode closest video mode + * fb_find_nearest_mode - find closest videomode * - * @var: pointer to struct fb_var_screeninfo + * @mode: pointer to struct fb_videomode * @head: pointer to modelist * * Finds best matching videomode, smaller or greater in dimension. * If more than 1 videomode is found, will return the videomode with - * the closest refresh rate + * the closest refresh rate. */ -struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var, +struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode, struct list_head *head) { struct list_head *pos; struct fb_modelist *modelist; - struct fb_videomode *mode, *best = NULL; + struct fb_videomode *cmode, *best = NULL; u32 diff = -1, diff_refresh = -1; list_for_each(pos, head) { u32 d; modelist = list_entry(pos, struct fb_modelist, list); - mode = &modelist->mode; + cmode = &modelist->mode; - d = abs(mode->xres - var->xres) + - abs(mode->yres - var->yres); + d = abs(cmode->xres - mode->xres) + + abs(cmode->yres - mode->yres); if (diff > d) { diff = d; - best = mode; + best = cmode; } else if (diff == d) { - d = abs(mode->refresh - best->refresh); + d = abs(cmode->refresh - mode->refresh); if (diff_refresh > d) { diff_refresh = d; - best = mode; + best = cmode; } } } @@ -942,6 +948,66 @@ void fb_videomode_to_modelist(struct fb_videomode *modedb, int num, } } +struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs, + struct list_head *head) +{ + struct list_head *pos; + struct fb_modelist *modelist; + struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL; + int first = 0; + + if (!head->prev || !head->next || list_empty(head)) + goto finished; + + /* get the first detailed mode and the very first mode */ + list_for_each(pos, head) { + modelist = list_entry(pos, struct fb_modelist, list); + m = &modelist->mode; + + if (!first) { + m1 = m; + first = 1; + } + + if (m->flag & FB_MODE_IS_FIRST) { + md = m; + break; + } + } + + /* first detailed timing is preferred */ + if (specs->misc & FB_MISC_1ST_DETAIL) { + best = md; + goto finished; + } + + /* find best mode based on display width and height */ + if (specs->max_x && specs->max_y) { + struct fb_var_screeninfo var; + + memset(&var, 0, sizeof(struct fb_var_screeninfo)); + var.xres = (specs->max_x * 7200)/254; + var.yres = (specs->max_y * 7200)/254; + m = fb_find_best_mode(&var, head); + if (m) { + best = m; + goto finished; + } + } + + /* use first detailed mode */ + if (md) { + best = md; + goto finished; + } + + /* last resort, use the very first mode */ + best = m1; +finished: + return best; +} +EXPORT_SYMBOL(fb_find_best_display); + EXPORT_SYMBOL(fb_videomode_to_var); EXPORT_SYMBOL(fb_var_to_videomode); EXPORT_SYMBOL(fb_mode_is_equal); diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 5d424a30270..8486e77872d 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -1665,7 +1665,6 @@ static struct fb_ops neofb_ops = { .fb_fillrect = neofb_fillrect, .fb_copyarea = neofb_copyarea, .fb_imageblit = neofb_imageblit, - .fb_cursor = soft_cursor, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h index afee284fc73..4243d7fae97 100644 --- a/drivers/video/nvidia/nv_local.h +++ b/drivers/video/nvidia/nv_local.h @@ -105,7 +105,7 @@ do { \ *a = byte_rev[*a]; \ } while(0) #else -#define reverse_order(l) +#define reverse_order(l) do { } while(0) #endif /* __LITTLE_ENDIAN */ #endif /* __NV_LOCAL_H__ */ diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c index 4fa2cf9a8af..7a03d040b1a 100644 --- a/drivers/video/nvidia/nv_of.c +++ b/drivers/video/nvidia/nv_of.c @@ -27,34 +27,60 @@ #include "nv_local.h" #include "nv_proto.h" -void nvidia_create_i2c_busses(struct nvidia_par *par) {} -void nvidia_delete_i2c_busses(struct nvidia_par *par) {} +#include "../edid.h" -int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) +int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid) { struct nvidia_par *par = info->par; - struct device_node *dp; + struct device_node *parent, *dp; unsigned char *pedid = NULL; - unsigned char *disptype = NULL; static char *propnames[] = { - "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL }; + "DFP,EDID", "LCD,EDID", "EDID", "EDID1", + "EDID,B", "EDID,A", NULL }; int i; - dp = pci_device_to_OF_node(par->pci_dev); - for (; dp != NULL; dp = dp->child) { - disptype = (unsigned char *)get_property(dp, "display-type", NULL); - if (disptype == NULL) - continue; - if (strncmp(disptype, "LCD", 3) != 0) - continue; + parent = pci_device_to_OF_node(par->pci_dev); + if (parent == NULL) + return -1; + if (par->twoHeads) { + char *pname; + int len; + + for (dp = NULL; + (dp = of_get_next_child(parent, dp)) != NULL;) { + pname = (char *)get_property(dp, "name", NULL); + if (!pname) + continue; + len = strlen(pname); + if ((pname[len-1] == 'A' && conn == 1) || + (pname[len-1] == 'B' && conn == 2)) { + for (i = 0; propnames[i] != NULL; ++i) { + pedid = (unsigned char *) + get_property(dp, propnames[i], + NULL); + if (pedid != NULL) + break; + } + of_node_put(dp); + break; + } + } + } + if (pedid == NULL) { for (i = 0; propnames[i] != NULL; ++i) { pedid = (unsigned char *) - get_property(dp, propnames[i], NULL); - if (pedid != NULL) { - *out_edid = pedid; - return 0; - } + get_property(parent, propnames[i], NULL); + if (pedid != NULL) + break; } } - return 1; + if (pedid) { + *out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (*out_edid == NULL) + return -1; + memcpy(*out_edid, pedid, EDID_LENGTH); + printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn); + return 0; + } + return -1; } diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h index cac44fc7f58..f60b1f43227 100644 --- a/drivers/video/nvidia/nv_proto.h +++ b/drivers/video/nvidia/nv_proto.h @@ -31,7 +31,7 @@ int NVShowHideCursor(struct nvidia_par *par, int); void NVLockUnlock(struct nvidia_par *par, int); /* in nvidia-i2c.c */ -#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF) +#ifdef CONFIG_FB_NVIDIA_I2C void nvidia_create_i2c_busses(struct nvidia_par *par); void nvidia_delete_i2c_busses(struct nvidia_par *par); int nvidia_probe_i2c_connector(struct fb_info *info, int conn, @@ -39,10 +39,18 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn, #else #define nvidia_create_i2c_busses(...) #define nvidia_delete_i2c_busses(...) -#define nvidia_probe_i2c_connector(p, c, edid) \ -do { \ - *(edid) = NULL; \ -} while(0) +#define nvidia_probe_i2c_connector(p, c, edid) (-1) +#endif + +#ifdef CONFIG_FB_OF +int nvidia_probe_of_connector(struct fb_info *info, int conn, + u8 ** out_edid); +#else +static inline int nvidia_probe_of_connector(struct fb_info *info, int conn, + u8 ** out_edid) +{ + return -1; +} #endif /* in nv_accel.c */ diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index 11c84178f42..1f06a9f1bd0 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c @@ -190,9 +190,9 @@ static int NVIsConnected(struct nvidia_par *par, int output) present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0; if (present) - printk("nvidiafb: CRTC%i found\n", output); + printk("nvidiafb: CRTC%i analog found\n", output); else - printk("nvidiafb: CRTC%i not found\n", output); + printk("nvidiafb: CRTC%i analog not found\n", output); NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) & 0x0000EFFF); @@ -305,6 +305,9 @@ void NVCommonSetup(struct fb_info *info) int FlatPanel = -1; /* really means the CRTC is slaved */ int Television = 0; + memset(&monitorA, 0, sizeof(struct fb_monspecs)); + memset(&monitorB, 0, sizeof(struct fb_monspecs)); + par->PRAMIN = par->REGS + (0x00710000 / 4); par->PCRTC0 = par->REGS + (0x00600000 / 4); par->PRAMDAC0 = par->REGS + (0x00680000 / 4); @@ -401,7 +404,8 @@ void NVCommonSetup(struct fb_info *info) nvidia_create_i2c_busses(par); if (!par->twoHeads) { par->CRTCnumber = 0; - nvidia_probe_i2c_connector(info, 1, &edidA); + if (nvidia_probe_i2c_connector(info, 1, &edidA)) + nvidia_probe_of_connector(info, 1, &edidA); if (edidA && !fb_parse_edid(edidA, &var)) { printk("nvidiafb: EDID found from BUS1\n"); monA = &monitorA; @@ -488,14 +492,16 @@ void NVCommonSetup(struct fb_info *info) oldhead = NV_RD32(par->PCRTC0, 0x00000860); NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010); - nvidia_probe_i2c_connector(info, 1, &edidA); + if (nvidia_probe_i2c_connector(info, 1, &edidA)) + nvidia_probe_of_connector(info, 1, &edidA); if (edidA && !fb_parse_edid(edidA, &var)) { printk("nvidiafb: EDID found from BUS1\n"); monA = &monitorA; fb_edid_to_monspecs(edidA, monA); } - nvidia_probe_i2c_connector(info, 2, &edidB); + if (nvidia_probe_i2c_connector(info, 2, &edidB)) + nvidia_probe_of_connector(info, 2, &edidB); if (edidB && !fb_parse_edid(edidB, &var)) { printk("nvidiafb: EDID found from BUS2\n"); monB = &monitorB; diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 308defc389a..0b40a2a721c 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -411,6 +411,7 @@ MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl); /* command line data, set in nvidiafb_setup() */ static int flatpanel __devinitdata = -1; /* Autodetect later */ +static int fpdither __devinitdata = -1; static int forceCRTC __devinitdata = -1; static int hwcur __devinitdata = 0; static int noaccel __devinitdata = 0; @@ -627,41 +628,85 @@ static void nvidia_save_vga(struct nvidia_par *par, NVTRACE_LEAVE(); } +#undef DUMP_REG + static void nvidia_write_regs(struct nvidia_par *par) { struct _riva_hw_state *state = &par->ModeReg; int i; NVTRACE_ENTER(); - NVWriteCrtc(par, 0x11, 0x00); - - NVLockUnlock(par, 0); NVLoadStateExt(par, state); NVWriteMiscOut(par, state->misc_output); + for (i = 1; i < NUM_SEQ_REGS; i++) { +#ifdef DUMP_REG + printk(" SEQ[%02x] = %08x\n", i, state->seq[i]); +#endif + NVWriteSeq(par, i, state->seq[i]); + } + + /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */ + NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80); + for (i = 0; i < NUM_CRT_REGS; i++) { switch (i) { case 0x19: case 0x20 ... 0x40: break; default: +#ifdef DUMP_REG + printk("CRTC[%02x] = %08x\n", i, state->crtc[i]); +#endif NVWriteCrtc(par, i, state->crtc[i]); } } - for (i = 0; i < NUM_ATC_REGS; i++) - NVWriteAttr(par, i, state->attr[i]); - - for (i = 0; i < NUM_GRC_REGS; i++) + for (i = 0; i < NUM_GRC_REGS; i++) { +#ifdef DUMP_REG + printk(" GRA[%02x] = %08x\n", i, state->gra[i]); +#endif NVWriteGr(par, i, state->gra[i]); + } + + for (i = 0; i < NUM_ATC_REGS; i++) { +#ifdef DUMP_REG + printk("ATTR[%02x] = %08x\n", i, state->attr[i]); +#endif + NVWriteAttr(par, i, state->attr[i]); + } - for (i = 0; i < NUM_SEQ_REGS; i++) - NVWriteSeq(par, i, state->seq[i]); NVTRACE_LEAVE(); } +static void nvidia_vga_protect(struct nvidia_par *par, int on) +{ + unsigned char tmp; + + if (on) { + /* + * Turn off screen and disable sequencer. + */ + tmp = NVReadSeq(par, 0x01); + + NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */ + NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */ + } else { + /* + * Reenable sequencer, then turn on screen. + */ + + tmp = NVReadSeq(par, 0x01); + + NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */ + NVWriteSeq(par, 0x00, 0x03); /* End Reset */ + } +} + + + static int nvidia_calc_regs(struct fb_info *info) { struct nvidia_par *par = info->par; @@ -868,7 +913,7 @@ static void nvidia_init_vga(struct fb_info *info) for (i = 0; i < 0x10; i++) state->attr[i] = i; state->attr[0x10] = 0x41; - state->attr[0x11] = 0x01; + state->attr[0x11] = 0xff; state->attr[0x12] = 0x0f; state->attr[0x13] = 0x00; state->attr[0x14] = 0x00; @@ -982,16 +1027,24 @@ static int nvidiafb_set_par(struct fb_info *info) NVTRACE_ENTER(); NVLockUnlock(par, 1); - if (!par->FlatPanel || (info->var.bits_per_pixel != 24) || - !par->twoHeads) + if (!par->FlatPanel || !par->twoHeads) par->FPDither = 0; + if (par->FPDither < 0) { + if ((par->Chipset & 0x0ff0) == 0x0110) + par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528) + & 0x00010000); + else + par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1); + printk(KERN_INFO PFX "Flat panel dithering %s\n", + par->FPDither ? "enabled" : "disabled"); + } + info->fix.visual = (info->var.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; nvidia_init_vga(info); nvidia_calc_regs(info); - nvidia_write_regs(par); NVLockUnlock(par, 0); if (par->twoHeads) { @@ -1000,7 +1053,22 @@ static int nvidiafb_set_par(struct fb_info *info) NVLockUnlock(par, 0); } - NVWriteCrtc(par, 0x11, 0x00); + nvidia_vga_protect(par, 1); + + nvidia_write_regs(par); + +#if defined (__BIG_ENDIAN) + /* turn on LFB swapping */ + { + unsigned char tmp; + + VGA_WR08(par->PCIO, 0x3d4, 0x46); + tmp = VGA_RD08(par->PCIO, 0x3d5); + tmp |= (1 << 7); + VGA_WR08(par->PCIO, 0x3d5, tmp); + } +#endif + info->fix.line_length = (info->var.xres_virtual * info->var.bits_per_pixel) >> 3; if (info->var.accel_flags) { @@ -1022,7 +1090,7 @@ static int nvidiafb_set_par(struct fb_info *info) par->cursor_reset = 1; - NVWriteCrtc(par, 0x11, 0xff); + nvidia_vga_protect(par, 0); NVTRACE_LEAVE(); return 0; @@ -1315,22 +1383,10 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) fb_var_to_videomode(&modedb, &nvidiafb_default_var); if (specs->modedb != NULL) { - /* get preferred timing */ - if (specs->misc & FB_MISC_1ST_DETAIL) { - int i; - - for (i = 0; i < specs->modedb_len; i++) { - if (specs->modedb[i].flag & FB_MODE_IS_FIRST) { - modedb = specs->modedb[i]; - break; - } - } - } else { - /* otherwise, get first mode in database */ - modedb = specs->modedb[0]; - } + struct fb_videomode *modedb; - fb_videomode_to_var(&nvidiafb_default_var, &modedb); + modedb = fb_find_best_display(specs, &info->modelist); + fb_videomode_to_var(&nvidiafb_default_var, modedb); nvidiafb_default_var.bits_per_pixel = 8; } else if (par->fpWidth && par->fpHeight) { char buf[16]; @@ -1365,7 +1421,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) info->pixmap.flags = FB_PIXMAP_SYSTEM; if (!hwcur) - info->fbops->fb_cursor = soft_cursor; + info->fbops->fb_cursor = NULL; info->var.accel_flags = (!noaccel); @@ -1490,9 +1546,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); par->FlatPanel = flatpanel; - if (flatpanel == 1) printk(KERN_INFO PFX "flatpanel support enabled\n"); + par->FPDither = fpdither; par->CRTCnumber = forceCRTC; par->FpScale = (!noscale); @@ -1671,6 +1727,8 @@ static int __devinit nvidiafb_setup(char *options) } else if (!strncmp(this_opt, "nomtrr", 6)) { nomtrr = 1; #endif + } else if (!strncmp(this_opt, "fpdither:", 9)) { + fpdither = simple_strtol(this_opt+9, NULL, 0); } else mode_option = this_opt; } @@ -1717,7 +1775,11 @@ module_exit(nvidiafb_exit); module_param(flatpanel, int, 0); MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. " - "(0 or 1=enabled) (default=0)"); + "(0=disabled, 1=enabled, -1=autodetect) (default=-1)"); +module_param(fpdither, int, 0); +MODULE_PARM_DESC(fpdither, + "Enables dithering of flat panel for 6 bits panels. " + "(0=disabled, 1=enabled, -1=autodetect) (default=-1)"); module_param(hwcur, int, 0); MODULE_PARM_DESC(hwcur, "Enables hardware cursor implementation. (0 or 1=enabled) " diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 611922c0b22..2c856838694 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -85,7 +85,6 @@ static struct fb_ops offb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; /* diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index b76a5a9a125..9aaf65fb623 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -48,7 +48,6 @@ static struct fb_ops p9100_ops = { .fb_imageblit = cfb_imageblit, .fb_mmap = p9100_mmap, .fb_ioctl = p9100_ioctl, - .fb_cursor = soft_cursor, }; /* P9100 control registers */ diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index b00887e9851..ca4082ae5a1 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -109,7 +109,6 @@ static struct fb_ops platinumfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; /* diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 42c17efa9fb..0277ce031e5 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -1034,7 +1034,6 @@ static struct fb_ops pm2fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; /* @@ -1121,6 +1120,22 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, default_par->mem_control, default_par->boot_address, default_par->mem_config); + if(default_par->mem_control == 0 && + default_par->boot_address == 0x31 && + default_par->mem_config == 0x259fffff && + pdev->subsystem_vendor == 0x1048 && + pdev->subsystem_device == 0x0a31) { + DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", + pdev->subsystem_vendor, pdev->subsystem_device); + DPRINTK("We have not been initialized by VGA BIOS " + "and are running on an Elsa Winner 2000 Office\n"); + DPRINTK("Initializing card timings manually...\n"); + default_par->mem_control=0; + default_par->boot_address=0x20; + default_par->mem_config=0xe6002021; + default_par->memclock=100000; + } + /* Now work out how big lfb is going to be. */ switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { case PM2F_MEM_BANKS_1: diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index c98f1c8d7dc..f3927b6cda9 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c @@ -128,7 +128,6 @@ static struct fb_ops pmagbafb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index a483b13e117..25148de5fe6 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c @@ -132,7 +132,6 @@ static struct fb_ops pmagbbfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index 31c547fd383..ec4bacf9dd2 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -230,7 +230,6 @@ static struct fb_ops pvr2fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static struct fb_videomode pvr2_modedb[] __initdata = { diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index efd9333b05c..f305a5b77b2 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -418,7 +418,6 @@ static struct fb_ops pxafb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_blank = pxafb_blank, - .fb_cursor = soft_cursor, .fb_mmap = pxafb_mmap, }; diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c index 8416b2e2b50..bfc41f2c902 100644 --- a/drivers/video/q40fb.c +++ b/drivers/video/q40fb.c @@ -84,7 +84,6 @@ static struct fb_ops q40fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static int __init q40fb_probe(struct device *device) diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c index a78b9bd8f89..600318f708f 100644 --- a/drivers/video/radeonfb.c +++ b/drivers/video/radeonfb.c @@ -2218,7 +2218,6 @@ static struct fb_ops radeonfb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, #endif - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index f4437430dc5..3edbd14c5c4 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c @@ -388,7 +388,6 @@ static struct fb_ops s1d13xxxfb_fbops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor }; static int s1d13xxxfb_width_tab[2][4] __devinitdata = { diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 3cef90456a4..855a6778b9e 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -495,7 +495,6 @@ static struct fb_ops s3c2410fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; @@ -885,6 +884,7 @@ static int s3c2410fb_resume(struct device *dev) static struct device_driver s3c2410fb_driver = { .name = "s3c2410-lcd", + .owner = THIS_MODULE, .bus = &platform_bus_type, .probe = s3c2410fb_probe, .suspend = s3c2410fb_suspend, diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 3d35b28aaac..a5184575cfa 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -853,7 +853,6 @@ static struct fb_ops sa1100fb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_blank = sa1100fb_blank, - .fb_cursor = soft_cursor, .fb_mmap = sa1100fb_mmap, }; diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h index ea17f7e0482..58cfdfb4183 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/savage/savagefb.h @@ -169,6 +169,7 @@ struct savagefb_par { struct savagefb_i2c_chan chan; unsigned char *edid; u32 pseudo_palette[16]; + int paletteEnabled; int pm_state; int display_type; int dvi; @@ -244,105 +245,150 @@ struct savagefb_par { /* IO functions */ +static inline u8 savage_in8(u32 addr, struct savagefb_par *par) +{ + return readb(par->mmio.vbase + addr); +} + +static inline u16 savage_in16(u32 addr, struct savagefb_par *par) +{ + return readw(par->mmio.vbase + addr); +} + +static inline u32 savage_in32(u32 addr, struct savagefb_par *par) +{ + return readl(par->mmio.vbase + addr); +} + +static inline void savage_out8(u32 addr, u8 val, struct savagefb_par *par) +{ + writeb(val, par->mmio.vbase + addr); +} + +static inline void savage_out16(u32 addr, u16 val, struct savagefb_par *par) +{ + writew(val, par->mmio.vbase + addr); +} + +static inline void savage_out32(u32 addr, u32 val, struct savagefb_par *par) +{ + writel(val, par->mmio.vbase + addr); +} + +static inline u8 vga_in8(int addr, struct savagefb_par *par) +{ + return savage_in8(0x8000 + addr, par); +} + +static inline u16 vga_in16(int addr, struct savagefb_par *par) +{ + return savage_in16(0x8000 + addr, par); +} + +static inline u8 vga_in32(int addr, struct savagefb_par *par) +{ + return savage_in32(0x8000 + addr, par); +} + +static inline void vga_out8(int addr, u8 val, struct savagefb_par *par) +{ + savage_out8(0x8000 + addr, val, par); +} + +static inline void vga_out16(int addr, u16 val, struct savagefb_par *par) +{ + savage_out16(0x8000 + addr, val, par); +} + +static inline void vga_out32(int addr, u32 val, struct savagefb_par *par) +{ + savage_out32(0x8000 + addr, val, par); +} -#define vga_in8(addr) (inb (addr)) -#define vga_in16(addr) (inw (addr)) -#define vga_in32(addr) (inl (addr)) +static inline u8 VGArCR (u8 index, struct savagefb_par *par) +{ + vga_out8(0x3d4, index, par); + return vga_in8(0x3d5, par); +} + +static inline u8 VGArGR (u8 index, struct savagefb_par *par) +{ + vga_out8(0x3ce, index, par); + return vga_in8(0x3cf, par); +} + +static inline u8 VGArSEQ (u8 index, struct savagefb_par *par) +{ + vga_out8(0x3c4, index, par); + return vga_in8(0x3c5, par); +} -#define vga_out8(addr,val) (outb ((val), (addr))) -#define vga_out16(addr,val) (outw ((val), (addr))) -#define vga_out32(addr,val) (outl ((val), (addr))) +static inline void VGAwCR(u8 index, u8 val, struct savagefb_par *par) +{ + vga_out8(0x3d4, index, par); + vga_out8(0x3d5, val, par); +} -#define savage_in16(addr) readw(par->mmio.vbase + (addr)) -#define savage_in32(addr) readl(par->mmio.vbase + (addr)) +static inline void VGAwGR(u8 index, u8 val, struct savagefb_par *par) +{ + vga_out8(0x3ce, index, par); + vga_out8(0x3cf, val, par); +} -#define savage_out16(addr,val) writew((val), par->mmio.vbase + (addr)) -#define savage_out32(addr,val) writel((val), par->mmio.vbase + (addr)) +static inline void VGAwSEQ(u8 index, u8 val, struct savagefb_par *par) +{ + vga_out8(0x3c4, index, par); + vga_out8 (0x3c5, val, par); +} -static inline u8 VGArCR (u8 index) +static inline void VGAenablePalette(struct savagefb_par *par) { - outb (index, 0x3d4); - return inb (0x3d5); + u8 tmp; + + tmp = vga_in8(0x3da, par); + vga_out8(0x3c0, 0x00, par); + par->paletteEnabled = 1; } -static inline u8 VGArGR (u8 index) +static inline void VGAdisablePalette(struct savagefb_par *par) { - outb (index, 0x3ce); - return inb (0x3cf); + u8 tmp; + + tmp = vga_in8(0x3da, par); + vga_out8(0x3c0, 0x20, par); + par->paletteEnabled = 0; } -static inline u8 VGArSEQ (u8 index) +static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par) { - outb (index, 0x3c4); - return inb (0x3c5); + u8 tmp; + + if (par->paletteEnabled) + index &= ~0x20; + else + index |= 0x20; + + tmp = vga_in8(0x3da, par); + vga_out8(0x3c0, index, par); + vga_out8 (0x3c0, value, par); } -#define VGAwCR(index, val) \ -do { \ - vga_out8 (0x3d4, index); \ - vga_out8 (0x3d5, val); \ -} while (0) - -#define VGAwGR(index, val) \ -do { \ - vga_out8 (0x3ce, index); \ - vga_out8 (0x3cf, val); \ -} while (0) - -#define VGAwSEQ(index, val) \ -do { \ - vga_out8 (0x3c4, index); \ - vga_out8 (0x3c5, val); \ -} while (0) - -#define VGAenablePalette() \ -do { \ - u8 tmp; \ - \ - tmp = vga_in8 (0x3da); \ - vga_out8 (0x3c0, 0x00); \ - paletteEnabled = 1; \ -} while (0) - -#define VGAdisablePalette() \ -do { \ - u8 tmp; \ - \ - tmp = vga_in8 (0x3da); \ - vga_out8 (0x3c0, 0x20); \ - paletteEnabled = 0; \ -} while (0) - -#define VGAwATTR(index, value) \ -do { \ - u8 tmp; \ - \ - if (paletteEnabled) \ - index &= ~0x20; \ - else \ - index |= 0x20; \ - \ - tmp = vga_in8 (0x3da); \ - vga_out8 (0x3c0, index); \ - vga_out8 (0x3c0, value); \ -} while (0) - -#define VGAwMISC(value) \ -do { \ - vga_out8 (0x3c2, value); \ -} while (0) +static inline void VGAwMISC(u8 value, struct savagefb_par *par) +{ + vga_out8(0x3c2, value, par); +} #ifndef CONFIG_FB_SAVAGE_ACCEL #define savagefb_set_clip(x) #endif -#define VerticalRetraceWait() \ -{ \ - vga_out8 (0x3d4, 0x17); \ - if (vga_in8 (0x3d5) & 0x80) { \ - while ((vga_in8(0x3da) & 0x08) == 0x08) ; \ - while ((vga_in8(0x3da) & 0x08) == 0x00) ; \ - } \ +static inline void VerticalRetraceWait(struct savagefb_par *par) +{ + vga_out8(0x3d4, 0x17, par); + if (vga_in8(0x3d5, par) & 0x80) { + while ((vga_in8(0x3da, par) & 0x08) == 0x08); + while ((vga_in8(0x3da, par) & 0x08) == 0x00); + } } extern int savagefb_probe_i2c_connector(struct fb_info *info, diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 7c285455c92..09e2f284190 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -74,7 +74,6 @@ static char *mode_option __initdata = NULL; -static int paletteEnabled = 0; #ifdef MODULE @@ -90,9 +89,9 @@ MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips"); static void vgaHWSeqReset (struct savagefb_par *par, int start) { if (start) - VGAwSEQ (0x00, 0x01); /* Synchronous Reset */ + VGAwSEQ (0x00, 0x01, par); /* Synchronous Reset */ else - VGAwSEQ (0x00, 0x03); /* End Reset */ + VGAwSEQ (0x00, 0x03, par); /* End Reset */ } static void vgaHWProtect (struct savagefb_par *par, int on) @@ -103,23 +102,23 @@ static void vgaHWProtect (struct savagefb_par *par, int on) /* * Turn off screen and disable sequencer. */ - tmp = VGArSEQ (0x01); + tmp = VGArSEQ (0x01, par); vgaHWSeqReset (par, 1); /* start synchronous reset */ - VGAwSEQ (0x01, tmp | 0x20); /* disable the display */ + VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */ - VGAenablePalette(); + VGAenablePalette(par); } else { /* * Reenable sequencer, then turn on screen. */ - tmp = VGArSEQ (0x01); + tmp = VGArSEQ (0x01, par); - VGAwSEQ (0x01, tmp & ~0x20); /* reenable display */ + VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */ vgaHWSeqReset (par, 0); /* clear synchronous reset */ - VGAdisablePalette(); + VGAdisablePalette(par); } } @@ -127,27 +126,27 @@ static void vgaHWRestore (struct savagefb_par *par) { int i; - VGAwMISC (par->MiscOutReg); + VGAwMISC (par->MiscOutReg, par); for (i = 1; i < 5; i++) - VGAwSEQ (i, par->Sequencer[i]); + VGAwSEQ (i, par->Sequencer[i], par); /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */ - VGAwCR (17, par->CRTC[17] & ~0x80); + VGAwCR (17, par->CRTC[17] & ~0x80, par); for (i = 0; i < 25; i++) - VGAwCR (i, par->CRTC[i]); + VGAwCR (i, par->CRTC[i], par); for (i = 0; i < 9; i++) - VGAwGR (i, par->Graphics[i]); + VGAwGR (i, par->Graphics[i], par); - VGAenablePalette(); + VGAenablePalette(par); for (i = 0; i < 21; i++) - VGAwATTR (i, par->Attribute[i]); + VGAwATTR (i, par->Attribute[i], par); - VGAdisablePalette(); + VGAdisablePalette(par); } static void vgaHWInit (struct fb_var_screeninfo *var, @@ -267,7 +266,7 @@ savage3D_waitfifo(struct savagefb_par *par, int space) { int slots = MAXFIFO - space; - while ((savage_in32(0x48C00) & 0x0000ffff) > slots); + while ((savage_in32(0x48C00, par) & 0x0000ffff) > slots); } static void @@ -275,7 +274,7 @@ savage4_waitfifo(struct savagefb_par *par, int space) { int slots = MAXFIFO - space; - while ((savage_in32(0x48C60) & 0x001fffff) > slots); + while ((savage_in32(0x48C60, par) & 0x001fffff) > slots); } static void @@ -283,26 +282,26 @@ savage2000_waitfifo(struct savagefb_par *par, int space) { int slots = MAXFIFO - space; - while ((savage_in32(0x48C60) & 0x0000ffff) > slots); + while ((savage_in32(0x48C60, par) & 0x0000ffff) > slots); } /* Wait for idle accelerator */ static void savage3D_waitidle(struct savagefb_par *par) { - while ((savage_in32(0x48C00) & 0x0008ffff) != 0x80000); + while ((savage_in32(0x48C00, par) & 0x0008ffff) != 0x80000); } static void savage4_waitidle(struct savagefb_par *par) { - while ((savage_in32(0x48C60) & 0x00a00000) != 0x00a00000); + while ((savage_in32(0x48C60, par) & 0x00a00000) != 0x00a00000); } static void savage2000_waitidle(struct savagefb_par *par) { - while ((savage_in32(0x48C60) & 0x009fffff)); + while ((savage_in32(0x48C60, par) & 0x009fffff)); } @@ -319,59 +318,64 @@ SavageSetup2DEngine (struct savagefb_par *par) case S3_SAVAGE3D: case S3_SAVAGE_MX: /* Disable BCI */ - savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0); + savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par); /* Setup BCI command overflow buffer */ - savage_out32(0x48C14, (par->cob_offset >> 11) | (par->cob_index << 29)); + savage_out32(0x48C14, + (par->cob_offset >> 11) | (par->cob_index << 29), + par); /* Program shadow status update. */ - savage_out32(0x48C10, 0x78207220); - savage_out32(0x48C0C, 0); + savage_out32(0x48C10, 0x78207220, par); + savage_out32(0x48C0C, 0, par); /* Enable BCI and command overflow buffer */ - savage_out32(0x48C18, savage_in32(0x48C18) | 0x0C); + savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par); break; case S3_SAVAGE4: case S3_PROSAVAGE: case S3_SUPERSAVAGE: /* Disable BCI */ - savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0); + savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par); /* Program shadow status update */ - savage_out32(0x48C10, 0x00700040); - savage_out32(0x48C0C, 0); + savage_out32(0x48C10, 0x00700040, par); + savage_out32(0x48C0C, 0, par); /* Enable BCI without the COB */ - savage_out32(0x48C18, savage_in32(0x48C18) | 0x08); + savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x08, par); break; case S3_SAVAGE2000: /* Disable BCI */ - savage_out32(0x48C18, 0); + savage_out32(0x48C18, 0, par); /* Setup BCI command overflow buffer */ - savage_out32(0x48C18, (par->cob_offset >> 7) | (par->cob_index)); + savage_out32(0x48C18, + (par->cob_offset >> 7) | (par->cob_index), + par); /* Disable shadow status update */ - savage_out32(0x48A30, 0); + savage_out32(0x48A30, 0, par); /* Enable BCI and command overflow buffer */ - savage_out32(0x48C18, savage_in32(0x48C18) | 0x00280000 ); + savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x00280000, + par); break; default: break; } /* Turn on 16-bit register access. */ - vga_out8(0x3d4, 0x31); - vga_out8(0x3d5, 0x0c); + vga_out8(0x3d4, 0x31, par); + vga_out8(0x3d5, 0x0c, par); /* Set stride to use GBD. */ - vga_out8 (0x3d4, 0x50); - vga_out8 (0x3d5, vga_in8 (0x3d5 ) | 0xC1); + vga_out8 (0x3d4, 0x50, par); + vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par); /* Enable 2D engine. */ - vga_out8 (0x3d4, 0x40 ); - vga_out8 (0x3d5, 0x01 ); + vga_out8 (0x3d4, 0x40, par); + vga_out8 (0x3d5, 0x01, par); - savage_out32 (MONO_PAT_0, ~0); - savage_out32 (MONO_PAT_1, ~0); + savage_out32 (MONO_PAT_0, ~0, par); + savage_out32 (MONO_PAT_1, ~0, par); /* Setup plane masks */ - savage_out32 (0x8128, ~0 ); /* enable all write planes */ - savage_out32 (0x812C, ~0 ); /* enable all read planes */ - savage_out16 (0x8134, 0x27 ); - savage_out16 (0x8136, 0x07 ); + savage_out32 (0x8128, ~0, par); /* enable all write planes */ + savage_out32 (0x812C, ~0, par); /* enable all read planes */ + savage_out16 (0x8134, 0x27, par); + savage_out16 (0x8136, 0x07, par); /* Now set the GBD */ par->bci_ptr = 0; @@ -489,8 +493,8 @@ static void SavagePrintRegs(void) for( i = 0; i < 0x70; i++ ) { if( !(i % 16) ) printk(KERN_DEBUG "\nSR%xx ", i >> 4 ); - vga_out8( 0x3c4, i ); - printk(KERN_DEBUG " %02x", vga_in8(0x3c5) ); + vga_out8( 0x3c4, i, par); + printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) ); } printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC " @@ -499,8 +503,8 @@ static void SavagePrintRegs(void) for( i = 0; i < 0xB7; i++ ) { if( !(i % 16) ) printk(KERN_DEBUG "\nCR%xx ", i >> 4 ); - vga_out8( vgaCRIndex, i ); - printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg) ); + vga_out8( vgaCRIndex, i, par); + printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) ); } printk(KERN_DEBUG "\n\n"); @@ -513,152 +517,152 @@ static void savage_get_default_par(struct savagefb_par *par) { unsigned char cr3a, cr53, cr66; - vga_out16 (0x3d4, 0x4838); - vga_out16 (0x3d4, 0xa039); - vga_out16 (0x3c4, 0x0608); - - vga_out8 (0x3d4, 0x66); - cr66 = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr66 | 0x80); - vga_out8 (0x3d4, 0x3a); - cr3a = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr3a | 0x80); - vga_out8 (0x3d4, 0x53); - cr53 = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr53 & 0x7f); - - vga_out8 (0x3d4, 0x66); - vga_out8 (0x3d5, cr66); - vga_out8 (0x3d4, 0x3a); - vga_out8 (0x3d5, cr3a); - - vga_out8 (0x3d4, 0x66); - vga_out8 (0x3d5, cr66); - vga_out8 (0x3d4, 0x3a); - vga_out8 (0x3d5, cr3a); + vga_out16 (0x3d4, 0x4838, par); + vga_out16 (0x3d4, 0xa039, par); + vga_out16 (0x3c4, 0x0608, par); + + vga_out8 (0x3d4, 0x66, par); + cr66 = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr66 | 0x80, par); + vga_out8 (0x3d4, 0x3a, par); + cr3a = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr3a | 0x80, par); + vga_out8 (0x3d4, 0x53, par); + cr53 = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr53 & 0x7f, par); + + vga_out8 (0x3d4, 0x66, par); + vga_out8 (0x3d5, cr66, par); + vga_out8 (0x3d4, 0x3a, par); + vga_out8 (0x3d5, cr3a, par); + + vga_out8 (0x3d4, 0x66, par); + vga_out8 (0x3d5, cr66, par); + vga_out8 (0x3d4, 0x3a, par); + vga_out8 (0x3d5, cr3a, par); /* unlock extended seq regs */ - vga_out8 (0x3c4, 0x08); - par->SR08 = vga_in8 (0x3c5); - vga_out8 (0x3c5, 0x06); + vga_out8 (0x3c4, 0x08, par); + par->SR08 = vga_in8 (0x3c5, par); + vga_out8 (0x3c5, 0x06, par); /* now save all the extended regs we need */ - vga_out8 (0x3d4, 0x31); - par->CR31 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x32); - par->CR32 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x34); - par->CR34 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x36); - par->CR36 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x3a); - par->CR3A = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x40); - par->CR40 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x42); - par->CR42 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x45); - par->CR45 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x50); - par->CR50 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x51); - par->CR51 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x53); - par->CR53 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x58); - par->CR58 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x60); - par->CR60 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x66); - par->CR66 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x67); - par->CR67 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x68); - par->CR68 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x69); - par->CR69 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x6f); - par->CR6F = vga_in8 (0x3d5); - - vga_out8 (0x3d4, 0x33); - par->CR33 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x86); - par->CR86 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x88); - par->CR88 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x90); - par->CR90 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x91); - par->CR91 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0xb0); - par->CRB0 = vga_in8 (0x3d5) | 0x80; + vga_out8 (0x3d4, 0x31, par); + par->CR31 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x32, par); + par->CR32 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x34, par); + par->CR34 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x36, par); + par->CR36 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x3a, par); + par->CR3A = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x40, par); + par->CR40 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x42, par); + par->CR42 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x45, par); + par->CR45 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x50, par); + par->CR50 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x51, par); + par->CR51 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x53, par); + par->CR53 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x58, par); + par->CR58 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x60, par); + par->CR60 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x66, par); + par->CR66 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x67, par); + par->CR67 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x68, par); + par->CR68 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x69, par); + par->CR69 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x6f, par); + par->CR6F = vga_in8 (0x3d5, par); + + vga_out8 (0x3d4, 0x33, par); + par->CR33 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x86, par); + par->CR86 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x88, par); + par->CR88 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x90, par); + par->CR90 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x91, par); + par->CR91 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0xb0, par); + par->CRB0 = vga_in8 (0x3d5, par) | 0x80; /* extended mode timing regs */ - vga_out8 (0x3d4, 0x3b); - par->CR3B = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x3c); - par->CR3C = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x43); - par->CR43 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x5d); - par->CR5D = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x5e); - par->CR5E = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x65); - par->CR65 = vga_in8 (0x3d5); + vga_out8 (0x3d4, 0x3b, par); + par->CR3B = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x3c, par); + par->CR3C = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x43, par); + par->CR43 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x5d, par); + par->CR5D = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x5e, par); + par->CR5E = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x65, par); + par->CR65 = vga_in8 (0x3d5, par); /* save seq extended regs for DCLK PLL programming */ - vga_out8 (0x3c4, 0x0e); - par->SR0E = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x0f); - par->SR0F = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x10); - par->SR10 = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x11); - par->SR11 = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x12); - par->SR12 = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x13); - par->SR13 = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x29); - par->SR29 = vga_in8 (0x3c5); - - vga_out8 (0x3c4, 0x15); - par->SR15 = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x30); - par->SR30 = vga_in8 (0x3c5); - vga_out8 (0x3c4, 0x18); - par->SR18 = vga_in8 (0x3c5); + vga_out8 (0x3c4, 0x0e, par); + par->SR0E = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x0f, par); + par->SR0F = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x10, par); + par->SR10 = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x11, par); + par->SR11 = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x12, par); + par->SR12 = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x13, par); + par->SR13 = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x29, par); + par->SR29 = vga_in8 (0x3c5, par); + + vga_out8 (0x3c4, 0x15, par); + par->SR15 = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x30, par); + par->SR30 = vga_in8 (0x3c5, par); + vga_out8 (0x3c4, 0x18, par); + par->SR18 = vga_in8 (0x3c5, par); /* Save flat panel expansion regsters. */ if (par->chip == S3_SAVAGE_MX) { int i; for (i = 0; i < 8; i++) { - vga_out8 (0x3c4, 0x54+i); - par->SR54[i] = vga_in8 (0x3c5); + vga_out8 (0x3c4, 0x54+i, par); + par->SR54[i] = vga_in8 (0x3c5, par); } } - vga_out8 (0x3d4, 0x66); - cr66 = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr66 | 0x80); - vga_out8 (0x3d4, 0x3a); - cr3a = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr3a | 0x80); + vga_out8 (0x3d4, 0x66, par); + cr66 = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr66 | 0x80, par); + vga_out8 (0x3d4, 0x3a, par); + cr3a = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr3a | 0x80, par); /* now save MIU regs */ if (par->chip != S3_SAVAGE_MX) { - par->MMPR0 = savage_in32(FIFO_CONTROL_REG); - par->MMPR1 = savage_in32(MIU_CONTROL_REG); - par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG); - par->MMPR3 = savage_in32(MISC_TIMEOUT_REG); + par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par); + par->MMPR1 = savage_in32(MIU_CONTROL_REG, par); + par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par); + par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par); } - vga_out8 (0x3d4, 0x3a); - vga_out8 (0x3d5, cr3a); - vga_out8 (0x3d4, 0x66); - vga_out8 (0x3d5, cr66); + vga_out8 (0x3d4, 0x3a, par); + vga_out8 (0x3d5, cr3a, par); + vga_out8 (0x3d4, 0x66, par); + vga_out8 (0x3d5, cr66, par); } static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) @@ -868,8 +872,8 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, * match. Fall back to traditional register-crunching. */ - vga_out8 (0x3d4, 0x3a); - tmp = vga_in8 (0x3d5); + vga_out8 (0x3d4, 0x3a, par); + tmp = vga_in8 (0x3d5, par); if (1 /*FIXME:psav->pci_burst*/) par->CR3A = (tmp & 0x7f) | 0x15; else @@ -879,16 +883,16 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, par->CR31 = 0x8c; par->CR66 = 0x89; - vga_out8 (0x3d4, 0x58); - par->CR58 = vga_in8 (0x3d5) & 0x80; + vga_out8 (0x3d4, 0x58, par); + par->CR58 = vga_in8 (0x3d5, par) & 0x80; par->CR58 |= 0x13; par->SR15 = 0x03 | 0x80; par->SR18 = 0x00; par->CR43 = par->CR45 = par->CR65 = 0x00; - vga_out8 (0x3d4, 0x40); - par->CR40 = vga_in8 (0x3d5) & ~0x01; + vga_out8 (0x3d4, 0x40, par); + par->CR40 = vga_in8 (0x3d5, par) & ~0x01; par->MMPR0 = 0x010400; par->MMPR1 = 0x00; @@ -992,19 +996,19 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, par->CR67 |= 1; - vga_out8(0x3d4, 0x36); - par->CR36 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x68); - par->CR68 = vga_in8 (0x3d5); + vga_out8(0x3d4, 0x36, par); + par->CR36 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x68, par); + par->CR68 = vga_in8 (0x3d5, par); par->CR69 = 0; - vga_out8 (0x3d4, 0x6f); - par->CR6F = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x86); - par->CR86 = vga_in8 (0x3d5); - vga_out8 (0x3d4, 0x88); - par->CR88 = vga_in8 (0x3d5) | 0x08; - vga_out8 (0x3d4, 0xb0); - par->CRB0 = vga_in8 (0x3d5) | 0x80; + vga_out8 (0x3d4, 0x6f, par); + par->CR6F = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x86, par); + par->CR86 = vga_in8 (0x3d5, par); + vga_out8 (0x3d4, 0x88, par); + par->CR88 = vga_in8 (0x3d5, par) | 0x08; + vga_out8 (0x3d4, 0xb0, par); + par->CRB0 = vga_in8 (0x3d5, par) | 0x80; return 0; } @@ -1033,11 +1037,11 @@ static int savagefb_setcolreg(unsigned regno, switch (info->var.bits_per_pixel) { case 8: - vga_out8 (0x3c8, regno); + vga_out8 (0x3c8, regno, par); - vga_out8 (0x3c9, red >> 10); - vga_out8 (0x3c9, green >> 10); - vga_out8 (0x3c9, blue >> 10); + vga_out8 (0x3c9, red >> 10, par); + vga_out8 (0x3c9, green >> 10, par); + vga_out8 (0x3c9, blue >> 10, par); break; case 16: @@ -1079,11 +1083,11 @@ static void savagefb_set_par_int (struct savagefb_par *par) par->SavageWaitIdle (par); - vga_out8 (0x3c2, 0x23); + vga_out8 (0x3c2, 0x23, par); - vga_out16 (0x3d4, 0x4838); - vga_out16 (0x3d4, 0xa539); - vga_out16 (0x3c4, 0x0608); + vga_out16 (0x3d4, 0x4838, par); + vga_out16 (0x3d4, 0xa539, par); + vga_out16 (0x3c4, 0x0608, par); vgaHWProtect (par, 1); @@ -1094,197 +1098,197 @@ static void savagefb_set_par_int (struct savagefb_par *par) * switch to mode 3 here seems to eliminate the issue. */ - VerticalRetraceWait(); - vga_out8 (0x3d4, 0x67); - cr67 = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c); /* no STREAMS yet */ + VerticalRetraceWait(par); + vga_out8 (0x3d4, 0x67, par); + cr67 = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */ - vga_out8 (0x3d4, 0x23); - vga_out8 (0x3d5, 0x00); - vga_out8 (0x3d4, 0x26); - vga_out8 (0x3d5, 0x00); + vga_out8 (0x3d4, 0x23, par); + vga_out8 (0x3d5, 0x00, par); + vga_out8 (0x3d4, 0x26, par); + vga_out8 (0x3d5, 0x00, par); /* restore extended regs */ - vga_out8 (0x3d4, 0x66); - vga_out8 (0x3d5, par->CR66); - vga_out8 (0x3d4, 0x3a); - vga_out8 (0x3d5, par->CR3A); - vga_out8 (0x3d4, 0x31); - vga_out8 (0x3d5, par->CR31); - vga_out8 (0x3d4, 0x32); - vga_out8 (0x3d5, par->CR32); - vga_out8 (0x3d4, 0x58); - vga_out8 (0x3d5, par->CR58); - vga_out8 (0x3d4, 0x53); - vga_out8 (0x3d5, par->CR53 & 0x7f); - - vga_out16 (0x3c4, 0x0608); + vga_out8 (0x3d4, 0x66, par); + vga_out8 (0x3d5, par->CR66, par); + vga_out8 (0x3d4, 0x3a, par); + vga_out8 (0x3d5, par->CR3A, par); + vga_out8 (0x3d4, 0x31, par); + vga_out8 (0x3d5, par->CR31, par); + vga_out8 (0x3d4, 0x32, par); + vga_out8 (0x3d5, par->CR32, par); + vga_out8 (0x3d4, 0x58, par); + vga_out8 (0x3d5, par->CR58, par); + vga_out8 (0x3d4, 0x53, par); + vga_out8 (0x3d5, par->CR53 & 0x7f, par); + + vga_out16 (0x3c4, 0x0608, par); /* Restore DCLK registers. */ - vga_out8 (0x3c4, 0x0e); - vga_out8 (0x3c5, par->SR0E); - vga_out8 (0x3c4, 0x0f); - vga_out8 (0x3c5, par->SR0F); - vga_out8 (0x3c4, 0x29); - vga_out8 (0x3c5, par->SR29); - vga_out8 (0x3c4, 0x15); - vga_out8 (0x3c5, par->SR15); + vga_out8 (0x3c4, 0x0e, par); + vga_out8 (0x3c5, par->SR0E, par); + vga_out8 (0x3c4, 0x0f, par); + vga_out8 (0x3c5, par->SR0F, par); + vga_out8 (0x3c4, 0x29, par); + vga_out8 (0x3c5, par->SR29, par); + vga_out8 (0x3c4, 0x15, par); + vga_out8 (0x3c5, par->SR15, par); /* Restore flat panel expansion regsters. */ if( par->chip == S3_SAVAGE_MX ) { int i; for( i = 0; i < 8; i++ ) { - vga_out8 (0x3c4, 0x54+i); - vga_out8 (0x3c5, par->SR54[i]); + vga_out8 (0x3c4, 0x54+i, par); + vga_out8 (0x3c5, par->SR54[i], par); } } vgaHWRestore (par); /* extended mode timing registers */ - vga_out8 (0x3d4, 0x53); - vga_out8 (0x3d5, par->CR53); - vga_out8 (0x3d4, 0x5d); - vga_out8 (0x3d5, par->CR5D); - vga_out8 (0x3d4, 0x5e); - vga_out8 (0x3d5, par->CR5E); - vga_out8 (0x3d4, 0x3b); - vga_out8 (0x3d5, par->CR3B); - vga_out8 (0x3d4, 0x3c); - vga_out8 (0x3d5, par->CR3C); - vga_out8 (0x3d4, 0x43); - vga_out8 (0x3d5, par->CR43); - vga_out8 (0x3d4, 0x65); - vga_out8 (0x3d5, par->CR65); + vga_out8 (0x3d4, 0x53, par); + vga_out8 (0x3d5, par->CR53, par); + vga_out8 (0x3d4, 0x5d, par); + vga_out8 (0x3d5, par->CR5D, par); + vga_out8 (0x3d4, 0x5e, par); + vga_out8 (0x3d5, par->CR5E, par); + vga_out8 (0x3d4, 0x3b, par); + vga_out8 (0x3d5, par->CR3B, par); + vga_out8 (0x3d4, 0x3c, par); + vga_out8 (0x3d5, par->CR3C, par); + vga_out8 (0x3d4, 0x43, par); + vga_out8 (0x3d5, par->CR43, par); + vga_out8 (0x3d4, 0x65, par); + vga_out8 (0x3d5, par->CR65, par); /* restore the desired video mode with cr67 */ - vga_out8 (0x3d4, 0x67); + vga_out8 (0x3d4, 0x67, par); /* following part not present in X11 driver */ - cr67 = vga_in8 (0x3d5) & 0xf; - vga_out8 (0x3d5, 0x50 | cr67); + cr67 = vga_in8 (0x3d5, par) & 0xf; + vga_out8 (0x3d5, 0x50 | cr67, par); udelay (10000); - vga_out8 (0x3d4, 0x67); + vga_out8 (0x3d4, 0x67, par); /* end of part */ - vga_out8 (0x3d5, par->CR67 & ~0x0c); + vga_out8 (0x3d5, par->CR67 & ~0x0c, par); /* other mode timing and extended regs */ - vga_out8 (0x3d4, 0x34); - vga_out8 (0x3d5, par->CR34); - vga_out8 (0x3d4, 0x40); - vga_out8 (0x3d5, par->CR40); - vga_out8 (0x3d4, 0x42); - vga_out8 (0x3d5, par->CR42); - vga_out8 (0x3d4, 0x45); - vga_out8 (0x3d5, par->CR45); - vga_out8 (0x3d4, 0x50); - vga_out8 (0x3d5, par->CR50); - vga_out8 (0x3d4, 0x51); - vga_out8 (0x3d5, par->CR51); + vga_out8 (0x3d4, 0x34, par); + vga_out8 (0x3d5, par->CR34, par); + vga_out8 (0x3d4, 0x40, par); + vga_out8 (0x3d5, par->CR40, par); + vga_out8 (0x3d4, 0x42, par); + vga_out8 (0x3d5, par->CR42, par); + vga_out8 (0x3d4, 0x45, par); + vga_out8 (0x3d5, par->CR45, par); + vga_out8 (0x3d4, 0x50, par); + vga_out8 (0x3d5, par->CR50, par); + vga_out8 (0x3d4, 0x51, par); + vga_out8 (0x3d5, par->CR51, par); /* memory timings */ - vga_out8 (0x3d4, 0x36); - vga_out8 (0x3d5, par->CR36); - vga_out8 (0x3d4, 0x60); - vga_out8 (0x3d5, par->CR60); - vga_out8 (0x3d4, 0x68); - vga_out8 (0x3d5, par->CR68); - vga_out8 (0x3d4, 0x69); - vga_out8 (0x3d5, par->CR69); - vga_out8 (0x3d4, 0x6f); - vga_out8 (0x3d5, par->CR6F); - - vga_out8 (0x3d4, 0x33); - vga_out8 (0x3d5, par->CR33); - vga_out8 (0x3d4, 0x86); - vga_out8 (0x3d5, par->CR86); - vga_out8 (0x3d4, 0x88); - vga_out8 (0x3d5, par->CR88); - vga_out8 (0x3d4, 0x90); - vga_out8 (0x3d5, par->CR90); - vga_out8 (0x3d4, 0x91); - vga_out8 (0x3d5, par->CR91); + vga_out8 (0x3d4, 0x36, par); + vga_out8 (0x3d5, par->CR36, par); + vga_out8 (0x3d4, 0x60, par); + vga_out8 (0x3d5, par->CR60, par); + vga_out8 (0x3d4, 0x68, par); + vga_out8 (0x3d5, par->CR68, par); + vga_out8 (0x3d4, 0x69, par); + vga_out8 (0x3d5, par->CR69, par); + vga_out8 (0x3d4, 0x6f, par); + vga_out8 (0x3d5, par->CR6F, par); + + vga_out8 (0x3d4, 0x33, par); + vga_out8 (0x3d5, par->CR33, par); + vga_out8 (0x3d4, 0x86, par); + vga_out8 (0x3d5, par->CR86, par); + vga_out8 (0x3d4, 0x88, par); + vga_out8 (0x3d5, par->CR88, par); + vga_out8 (0x3d4, 0x90, par); + vga_out8 (0x3d5, par->CR90, par); + vga_out8 (0x3d4, 0x91, par); + vga_out8 (0x3d5, par->CR91, par); if (par->chip == S3_SAVAGE4) { - vga_out8 (0x3d4, 0xb0); - vga_out8 (0x3d5, par->CRB0); + vga_out8 (0x3d4, 0xb0, par); + vga_out8 (0x3d5, par->CRB0, par); } - vga_out8 (0x3d4, 0x32); - vga_out8 (0x3d5, par->CR32); + vga_out8 (0x3d4, 0x32, par); + vga_out8 (0x3d5, par->CR32, par); /* unlock extended seq regs */ - vga_out8 (0x3c4, 0x08); - vga_out8 (0x3c5, 0x06); + vga_out8 (0x3c4, 0x08, par); + vga_out8 (0x3c5, 0x06, par); /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates * that we should leave the default SR10 and SR11 values there. */ if (par->SR10 != 255) { - vga_out8 (0x3c4, 0x10); - vga_out8 (0x3c5, par->SR10); - vga_out8 (0x3c4, 0x11); - vga_out8 (0x3c5, par->SR11); + vga_out8 (0x3c4, 0x10, par); + vga_out8 (0x3c5, par->SR10, par); + vga_out8 (0x3c4, 0x11, par); + vga_out8 (0x3c5, par->SR11, par); } /* restore extended seq regs for dclk */ - vga_out8 (0x3c4, 0x0e); - vga_out8 (0x3c5, par->SR0E); - vga_out8 (0x3c4, 0x0f); - vga_out8 (0x3c5, par->SR0F); - vga_out8 (0x3c4, 0x12); - vga_out8 (0x3c5, par->SR12); - vga_out8 (0x3c4, 0x13); - vga_out8 (0x3c5, par->SR13); - vga_out8 (0x3c4, 0x29); - vga_out8 (0x3c5, par->SR29); - - vga_out8 (0x3c4, 0x18); - vga_out8 (0x3c5, par->SR18); + vga_out8 (0x3c4, 0x0e, par); + vga_out8 (0x3c5, par->SR0E, par); + vga_out8 (0x3c4, 0x0f, par); + vga_out8 (0x3c5, par->SR0F, par); + vga_out8 (0x3c4, 0x12, par); + vga_out8 (0x3c5, par->SR12, par); + vga_out8 (0x3c4, 0x13, par); + vga_out8 (0x3c5, par->SR13, par); + vga_out8 (0x3c4, 0x29, par); + vga_out8 (0x3c5, par->SR29, par); + + vga_out8 (0x3c4, 0x18, par); + vga_out8 (0x3c5, par->SR18, par); /* load new m, n pll values for dclk & mclk */ - vga_out8 (0x3c4, 0x15); - tmp = vga_in8 (0x3c5) & ~0x21; + vga_out8 (0x3c4, 0x15, par); + tmp = vga_in8 (0x3c5, par) & ~0x21; - vga_out8 (0x3c5, tmp | 0x03); - vga_out8 (0x3c5, tmp | 0x23); - vga_out8 (0x3c5, tmp | 0x03); - vga_out8 (0x3c5, par->SR15); + vga_out8 (0x3c5, tmp | 0x03, par); + vga_out8 (0x3c5, tmp | 0x23, par); + vga_out8 (0x3c5, tmp | 0x03, par); + vga_out8 (0x3c5, par->SR15, par); udelay (100); - vga_out8 (0x3c4, 0x30); - vga_out8 (0x3c5, par->SR30); - vga_out8 (0x3c4, 0x08); - vga_out8 (0x3c5, par->SR08); + vga_out8 (0x3c4, 0x30, par); + vga_out8 (0x3c5, par->SR30, par); + vga_out8 (0x3c4, 0x08, par); + vga_out8 (0x3c5, par->SR08, par); /* now write out cr67 in full, possibly starting STREAMS */ - VerticalRetraceWait(); - vga_out8 (0x3d4, 0x67); - vga_out8 (0x3d5, par->CR67); + VerticalRetraceWait(par); + vga_out8 (0x3d4, 0x67, par); + vga_out8 (0x3d5, par->CR67, par); - vga_out8 (0x3d4, 0x66); - cr66 = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr66 | 0x80); - vga_out8 (0x3d4, 0x3a); - cr3a = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr3a | 0x80); + vga_out8 (0x3d4, 0x66, par); + cr66 = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr66 | 0x80, par); + vga_out8 (0x3d4, 0x3a, par); + cr3a = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr3a | 0x80, par); if (par->chip != S3_SAVAGE_MX) { - VerticalRetraceWait(); - savage_out32 (FIFO_CONTROL_REG, par->MMPR0); + VerticalRetraceWait(par); + savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par); par->SavageWaitIdle (par); - savage_out32 (MIU_CONTROL_REG, par->MMPR1); + savage_out32 (MIU_CONTROL_REG, par->MMPR1, par); par->SavageWaitIdle (par); - savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2); + savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par); par->SavageWaitIdle (par); - savage_out32 (MISC_TIMEOUT_REG, par->MMPR3); + savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par); } - vga_out8 (0x3d4, 0x66); - vga_out8 (0x3d5, cr66); - vga_out8 (0x3d4, 0x3a); - vga_out8 (0x3d5, cr3a); + vga_out8 (0x3d4, 0x66, par); + vga_out8 (0x3d5, cr66, par); + vga_out8 (0x3d4, 0x3a, par); + vga_out8 (0x3d5, cr3a, par); SavageSetup2DEngine (par); vgaHWProtect (par, 0); @@ -1299,10 +1303,10 @@ static void savagefb_update_start (struct savagefb_par *par, * ((var->bits_per_pixel+7) / 8)) >> 2; /* now program the start address registers */ - vga_out16(0x3d4, (base & 0x00ff00) | 0x0c); - vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d); - vga_out8 (0x3d4, 0x69); - vga_out8 (0x3d5, (base & 0x7f0000) >> 16); + vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par); + vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par); + vga_out8 (0x3d4, 0x69, par); + vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par); } @@ -1311,10 +1315,14 @@ static void savagefb_set_fix(struct fb_info *info) info->fix.line_length = info->var.xres_virtual * info->var.bits_per_pixel / 8; - if (info->var.bits_per_pixel == 8) + if (info->var.bits_per_pixel == 8) { info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - else + info->fix.xpanstep = 4; + } else { info->fix.visual = FB_VISUAL_TRUECOLOR; + info->fix.xpanstep = 2; + } + } #if defined(CONFIG_FB_SAVAGE_ACCEL) @@ -1359,7 +1367,6 @@ static int savagefb_set_par (struct fb_info *info) par->minClock = 10000; savagefb_set_par_int (par); - savagefb_update_start (par, var); fb_set_cmap (&info->cmap, info); savagefb_set_fix(info); savagefb_set_clip(info); @@ -1406,12 +1413,12 @@ static int savagefb_blank(int blank, struct fb_info *info) u8 sr8 = 0, srd = 0; if (par->display_type == DISP_CRT) { - vga_out8(0x3c4, 0x08); - sr8 = vga_in8(0x3c5); + vga_out8(0x3c4, 0x08, par); + sr8 = vga_in8(0x3c5, par); sr8 |= 0x06; - vga_out8(0x3c5, sr8); - vga_out8(0x3c4, 0x0d); - srd = vga_in8(0x3c5); + vga_out8(0x3c5, sr8, par); + vga_out8(0x3c4, 0x0d, par); + srd = vga_in8(0x3c5, par); srd &= 0x03; switch (blank) { @@ -1429,8 +1436,8 @@ static int savagefb_blank(int blank, struct fb_info *info) break; } - vga_out8(0x3c4, 0x0d); - vga_out8(0x3c5, srd); + vga_out8(0x3c4, 0x0d, par); + vga_out8(0x3c5, srd, par); } if (par->display_type == DISP_LCD || @@ -1438,14 +1445,14 @@ static int savagefb_blank(int blank, struct fb_info *info) switch(blank) { case FB_BLANK_UNBLANK: case FB_BLANK_NORMAL: - vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */ - vga_out8(0x3c5, vga_in8(0x3c5) | 0x10); + vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */ + vga_out8(0x3c5, vga_in8(0x3c5, par) | 0x10, par); break; case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND: case FB_BLANK_POWERDOWN: - vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */ - vga_out8(0x3c5, vga_in8(0x3c5) & ~0x10); + vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */ + vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x10, par); break; } } @@ -1470,7 +1477,6 @@ static struct fb_ops savagefb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, #endif - .fb_cursor = soft_cursor, }; /* --------------------------------------------------------------------- */ @@ -1499,15 +1505,15 @@ static void savage_enable_mmio (struct savagefb_par *par) DBG ("savage_enable_mmio\n"); - val = vga_in8 (0x3c3); - vga_out8 (0x3c3, val | 0x01); - val = vga_in8 (0x3cc); - vga_out8 (0x3c2, val | 0x01); + val = vga_in8 (0x3c3, par); + vga_out8 (0x3c3, val | 0x01, par); + val = vga_in8 (0x3cc, par); + vga_out8 (0x3c2, val | 0x01, par); if (par->chip >= S3_SAVAGE4) { - vga_out8 (0x3d4, 0x40); - val = vga_in8 (0x3d5); - vga_out8 (0x3d5, val | 1); + vga_out8 (0x3d4, 0x40, par); + val = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, val | 1, par); } } @@ -1519,9 +1525,9 @@ static void savage_disable_mmio (struct savagefb_par *par) DBG ("savage_disable_mmio\n"); if(par->chip >= S3_SAVAGE4 ) { - vga_out8 (0x3d4, 0x40); - val = vga_in8 (0x3d5); - vga_out8 (0x3d5, val | 1); + vga_out8 (0x3d4, 0x40, par); + val = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, val | 1, par); } } @@ -1641,30 +1647,30 @@ static int __devinit savage_init_hw (struct savagefb_par *par) DBG("savage_init_hw"); /* unprotect CRTC[0-7] */ - vga_out8(0x3d4, 0x11); - tmp = vga_in8(0x3d5); - vga_out8(0x3d5, tmp & 0x7f); + vga_out8(0x3d4, 0x11, par); + tmp = vga_in8(0x3d5, par); + vga_out8(0x3d5, tmp & 0x7f, par); /* unlock extended regs */ - vga_out16(0x3d4, 0x4838); - vga_out16(0x3d4, 0xa039); - vga_out16(0x3c4, 0x0608); + vga_out16(0x3d4, 0x4838, par); + vga_out16(0x3d4, 0xa039, par); + vga_out16(0x3c4, 0x0608, par); - vga_out8(0x3d4, 0x40); - tmp = vga_in8(0x3d5); - vga_out8(0x3d5, tmp & ~0x01); + vga_out8(0x3d4, 0x40, par); + tmp = vga_in8(0x3d5, par); + vga_out8(0x3d5, tmp & ~0x01, par); /* unlock sys regs */ - vga_out8(0x3d4, 0x38); - vga_out8(0x3d5, 0x48); + vga_out8(0x3d4, 0x38, par); + vga_out8(0x3d5, 0x48, par); /* Unlock system registers. */ - vga_out16(0x3d4, 0x4838); + vga_out16(0x3d4, 0x4838, par); /* Next go on to detect amount of installed ram */ - vga_out8(0x3d4, 0x36); /* for register CR36 (CONFG_REG1), */ - config1 = vga_in8(0x3d5); /* get amount of vram installed */ + vga_out8(0x3d4, 0x36, par); /* for register CR36 (CONFG_REG1), */ + config1 = vga_in8(0x3d5, par); /* get amount of vram installed */ /* Compute the amount of video memory and offscreen memory. */ @@ -1680,8 +1686,8 @@ static int __devinit savage_init_hw (struct savagefb_par *par) * when it really means 8MB. Why do it the same when you * can do it different... */ - vga_out8(0x3d4, 0x68); /* memory control 1 */ - if( (vga_in8(0x3d5) & 0xC0) == (0x01 << 6) ) + vga_out8(0x3d4, 0x68, par); /* memory control 1 */ + if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) ) RamSavage4[1] = 8; /*FALLTHROUGH*/ @@ -1710,13 +1716,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par) printk (KERN_INFO "savagefb: probed videoram: %dk\n", videoRam); /* reset graphics engine to avoid memory corruption */ - vga_out8 (0x3d4, 0x66); - cr66 = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr66 | 0x02); + vga_out8 (0x3d4, 0x66, par); + cr66 = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr66 | 0x02, par); udelay (10000); - vga_out8 (0x3d4, 0x66); - vga_out8 (0x3d5, cr66 & ~0x02); /* clear reset flag */ + vga_out8 (0x3d4, 0x66, par); + vga_out8 (0x3d5, cr66 & ~0x02, par); /* clear reset flag */ udelay (10000); @@ -1724,13 +1730,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par) * reset memory interface, 3D engine, AGP master, PCI master, * master engine unit, motion compensation/LPB */ - vga_out8 (0x3d4, 0x3f); - cr3f = vga_in8 (0x3d5); - vga_out8 (0x3d5, cr3f | 0x08); + vga_out8 (0x3d4, 0x3f, par); + cr3f = vga_in8 (0x3d5, par); + vga_out8 (0x3d5, cr3f | 0x08, par); udelay (10000); - vga_out8 (0x3d4, 0x3f); - vga_out8 (0x3d5, cr3f & ~0x08); /* clear reset flags */ + vga_out8 (0x3d4, 0x3f, par); + vga_out8 (0x3d5, cr3f & ~0x08, par); /* clear reset flags */ udelay (10000); /* Savage ramdac speeds */ @@ -1741,15 +1747,15 @@ static int __devinit savage_init_hw (struct savagefb_par *par) par->clock[3] = 220000; /* detect current mclk */ - vga_out8(0x3c4, 0x08); - sr8 = vga_in8(0x3c5); - vga_out8(0x3c5, 0x06); - vga_out8(0x3c4, 0x10); - n = vga_in8(0x3c5); - vga_out8(0x3c4, 0x11); - m = vga_in8(0x3c5); - vga_out8(0x3c4, 0x08); - vga_out8(0x3c5, sr8); + vga_out8(0x3c4, 0x08, par); + sr8 = vga_in8(0x3c5, par); + vga_out8(0x3c5, 0x06, par); + vga_out8(0x3c4, 0x10, par); + n = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x11, par); + m = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x08, par); + vga_out8(0x3c5, sr8, par); m &= 0x7f; n1 = n & 0x1f; n2 = (n >> 5) & 0x03; @@ -1763,10 +1769,10 @@ static int __devinit savage_init_hw (struct savagefb_par *par) if (par->chip == S3_SAVAGE4) { unsigned char sr30 = 0x00; - vga_out8(0x3c4, 0x30); + vga_out8(0x3c4, 0x30, par); /* clear bit 1 */ - vga_out8(0x3c5, vga_in8(0x3c5) & ~0x02); - sr30 = vga_in8(0x3c5); + vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x02, par); + sr30 = vga_in8(0x3c5, par); if (sr30 & 0x02 /*0x04 */) { dvi = 1; printk("savagefb: Digital Flat Panel Detected\n"); @@ -1783,12 +1789,12 @@ static int __devinit savage_init_hw (struct savagefb_par *par) /* Check LCD panel parrmation */ if (par->display_type == DISP_LCD) { - unsigned char cr6b = VGArCR( 0x6b ); + unsigned char cr6b = VGArCR( 0x6b, par); - int panelX = (VGArSEQ (0x61) + - ((VGArSEQ (0x66) & 0x02) << 7) + 1) * 8; - int panelY = (VGArSEQ (0x69) + - ((VGArSEQ (0x6e) & 0x70) << 4) + 1); + int panelX = (VGArSEQ (0x61, par) + + ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8; + int panelY = (VGArSEQ (0x69, par) + + ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1); char * sTechnology = "Unknown"; @@ -1810,9 +1816,9 @@ static int __devinit savage_init_hw (struct savagefb_par *par) ActiveDUO = 0x80 }; - if ((VGArSEQ (0x39) & 0x03) == 0) { + if ((VGArSEQ (0x39, par) & 0x03) == 0) { sTechnology = "TFT"; - } else if ((VGArSEQ (0x30) & 0x01) == 0) { + } else if ((VGArSEQ (0x30, par) & 0x01) == 0) { sTechnology = "DSTN"; } else { sTechnology = "STN"; @@ -1870,7 +1876,6 @@ static int __devinit savage_init_fb_info (struct fb_info *info, info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.type_aux = 0; - info->fix.xpanstep = 2; info->fix.ypanstep = 1; info->fix.ywrapstep = 0; info->fix.accel = id->driver_data; @@ -2049,24 +2054,11 @@ static int __devinit savagefb_probe (struct pci_dev* dev, info->monspecs.modedb, info->monspecs.modedb_len, NULL, 8); } else if (info->monspecs.modedb != NULL) { - struct fb_monspecs *specs = &info->monspecs; - struct fb_videomode modedb; - - if (info->monspecs.misc & FB_MISC_1ST_DETAIL) { - int i; - - for (i = 0; i < specs->modedb_len; i++) { - if (specs->modedb[i].flag & FB_MODE_IS_FIRST) { - modedb = specs->modedb[i]; - break; - } - } - } else { - /* otherwise, get first mode in database */ - modedb = specs->modedb[0]; - } + struct fb_videomode *modedb; - savage_update_var(&info->var, &modedb); + modedb = fb_find_best_display(&info->monspecs, + &info->modelist); + savage_update_var(&info->var, modedb); } /* maximize virtual vertical length */ diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index cf5106eab2d..2e8769dd345 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c @@ -126,7 +126,6 @@ static struct fb_ops sgivwfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, .fb_mmap = sgivwfb_mmap, }; @@ -751,10 +750,6 @@ int __init sgivwfb_setup(char *options) /* * Initialisation */ -static void sgivwfb_release(struct device *device) -{ -} - static int __init sgivwfb_probe(struct device *device) { struct platform_device *dev = to_platform_device(device); @@ -859,13 +854,7 @@ static struct device_driver sgivwfb_driver = { .remove = sgivwfb_remove, }; -static struct platform_device sgivwfb_device = { - .name = "sgivwfb", - .id = 0, - .dev = { - .release = sgivwfb_release, - } -}; +static struct platform_device *sgivwfb_device; int __init sgivwfb_init(void) { @@ -880,9 +869,15 @@ int __init sgivwfb_init(void) #endif ret = driver_register(&sgivwfb_driver); if (!ret) { - ret = platform_device_register(&sgivwfb_device); - if (ret) + sgivwfb_device = platform_device_alloc("sgivwfb", 0); + if (sgivwfb_device) { + ret = platform_device_add(sgivwfb_device); + } else + ret = -ENOMEM; + if (ret) { driver_unregister(&sgivwfb_driver); + platform_device_put(sgivwfb_device); + } } return ret; } @@ -894,7 +889,7 @@ MODULE_LICENSE("GPL"); static void __exit sgivwfb_exit(void) { - platform_device_unregister(&sgivwfb_device); + platform_device_unregister(sgivwfb_device); driver_unregister(&sgivwfb_driver); } diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 42c54b69726..dea1a46c67c 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -2002,7 +2002,9 @@ static struct fb_ops sisfb_ops = { .fb_fillrect = fbcon_sis_fillrect, .fb_copyarea = fbcon_sis_copyarea, .fb_imageblit = cfb_imageblit, +#ifdef CONFIG_FB_SOFT_CURSOR .fb_cursor = soft_cursor, +#endif .fb_sync = fbcon_sis_sync, #ifdef SIS_NEW_CONFIG_COMPAT .fb_compat_ioctl= sisfb_compat_ioctl, diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index 7b43716ab66..a01e7ecc15e 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c @@ -457,11 +457,8 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) } /** - * xxxfb_cursor - REQUIRED function. If your hardware lacks support - * for a cursor you can use the default cursor whose - * function is called soft_cursor. It will always - * work since it uses xxxfb_imageblit function which - * is required. + * xxxfb_cursor - OPTIONAL. If your hardware lacks support + * for a cursor, leave this field NULL. * * @info: frame buffer structure that represents a single frame buffer * @cursor: structure defining the cursor to draw. @@ -663,7 +660,7 @@ static struct fb_ops xxxfb_ops = { .fb_fillrect = xxxfb_fillrect, /* Needed !!! */ .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ - .fb_cursor = xxxfb_cursor, /* Needed !!! */ + .fb_cursor = xxxfb_cursor, /* Optional !!! */ .fb_rotate = xxxfb_rotate, .fb_poll = xxxfb_poll, .fb_sync = xxxfb_sync, diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index 663d53657fa..e0f14df840d 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -1382,7 +1382,6 @@ static struct fb_ops sstfb_ops = { .fb_fillrect = cfb_fillrect, /* sstfb_fillrect */ .fb_copyarea = cfb_copyarea, /* sstfb_copyarea */ .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, .fb_ioctl = sstfb_ioctl, }; diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 9e52794768e..fbb17332afd 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -1147,7 +1147,6 @@ static struct fb_ops stifb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index 1986a8b3833..59fff29bc02 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -52,7 +52,6 @@ static struct fb_ops tcx_ops = { .fb_imageblit = cfb_imageblit, .fb_mmap = tcx_mmap, .fb_ioctl = tcx_ioctl, - .fb_cursor = soft_cursor, }; /* THC definitions */ diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 7044226c5d4..9d53387e6a6 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -184,7 +184,6 @@ static struct fb_ops tdfxfb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, #endif - .fb_cursor = soft_cursor, }; /* diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c index 9d9d2009ad8..7398bd48ba6 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/tgafb.c @@ -63,7 +63,6 @@ static struct fb_ops tgafb_ops = { .fb_fillrect = tgafb_fillrect, .fb_copyarea = tgafb_copyarea, .fb_imageblit = tgafb_imageblit, - .fb_cursor = soft_cursor, }; diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 81a6d9f188c..9ac2d317118 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c @@ -1293,7 +1293,6 @@ static struct fb_ops tridentfb_ops = { .fb_fillrect = tridentfb_fillrect, .fb_copyarea= tridentfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; module_init(tridentfb_init); diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c index 39d9ca71856..d904da44e1a 100644 --- a/drivers/video/tx3912fb.c +++ b/drivers/video/tx3912fb.c @@ -89,7 +89,6 @@ static struct fb_ops tx3912fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index 31a2bbc5397..ce97ec8eae9 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c @@ -135,7 +135,6 @@ static struct fb_ops valkyriefb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; /* Sets the video mode according to info->var */ diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 3cc23106641..e25eae1a78c 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -48,7 +48,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { }; static int inverse = 0; -static int mtrr = 3; /* default to write-combining */ +static int mtrr = 0; /* disable mtrr */ static int vram_remap __initdata = 0; /* Set amount of memory to be used */ static int vram_total __initdata = 0; /* Set total amount of memory */ static int pmi_setpal = 0; /* pmi for palette changes ??? */ @@ -166,45 +166,39 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, if (regno >= info->cmap.len) return 1; - switch (info->var.bits_per_pixel) { - case 8: + if (info->var.bits_per_pixel == 8) vesa_setpalette(regno,red,green,blue); - break; - case 16: - if (info->var.red.offset == 10) { - /* 1:5:5:5 */ - ((u32*) (info->pseudo_palette))[regno] = + else if (regno < 16) { + switch (info->var.bits_per_pixel) { + case 16: + if (info->var.red.offset == 10) { + /* 1:5:5:5 */ + ((u32*) (info->pseudo_palette))[regno] = ((red & 0xf800) >> 1) | ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); - } else { - /* 0:5:6:5 */ - ((u32*) (info->pseudo_palette))[regno] = + } else { + /* 0:5:6:5 */ + ((u32*) (info->pseudo_palette))[regno] = ((red & 0xf800) ) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); + } + break; + case 24: + case 32: + red >>= 8; + green >>= 8; + blue >>= 8; + ((u32 *)(info->pseudo_palette))[regno] = + (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); + break; } - break; - case 24: - red >>= 8; - green >>= 8; - blue >>= 8; - ((u32 *)(info->pseudo_palette))[regno] = - (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset); - break; - case 32: - red >>= 8; - green >>= 8; - blue >>= 8; - ((u32 *)(info->pseudo_palette))[regno] = - (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset); - break; - } - return 0; + } + + return 0; } static struct fb_ops vesafb_ops = { @@ -215,7 +209,6 @@ static struct fb_ops vesafb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; static int __init vesafb_setup(char *options) diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index 92d46555dd8..8794dc5d246 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c @@ -92,7 +92,6 @@ static struct fb_ops vfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, .fb_mmap = vfb_mmap, }; diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index b46454c55c9..226ae8a8848 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -21,6 +21,7 @@ #include <linux/fb.h> #include <linux/ioport.h> #include <linux/init.h> +#include <linux/platform_device.h> #include <asm/io.h> #include <video/vga.h> @@ -51,35 +52,33 @@ * card parameters */ -static struct fb_info vga16fb; - -static struct vga16fb_par { +struct vga16fb_par { /* structure holding original VGA register settings when the screen is blanked */ struct { - unsigned char SeqCtrlIndex; /* Sequencer Index reg. */ - unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */ - unsigned char CrtMiscIO; /* Miscellaneous register */ - unsigned char HorizontalTotal; /* CRT-Controller:00h */ - unsigned char HorizDisplayEnd; /* CRT-Controller:01h */ - unsigned char StartHorizRetrace; /* CRT-Controller:04h */ - unsigned char EndHorizRetrace; /* CRT-Controller:05h */ - unsigned char Overflow; /* CRT-Controller:07h */ - unsigned char StartVertRetrace; /* CRT-Controller:10h */ - unsigned char EndVertRetrace; /* CRT-Controller:11h */ - unsigned char ModeControl; /* CRT-Controller:17h */ - unsigned char ClockingMode; /* Seq-Controller:01h */ + unsigned char SeqCtrlIndex; /* Sequencer Index reg. */ + unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */ + unsigned char CrtMiscIO; /* Miscellaneous register */ + unsigned char HorizontalTotal; /* CRT-Controller:00h */ + unsigned char HorizDisplayEnd; /* CRT-Controller:01h */ + unsigned char StartHorizRetrace;/* CRT-Controller:04h */ + unsigned char EndHorizRetrace; /* CRT-Controller:05h */ + unsigned char Overflow; /* CRT-Controller:07h */ + unsigned char StartVertRetrace; /* CRT-Controller:10h */ + unsigned char EndVertRetrace; /* CRT-Controller:11h */ + unsigned char ModeControl; /* CRT-Controller:17h */ + unsigned char ClockingMode; /* Seq-Controller:01h */ } vga_state; struct vgastate state; atomic_t ref_count; int palette_blanked, vesa_blanked, mode, isVGA; u8 misc, pel_msk, vss, clkdiv; u8 crtc[VGA_CRT_C]; -} vga16_par; +}; /* --------------------------------------------------------------------- */ -static struct fb_var_screeninfo vga16fb_defined = { +static struct fb_var_screeninfo vga16fb_defined __initdata = { .xres = 640, .yres = 480, .xres_virtual = 640, @@ -205,7 +204,7 @@ static inline void setindex(int index) static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var) { - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; u32 xoffset, pos; xoffset = var->xoffset; @@ -300,7 +299,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par, static int vga16fb_open(struct fb_info *info, int user) { - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; int cnt = atomic_read(&par->ref_count); if (!cnt) { @@ -315,7 +314,7 @@ static int vga16fb_open(struct fb_info *info, int user) static int vga16fb_release(struct fb_info *info, int user) { - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; int cnt = atomic_read(&par->ref_count); if (!cnt) @@ -330,7 +329,7 @@ static int vga16fb_release(struct fb_info *info, int user) static int vga16fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; u32 xres, right, hslen, left, xtotal; u32 yres, lower, vslen, upper, ytotal; u32 vxres, xoffset, vyres, yoffset; @@ -535,7 +534,7 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var, static int vga16fb_set_par(struct fb_info *info) { - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; u8 gdc[VGA_GFX_C]; u8 seq[VGA_SEQ_C]; u8 atc[VGA_ATT_C]; @@ -677,7 +676,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; int gray; /* @@ -850,7 +849,7 @@ static void vga_pal_blank(void) /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ static int vga16fb_blank(int blank, struct fb_info *info) { - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; switch (blank) { case FB_BLANK_UNBLANK: /* Unblank */ @@ -1201,7 +1200,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im { char __iomem *where = info->screen_base + (image->dx/8) + image->dy * info->fix.line_length; - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; char *cdat = (char *) image->data; char __iomem *dst; int x, y; @@ -1266,7 +1265,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima /* * Draw logo */ - struct vga16fb_par *par = (struct vga16fb_par *) info->par; + struct vga16fb_par *par = info->par; char __iomem *where = info->screen_base + image->dy * info->fix.line_length + image->dx/8; @@ -1326,7 +1325,6 @@ static struct fb_ops vga16fb_ops = { .fb_fillrect = vga16fb_fillrect, .fb_copyarea = vga16fb_copyarea, .fb_imageblit = vga16fb_imageblit, - .fb_cursor = soft_cursor, }; #ifndef MODULE @@ -1344,89 +1342,141 @@ static int vga16fb_setup(char *options) } #endif -static int __init vga16fb_init(void) +static int __init vga16fb_probe(struct device *device) { + struct platform_device *dev = to_platform_device(device); + struct fb_info *info; + struct vga16fb_par *par; int i; - int ret; -#ifndef MODULE - char *option = NULL; + int ret = 0; - if (fb_get_options("vga16fb", &option)) - return -ENODEV; - - vga16fb_setup(option); -#endif printk(KERN_DEBUG "vga16fb: initializing\n"); + info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev); + + if (!info) { + ret = -ENOMEM; + goto err_fb_alloc; + } /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ + info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); - vga16fb.screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); - if (!vga16fb.screen_base) { + if (!info->screen_base) { printk(KERN_ERR "vga16fb: unable to map device\n"); ret = -ENOMEM; goto err_ioremap; } - printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base); - vga16_par.isVGA = ORIG_VIDEO_ISVGA; - vga16_par.palette_blanked = 0; - vga16_par.vesa_blanked = 0; + printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); + par = info->par; - i = vga16_par.isVGA? 6 : 2; + par->isVGA = ORIG_VIDEO_ISVGA; + par->palette_blanked = 0; + par->vesa_blanked = 0; + + i = par->isVGA? 6 : 2; vga16fb_defined.red.length = i; vga16fb_defined.green.length = i; vga16fb_defined.blue.length = i; /* name should not depend on EGA/VGA */ - vga16fb.fbops = &vga16fb_ops; - vga16fb.var = vga16fb_defined; - vga16fb.fix = vga16fb_fix; - vga16fb.par = &vga16_par; - vga16fb.flags = FBINFO_FLAG_DEFAULT | + info->fbops = &vga16fb_ops; + info->var = vga16fb_defined; + info->fix = vga16fb_fix; + info->flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_YPAN; - i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16; - ret = fb_alloc_cmap(&vga16fb.cmap, i, 0); + i = (info->var.bits_per_pixel == 8) ? 256 : 16; + ret = fb_alloc_cmap(&info->cmap, i, 0); if (ret) { printk(KERN_ERR "vga16fb: unable to allocate colormap\n"); ret = -ENOMEM; goto err_alloc_cmap; } - if (vga16fb_check_var(&vga16fb.var, &vga16fb)) { + if (vga16fb_check_var(&info->var, info)) { printk(KERN_ERR "vga16fb: unable to validate variable\n"); ret = -EINVAL; goto err_check_var; } - vga16fb_update_fix(&vga16fb); + vga16fb_update_fix(info); - if (register_framebuffer(&vga16fb) < 0) { + if (register_framebuffer(info) < 0) { printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); ret = -EINVAL; goto err_check_var; } printk(KERN_INFO "fb%d: %s frame buffer device\n", - vga16fb.node, vga16fb.fix.id); + info->node, info->fix.id); + dev_set_drvdata(device, info); return 0; err_check_var: - fb_dealloc_cmap(&vga16fb.cmap); + fb_dealloc_cmap(&info->cmap); err_alloc_cmap: - iounmap(vga16fb.screen_base); + iounmap(info->screen_base); err_ioremap: + framebuffer_release(info); + err_fb_alloc: + return ret; +} + +static int vga16fb_remove(struct device *device) +{ + struct fb_info *info = dev_get_drvdata(device); + + if (info) { + unregister_framebuffer(info); + iounmap(info->screen_base); + fb_dealloc_cmap(&info->cmap); + /* XXX unshare VGA regions */ + framebuffer_release(info); + } + + return 0; +} + +static struct device_driver vga16fb_driver = { + .name = "vga16fb", + .bus = &platform_bus_type, + .probe = vga16fb_probe, + .remove = vga16fb_remove, +}; + +static struct platform_device vga16fb_device = { + .name = "vga16fb", +}; + +static int __init vga16fb_init(void) +{ + int ret; +#ifndef MODULE + char *option = NULL; + + if (fb_get_options("vga16fb", &option)) + return -ENODEV; + + vga16fb_setup(option); +#endif + ret = driver_register(&vga16fb_driver); + + if (!ret) { + ret = platform_device_register(&vga16fb_device); + if (ret) + driver_unregister(&vga16fb_driver); + } + return ret; } static void __exit vga16fb_exit(void) { - unregister_framebuffer(&vga16fb); - iounmap(vga16fb.screen_base); - fb_dealloc_cmap(&vga16fb.cmap); - /* XXX unshare VGA regions */ + platform_device_unregister(&vga16fb_device); + driver_unregister(&vga16fb_driver); } MODULE_LICENSE("GPL"); diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c index ca92940f394..d9e01daee63 100644 --- a/drivers/video/vgastate.c +++ b/drivers/video/vgastate.c @@ -485,11 +485,6 @@ int restore_vga (struct vgastate *state) return 0; } -#ifdef MODULE -int init_module(void) { return 0; }; -void cleanup_module(void) {}; -#endif - EXPORT_SYMBOL(save_vga); EXPORT_SYMBOL(restore_vga); diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index cf8cdb108fd..48e70f153c4 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c @@ -397,7 +397,6 @@ static struct fb_ops w100fb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; #ifdef CONFIG_PM |