aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/68328fb.c1
-rw-r--r--drivers/video/Kconfig140
-rw-r--r--drivers/video/Makefile13
-rw-r--r--drivers/video/S3triofb.c14
-rw-r--r--drivers/video/acornfb.c1
-rw-r--r--drivers/video/amifb.c2
-rw-r--r--drivers/video/arcfb.c3
-rw-r--r--drivers/video/asiliantfb.c2
-rw-r--r--drivers/video/atafb.c1
-rw-r--r--drivers/video/aty/Makefile1
-rw-r--r--drivers/video/aty/aty128fb.c377
-rw-r--r--drivers/video/aty/atyfb.h2
-rw-r--r--drivers/video/aty/atyfb_base.c237
-rw-r--r--drivers/video/aty/mach64_accel.c10
-rw-r--r--drivers/video/aty/mach64_cursor.c33
-rw-r--r--drivers/video/aty/radeon_backlight.c247
-rw-r--r--drivers/video/aty/radeon_base.c170
-rw-r--r--drivers/video/aty/radeon_i2c.c1
-rw-r--r--drivers/video/aty/radeon_monitor.c12
-rw-r--r--drivers/video/aty/radeon_pm.c165
-rw-r--r--drivers/video/aty/radeonfb.h18
-rw-r--r--drivers/video/au1100fb.c63
-rw-r--r--drivers/video/au1200fb.c2
-rw-r--r--drivers/video/backlight/Kconfig8
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/hp680_bl.c6
-rw-r--r--drivers/video/backlight/locomolcd.c150
-rw-r--r--drivers/video/bw2.c213
-rw-r--r--drivers/video/cfbcopyarea.c1
-rw-r--r--drivers/video/cfbfillrect.c1
-rw-r--r--drivers/video/cfbimgblt.c2
-rw-r--r--drivers/video/cg14.c326
-rw-r--r--drivers/video/cg3.c217
-rw-r--r--drivers/video/cg6.c337
-rw-r--r--drivers/video/chipsfb.c31
-rw-r--r--drivers/video/cirrusfb.c4
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/console/bitblit.c1
-rw-r--r--drivers/video/console/dummycon.c3
-rw-r--r--drivers/video/console/fbcon.c363
-rw-r--r--drivers/video/console/fbcon.h2
-rw-r--r--drivers/video/console/fbcon_ccw.c1
-rw-r--r--drivers/video/console/fbcon_cw.c1
-rw-r--r--drivers/video/console/fbcon_rotate.c1
-rw-r--r--drivers/video/console/fbcon_ud.c1
-rw-r--r--drivers/video/console/font_acorn_8x8.c1
-rw-r--r--drivers/video/console/fonts.c1
-rw-r--r--drivers/video/console/mdacon.c7
-rw-r--r--drivers/video/console/newport_con.c39
-rw-r--r--drivers/video/console/promcon.c6
-rw-r--r--drivers/video/console/softcursor.c1
-rw-r--r--drivers/video/console/sticon.c3
-rw-r--r--drivers/video/console/sticore.c1
-rw-r--r--drivers/video/console/tileblit.c1
-rw-r--r--drivers/video/console/vgacon.c43
-rw-r--r--drivers/video/controlfb.c2
-rw-r--r--drivers/video/cyber2000fb.c2
-rw-r--r--drivers/video/cyber2000fb.h1
-rw-r--r--drivers/video/cyberfb.c1
-rw-r--r--drivers/video/cyblafb.c1
-rw-r--r--drivers/video/dnfb.c1
-rw-r--r--drivers/video/epson1355fb.c30
-rw-r--r--drivers/video/fb_notify.c46
-rw-r--r--drivers/video/fbcmap.c1
-rw-r--r--drivers/video/fbcvt.c1
-rw-r--r--drivers/video/fbmem.c116
-rw-r--r--drivers/video/fbmon.c34
-rw-r--r--drivers/video/fbsysfs.c152
-rw-r--r--drivers/video/ffb.c466
-rw-r--r--drivers/video/g364fb.c1
-rw-r--r--drivers/video/gbefb.c1
-rw-r--r--drivers/video/geode/gx1fb_core.c4
-rw-r--r--drivers/video/geode/gxfb_core.c4
-rw-r--r--drivers/video/hgafb.c1
-rw-r--r--drivers/video/hitfb.c231
-rw-r--r--drivers/video/hpfb.c1
-rw-r--r--drivers/video/i810/i810-i2c.c2
-rw-r--r--drivers/video/i810/i810_main.c17
-rw-r--r--drivers/video/igafb.c4
-rw-r--r--drivers/video/imacfb.c380
-rw-r--r--drivers/video/imsttfb.c2
-rw-r--r--drivers/video/imxfb.c1
-rw-r--r--drivers/video/intelfb/intelfbdrv.c3
-rw-r--r--drivers/video/intelfb/intelfbhw.c2
-rw-r--r--drivers/video/kyro/fbdev.c2
-rw-r--r--drivers/video/leo.c294
-rw-r--r--drivers/video/logo/logo.c1
-rw-r--r--drivers/video/macfb.c1
-rw-r--r--drivers/video/macmodes.c7
-rw-r--r--drivers/video/macmodes.h7
-rw-r--r--drivers/video/matrox/g450_pll.c8
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c12
-rw-r--r--drivers/video/matrox/matroxfb_DAC1064.c1
-rw-r--r--drivers/video/matrox/matroxfb_DAC1064.h1
-rw-r--r--drivers/video/matrox/matroxfb_Ti3026.c1
-rw-r--r--drivers/video/matrox/matroxfb_Ti3026.h1
-rw-r--r--drivers/video/matrox/matroxfb_base.c55
-rw-r--r--drivers/video/matrox/matroxfb_base.h2
-rw-r--r--drivers/video/matrox/matroxfb_misc.c1
-rw-r--r--drivers/video/maxinefb.c1
-rw-r--r--drivers/video/mbx/Makefile4
-rw-r--r--drivers/video/mbx/mbxdebugfs.c188
-rw-r--r--drivers/video/mbx/mbxfb.c683
-rw-r--r--drivers/video/mbx/reg_bits.h418
-rw-r--r--drivers/video/mbx/regs.h195
-rw-r--r--drivers/video/modedb.c12
-rw-r--r--drivers/video/neofb.c34
-rw-r--r--drivers/video/nvidia/Makefile3
-rw-r--r--drivers/video/nvidia/nv_backlight.c203
-rw-r--r--drivers/video/nvidia/nv_hw.c10
-rw-r--r--drivers/video/nvidia/nv_i2c.c1
-rw-r--r--drivers/video/nvidia/nv_of.c13
-rw-r--r--drivers/video/nvidia/nv_proto.h12
-rw-r--r--drivers/video/nvidia/nvidia.c480
-rw-r--r--drivers/video/offb.c445
-rw-r--r--drivers/video/p9100.c251
-rw-r--r--drivers/video/platinumfb.c2
-rw-r--r--drivers/video/pm2fb.c2
-rw-r--r--drivers/video/pm3fb.c2
-rw-r--r--drivers/video/pmag-aa-fb.c1
-rw-r--r--drivers/video/pnx4008/Makefile7
-rw-r--r--drivers/video/pnx4008/dum.h211
-rw-r--r--drivers/video/pnx4008/fbcommon.h43
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c213
-rw-r--r--drivers/video/pnx4008/sdum.c872
-rw-r--r--drivers/video/pnx4008/sdum.h139
-rw-r--r--drivers/video/pvr2fb.c24
-rw-r--r--drivers/video/pxafb.c3
-rw-r--r--drivers/video/q40fb.c1
-rw-r--r--drivers/video/retz3fb.c1
-rw-r--r--drivers/video/riva/fbdev.c262
-rw-r--r--drivers/video/riva/rivafb-i2c.c1
-rw-r--r--drivers/video/riva/rivafb.h1
-rw-r--r--drivers/video/s1d13xxxfb.c1
-rw-r--r--drivers/video/s3c2410fb.c20
-rw-r--r--drivers/video/sa1100fb.c3
-rw-r--r--drivers/video/savage/savagefb-i2c.c2
-rw-r--r--drivers/video/savage/savagefb.h45
-rw-r--r--drivers/video/savage/savagefb_driver.c1489
-rw-r--r--drivers/video/sgivwfb.c7
-rw-r--r--drivers/video/sis/init.h1
-rw-r--r--drivers/video/sis/init301.c4
-rw-r--r--drivers/video/sis/init301.h1
-rw-r--r--drivers/video/sis/initextlfb.c1
-rw-r--r--drivers/video/sis/osdef.h1
-rw-r--r--drivers/video/sis/sis.h1
-rw-r--r--drivers/video/sis/sis_accel.c1
-rw-r--r--drivers/video/sis/sis_main.c9
-rw-r--r--drivers/video/skeletonfb.c6
-rw-r--r--drivers/video/sstfb.c1
-rw-r--r--drivers/video/stifb.c1
-rw-r--r--drivers/video/sun3fb.c2
-rw-r--r--drivers/video/tcx.c224
-rw-r--r--drivers/video/tdfxfb.c2
-rw-r--r--drivers/video/tgafb.c2
-rw-r--r--drivers/video/tridentfb.c7
-rw-r--r--drivers/video/tx3912fb.c1
-rw-r--r--drivers/video/valkyriefb.c2
-rw-r--r--drivers/video/vesafb.c61
-rw-r--r--drivers/video/vfb.c30
-rw-r--r--drivers/video/vga16fb.c42
-rw-r--r--drivers/video/vgastate.c1
-rw-r--r--drivers/video/virgefb.c1
163 files changed, 8238 insertions, 3662 deletions
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 78488bb41aeb..0dda73da8628 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -32,7 +32,6 @@
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/mm.h> 34#include <linux/mm.h>
35#include <linux/tty.h>
36#include <linux/slab.h> 35#include <linux/slab.h>
37#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
38#include <linux/delay.h> 37#include <linux/delay.h>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 60c6773eaac4..e0ef3328942c 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -4,6 +4,21 @@
4 4
5menu "Graphics support" 5menu "Graphics support"
6 6
7config FIRMWARE_EDID
8 bool "Enable firmware EDID"
9 default y
10 ---help---
11 This enables access to the EDID transferred from the firmware.
12 On the i386, this is from the Video BIOS. Enable this if DDC/I2C
13 transfers do not work for your driver and if you are using
14 nvidiafb, i810fb or savagefb.
15
16 In general, choosing Y for this option is safe. If you
17 experience extremely long delays while booting before you get
18 something on your display, try setting this to N. Matrox cards in
19 combination with certain motherboards and monitors are known to
20 suffer from this problem.
21
7config FB 22config FB
8 tristate "Support for frame buffer devices" 23 tristate "Support for frame buffer devices"
9 ---help--- 24 ---help---
@@ -70,21 +85,12 @@ config FB_MACMODES
70 depends on FB 85 depends on FB
71 default n 86 default n
72 87
73config FB_FIRMWARE_EDID 88config FB_BACKLIGHT
74 bool "Enable firmware EDID" 89 bool
75 depends on FB 90 depends on FB
76 default y 91 select BACKLIGHT_LCD_SUPPORT
77 ---help--- 92 select BACKLIGHT_CLASS_DEVICE
78 This enables access to the EDID transferred from the firmware. 93 default n
79 On the i386, this is from the Video BIOS. Enable this if DDC/I2C
80 transfers do not work for your driver and if you are using
81 nvidiafb, i810fb or savagefb.
82
83 In general, choosing Y for this option is safe. If you
84 experience extremely long delays while booting before you get
85 something on your display, try setting this to N. Matrox cards in
86 combination with certain motherboards and monitors are known to
87 suffer from this problem.
88 94
89config FB_MODE_HELPERS 95config FB_MODE_HELPERS
90 bool "Enable Video Mode Handling Helpers" 96 bool "Enable Video Mode Handling Helpers"
@@ -416,7 +422,7 @@ config FB_OF
416 422
417config FB_CONTROL 423config FB_CONTROL
418 bool "Apple \"control\" display support" 424 bool "Apple \"control\" display support"
419 depends on (FB = y) && PPC_PMAC 425 depends on (FB = y) && PPC_PMAC && PPC32
420 select FB_CFB_FILLRECT 426 select FB_CFB_FILLRECT
421 select FB_CFB_COPYAREA 427 select FB_CFB_COPYAREA
422 select FB_CFB_IMAGEBLIT 428 select FB_CFB_IMAGEBLIT
@@ -427,7 +433,7 @@ config FB_CONTROL
427 433
428config FB_PLATINUM 434config FB_PLATINUM
429 bool "Apple \"platinum\" display support" 435 bool "Apple \"platinum\" display support"
430 depends on (FB = y) && PPC_PMAC 436 depends on (FB = y) && PPC_PMAC && PPC32
431 select FB_CFB_FILLRECT 437 select FB_CFB_FILLRECT
432 select FB_CFB_COPYAREA 438 select FB_CFB_COPYAREA
433 select FB_CFB_IMAGEBLIT 439 select FB_CFB_IMAGEBLIT
@@ -438,7 +444,7 @@ config FB_PLATINUM
438 444
439config FB_VALKYRIE 445config FB_VALKYRIE
440 bool "Apple \"valkyrie\" display support" 446 bool "Apple \"valkyrie\" display support"
441 depends on (FB = y) && (MAC || PPC_PMAC) 447 depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
442 select FB_CFB_FILLRECT 448 select FB_CFB_FILLRECT
443 select FB_CFB_COPYAREA 449 select FB_CFB_COPYAREA
444 select FB_CFB_IMAGEBLIT 450 select FB_CFB_IMAGEBLIT
@@ -449,7 +455,7 @@ config FB_VALKYRIE
449 455
450config FB_CT65550 456config FB_CT65550
451 bool "Chips 65550 display support" 457 bool "Chips 65550 display support"
452 depends on (FB = y) && PPC 458 depends on (FB = y) && PPC32
453 select FB_CFB_FILLRECT 459 select FB_CFB_FILLRECT
454 select FB_CFB_COPYAREA 460 select FB_CFB_COPYAREA
455 select FB_CFB_IMAGEBLIT 461 select FB_CFB_IMAGEBLIT
@@ -546,10 +552,14 @@ config FB_VESA
546 You will get a boot time penguin logo at no additional cost. Please 552 You will get a boot time penguin logo at no additional cost. Please
547 read <file:Documentation/fb/vesafb.txt>. If unsure, say Y. 553 read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
548 554
549config VIDEO_SELECT 555config FB_IMAC
550 bool 556 bool "Intel-based Macintosh Framebuffer Support"
551 depends on FB_VESA 557 depends on (FB = y) && X86 && EFI
552 default y 558 select FB_CFB_FILLRECT
559 select FB_CFB_COPYAREA
560 select FB_CFB_IMAGEBLIT
561 help
562 This is the frame buffer device driver for the Intel-based Macintosh
553 563
554config FB_HGA 564config FB_HGA
555 tristate "Hercules mono graphics support" 565 tristate "Hercules mono graphics support"
@@ -573,12 +583,6 @@ config FB_HGA_ACCEL
573 This will compile the Hercules mono graphics with 583 This will compile the Hercules mono graphics with
574 acceleration functions. 584 acceleration functions.
575 585
576
577config VIDEO_SELECT
578 bool
579 depends on (FB = y) && X86
580 default y
581
582config FB_SGIVW 586config FB_SGIVW
583 tristate "SGI Visual Workstation framebuffer support" 587 tristate "SGI Visual Workstation framebuffer support"
584 depends on FB && X86_VISWS 588 depends on FB && X86_VISWS
@@ -717,6 +721,14 @@ config FB_NVIDIA_I2C
717 independently validate video mode parameters, you should say Y 721 independently validate video mode parameters, you should say Y
718 here. 722 here.
719 723
724config FB_NVIDIA_BACKLIGHT
725 bool "Support for backlight control"
726 depends on FB_NVIDIA && PMAC_BACKLIGHT
727 select FB_BACKLIGHT
728 default y
729 help
730 Say Y here if you want to control the backlight of your display.
731
720config FB_RIVA 732config FB_RIVA
721 tristate "nVidia Riva support" 733 tristate "nVidia Riva support"
722 depends on FB && PCI 734 depends on FB && PCI
@@ -755,6 +767,14 @@ config FB_RIVA_DEBUG
755 of debugging informations to provide to the maintainer when 767 of debugging informations to provide to the maintainer when
756 something goes wrong. 768 something goes wrong.
757 769
770config FB_RIVA_BACKLIGHT
771 bool "Support for backlight control"
772 depends on FB_RIVA && PMAC_BACKLIGHT
773 select FB_BACKLIGHT
774 default y
775 help
776 Say Y here if you want to control the backlight of your display.
777
758config FB_I810 778config FB_I810
759 tristate "Intel 810/815 support (EXPERIMENTAL)" 779 tristate "Intel 810/815 support (EXPERIMENTAL)"
760 depends on FB && EXPERIMENTAL && PCI && X86_32 780 depends on FB && EXPERIMENTAL && PCI && X86_32
@@ -1011,6 +1031,7 @@ config FB_RADEON
1011 1031
1012 There is a product page at 1032 There is a product page at
1013 http://apps.ati.com/ATIcompare/ 1033 http://apps.ati.com/ATIcompare/
1034
1014config FB_RADEON_I2C 1035config FB_RADEON_I2C
1015 bool "DDC/I2C for ATI Radeon support" 1036 bool "DDC/I2C for ATI Radeon support"
1016 depends on FB_RADEON 1037 depends on FB_RADEON
@@ -1018,6 +1039,14 @@ config FB_RADEON_I2C
1018 help 1039 help
1019 Say Y here if you want DDC/I2C support for your Radeon board. 1040 Say Y here if you want DDC/I2C support for your Radeon board.
1020 1041
1042config FB_RADEON_BACKLIGHT
1043 bool "Support for backlight control"
1044 depends on FB_RADEON && PMAC_BACKLIGHT
1045 select FB_BACKLIGHT
1046 default y
1047 help
1048 Say Y here if you want to control the backlight of your display.
1049
1021config FB_RADEON_DEBUG 1050config FB_RADEON_DEBUG
1022 bool "Lots of debug output from Radeon driver" 1051 bool "Lots of debug output from Radeon driver"
1023 depends on FB_RADEON 1052 depends on FB_RADEON
@@ -1042,6 +1071,14 @@ config FB_ATY128
1042 To compile this driver as a module, choose M here: the 1071 To compile this driver as a module, choose M here: the
1043 module will be called aty128fb. 1072 module will be called aty128fb.
1044 1073
1074config FB_ATY128_BACKLIGHT
1075 bool "Support for backlight control"
1076 depends on FB_ATY128 && PMAC_BACKLIGHT
1077 select FB_BACKLIGHT
1078 default y
1079 help
1080 Say Y here if you want to control the backlight of your display.
1081
1045config FB_ATY 1082config FB_ATY
1046 tristate "ATI Mach64 display support" if PCI || ATARI 1083 tristate "ATI Mach64 display support" if PCI || ATARI
1047 depends on FB && !SPARC32 1084 depends on FB && !SPARC32
@@ -1084,6 +1121,14 @@ config FB_ATY_GX
1084 is at 1121 is at
1085 <http://support.ati.com/products/pc/mach64/graphics_xpression.html>. 1122 <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
1086 1123
1124config FB_ATY_BACKLIGHT
1125 bool "Support for backlight control"
1126 depends on FB_ATY && PMAC_BACKLIGHT
1127 select FB_BACKLIGHT
1128 default y
1129 help
1130 Say Y here if you want to control the backlight of your display.
1131
1087config FB_S3TRIO 1132config FB_S3TRIO
1088 bool "S3 Trio display support" 1133 bool "S3 Trio display support"
1089 depends on (FB = y) && PPC && BROKEN 1134 depends on (FB = y) && PPC && BROKEN
@@ -1483,6 +1528,26 @@ config FB_PXA_PARAMETERS
1483 1528
1484 <file:Documentation/fb/pxafb.txt> describes the available parameters. 1529 <file:Documentation/fb/pxafb.txt> describes the available parameters.
1485 1530
1531config FB_MBX
1532 tristate "2700G LCD framebuffer support"
1533 depends on FB && ARCH_PXA
1534 select FB_CFB_FILLRECT
1535 select FB_CFB_COPYAREA
1536 select FB_CFB_IMAGEBLIT
1537 ---help---
1538 Framebuffer driver for the Intel 2700G (Marathon) Graphics
1539 Accelerator
1540
1541config FB_MBX_DEBUG
1542 bool "Enable debugging info via debugfs"
1543 depends on FB_MBX && DEBUG_FS
1544 default n
1545 ---help---
1546 Enable this if you want debugging information using the debug
1547 filesystem (debugfs)
1548
1549 If unsure, say N.
1550
1486config FB_W100 1551config FB_W100
1487 tristate "W100 frame buffer support" 1552 tristate "W100 frame buffer support"
1488 depends on FB && PXA_SHARPSL 1553 depends on FB && PXA_SHARPSL
@@ -1522,6 +1587,21 @@ config FB_S3C2410_DEBUG
1522 Turn on debugging messages. Note that you can set/unset at run time 1587 Turn on debugging messages. Note that you can set/unset at run time
1523 through sysfs 1588 through sysfs
1524 1589
1590config FB_PNX4008_DUM
1591 tristate "Display Update Module support on Philips PNX4008 board"
1592 depends on FB && ARCH_PNX4008
1593 ---help---
1594 Say Y here to enable support for PNX4008 Display Update Module (DUM)
1595
1596config FB_PNX4008_DUM_RGB
1597 tristate "RGB Framebuffer support on Philips PNX4008 board"
1598 depends on FB_PNX4008_DUM
1599 select FB_CFB_FILLRECT
1600 select FB_CFB_COPYAREA
1601 select FB_CFB_IMAGEBLIT
1602 ---help---
1603 Say Y here to enable support for PNX4008 RGB Framebuffer
1604
1525config FB_VIRTUAL 1605config FB_VIRTUAL
1526 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 1606 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1527 depends on FB 1607 depends on FB
@@ -1550,7 +1630,7 @@ if FB || SGI_NEWPORT_CONSOLE
1550 source "drivers/video/logo/Kconfig" 1630 source "drivers/video/logo/Kconfig"
1551endif 1631endif
1552 1632
1553if FB && SYSFS 1633if SYSFS
1554 source "drivers/video/backlight/Kconfig" 1634 source "drivers/video/backlight/Kconfig"
1555endif 1635endif
1556 1636
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23de3b2c7856..481c6c9695f8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -4,15 +4,16 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_VT) += console/ 7obj-y += fb_notify.o
8obj-$(CONFIG_LOGO) += logo/
9obj-$(CONFIG_SYSFS) += backlight/
10
11obj-$(CONFIG_FB) += fb.o 8obj-$(CONFIG_FB) += fb.o
12fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ 9fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
13 modedb.o fbcvt.o 10 modedb.o fbcvt.o
14fb-objs := $(fb-y) 11fb-objs := $(fb-y)
15 12
13obj-$(CONFIG_VT) += console/
14obj-$(CONFIG_LOGO) += logo/
15obj-$(CONFIG_SYSFS) += backlight/
16
16obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o 17obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
17obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o 18obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
18obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o 19obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
@@ -38,6 +39,7 @@ obj-$(CONFIG_FB_SIS) += sis/
38obj-$(CONFIG_FB_KYRO) += kyro/ 39obj-$(CONFIG_FB_KYRO) += kyro/
39obj-$(CONFIG_FB_SAVAGE) += savage/ 40obj-$(CONFIG_FB_SAVAGE) += savage/
40obj-$(CONFIG_FB_GEODE) += geode/ 41obj-$(CONFIG_FB_GEODE) += geode/
42obj-$(CONFIG_FB_MBX) += mbx/
41obj-$(CONFIG_FB_I810) += vgastate.o 43obj-$(CONFIG_FB_I810) += vgastate.o
42obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o 44obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
43obj-$(CONFIG_FB_VIRGE) += virgefb.o 45obj-$(CONFIG_FB_VIRGE) += virgefb.o
@@ -94,9 +96,12 @@ obj-$(CONFIG_FB_TX3912) += tx3912fb.o
94obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 96obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
95obj-$(CONFIG_FB_IMX) += imxfb.o 97obj-$(CONFIG_FB_IMX) += imxfb.o
96obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o 98obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
99obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
100obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
97 101
98# Platform or fallback drivers go here 102# Platform or fallback drivers go here
99obj-$(CONFIG_FB_VESA) += vesafb.o 103obj-$(CONFIG_FB_VESA) += vesafb.o
104obj-$(CONFIG_FB_IMAC) += imacfb.o
100obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o 105obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o
101obj-$(CONFIG_FB_OF) += offb.o 106obj-$(CONFIG_FB_OF) += offb.o
102 107
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index 455fda990ff7..397005eb392d 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -23,13 +23,11 @@
23 23
24*/ 24*/
25 25
26#include <linux/config.h>
27#include <linux/kernel.h> 26#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/errno.h> 28#include <linux/errno.h>
30#include <linux/string.h> 29#include <linux/string.h>
31#include <linux/mm.h> 30#include <linux/mm.h>
32#include <linux/tty.h>
33#include <linux/slab.h> 31#include <linux/slab.h>
34#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
35#include <linux/delay.h> 33#include <linux/delay.h>
@@ -351,30 +349,30 @@ static void __init s3triofb_of_init(struct device_node *dp)
351 s3trio_name[sizeof(s3trio_name)-1] = '\0'; 349 s3trio_name[sizeof(s3trio_name)-1] = '\0';
352 strcpy(fb_fix.id, s3trio_name); 350 strcpy(fb_fix.id, s3trio_name);
353 351
354 if((pp = (int *)get_property(dp, "vendor-id", &len)) != NULL 352 if((pp = get_property(dp, "vendor-id", &len)) != NULL
355 && *pp!=PCI_VENDOR_ID_S3) { 353 && *pp!=PCI_VENDOR_ID_S3) {
356 printk("%s: can't find S3 Trio board\n", dp->full_name); 354 printk("%s: can't find S3 Trio board\n", dp->full_name);
357 return; 355 return;
358 } 356 }
359 357
360 if((pp = (int *)get_property(dp, "device-id", &len)) != NULL 358 if((pp = get_property(dp, "device-id", &len)) != NULL
361 && *pp!=PCI_DEVICE_ID_S3_TRIO) { 359 && *pp!=PCI_DEVICE_ID_S3_TRIO) {
362 printk("%s: can't find S3 Trio board\n", dp->full_name); 360 printk("%s: can't find S3 Trio board\n", dp->full_name);
363 return; 361 return;
364 } 362 }
365 363
366 if ((pp = (int *)get_property(dp, "depth", &len)) != NULL 364 if ((pp = get_property(dp, "depth", &len)) != NULL
367 && len == sizeof(int) && *pp != 8) { 365 && len == sizeof(int) && *pp != 8) {
368 printk("%s: can't use depth = %d\n", dp->full_name, *pp); 366 printk("%s: can't use depth = %d\n", dp->full_name, *pp);
369 return; 367 return;
370 } 368 }
371 if ((pp = (int *)get_property(dp, "width", &len)) != NULL 369 if ((pp = get_property(dp, "width", &len)) != NULL
372 && len == sizeof(int)) 370 && len == sizeof(int))
373 fb_var.xres = fb_var.xres_virtual = *pp; 371 fb_var.xres = fb_var.xres_virtual = *pp;
374 if ((pp = (int *)get_property(dp, "height", &len)) != NULL 372 if ((pp = get_property(dp, "height", &len)) != NULL
375 && len == sizeof(int)) 373 && len == sizeof(int))
376 fb_var.yres = fb_var.yres_virtual = *pp; 374 fb_var.yres = fb_var.yres_virtual = *pp;
377 if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL 375 if ((pp = get_property(dp, "linebytes", &len)) != NULL
378 && len == sizeof(int)) 376 && len == sizeof(int))
379 fb_fix.line_length = *pp; 377 fb_fix.line_length = *pp;
380 else 378 else
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 98baecccb3fd..61a8bf159cb0 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -17,7 +17,6 @@
17 * - Blanking 8bpp displays with VIDC 17 * - Blanking 8bpp displays with VIDC
18 */ 18 */
19 19
20#include <linux/config.h>
21#include <linux/module.h> 20#include <linux/module.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/errno.h> 22#include <linux/errno.h>
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 3033c72dea20..f1ba54f4fc39 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -45,10 +45,8 @@
45#include <linux/errno.h> 45#include <linux/errno.h>
46#include <linux/string.h> 46#include <linux/string.h>
47#include <linux/mm.h> 47#include <linux/mm.h>
48#include <linux/tty.h>
49#include <linux/slab.h> 48#include <linux/slab.h>
50#include <linux/delay.h> 49#include <linux/delay.h>
51#include <linux/config.h>
52#include <linux/interrupt.h> 50#include <linux/interrupt.h>
53#include <linux/fb.h> 51#include <linux/fb.h>
54#include <linux/init.h> 52#include <linux/init.h>
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 466042808daf..70dd8115a4d8 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -39,7 +39,6 @@
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <linux/string.h> 40#include <linux/string.h>
41#include <linux/mm.h> 41#include <linux/mm.h>
42#include <linux/tty.h>
43#include <linux/slab.h> 42#include <linux/slab.h>
44#include <linux/vmalloc.h> 43#include <linux/vmalloc.h>
45#include <linux/delay.h> 44#include <linux/delay.h>
@@ -561,7 +560,7 @@ static int __init arcfb_probe(struct platform_device *dev)
561 platform_set_drvdata(dev, info); 560 platform_set_drvdata(dev, info);
562 if (irq) { 561 if (irq) {
563 par->irq = irq; 562 par->irq = irq;
564 if (request_irq(par->irq, &arcfb_interrupt, SA_SHIRQ, 563 if (request_irq(par->irq, &arcfb_interrupt, IRQF_SHARED,
565 "arcfb", info)) { 564 "arcfb", info)) {
566 printk(KERN_INFO 565 printk(KERN_INFO
567 "arcfb: Failed req IRQ %d\n", par->irq); 566 "arcfb: Failed req IRQ %d\n", par->irq);
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index 29f9f0dfe3b4..1fd22f460b0f 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -29,13 +29,11 @@
29 * more details. 29 * more details.
30 */ 30 */
31 31
32#include <linux/config.h>
33#include <linux/module.h> 32#include <linux/module.h>
34#include <linux/kernel.h> 33#include <linux/kernel.h>
35#include <linux/errno.h> 34#include <linux/errno.h>
36#include <linux/string.h> 35#include <linux/string.h>
37#include <linux/mm.h> 36#include <linux/mm.h>
38#include <linux/tty.h>
39#include <linux/slab.h> 37#include <linux/slab.h>
40#include <linux/vmalloc.h> 38#include <linux/vmalloc.h>
41#include <linux/delay.h> 39#include <linux/delay.h>
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index e69ab65f7843..5831893bf7a0 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -53,7 +53,6 @@
53#include <linux/errno.h> 53#include <linux/errno.h>
54#include <linux/string.h> 54#include <linux/string.h>
55#include <linux/mm.h> 55#include <linux/mm.h>
56#include <linux/tty.h>
57#include <linux/slab.h> 56#include <linux/slab.h>
58#include <linux/delay.h> 57#include <linux/delay.h>
59#include <linux/init.h> 58#include <linux/init.h>
diff --git a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile
index 18521397a6e3..a6cc0e9ec790 100644
--- a/drivers/video/aty/Makefile
+++ b/drivers/video/aty/Makefile
@@ -10,5 +10,6 @@ atyfb-objs := $(atyfb-y)
10 10
11radeonfb-y := radeon_base.o radeon_pm.o radeon_monitor.o radeon_accel.o 11radeonfb-y := radeon_base.o radeon_pm.o radeon_monitor.o radeon_accel.o
12radeonfb-$(CONFIG_FB_RADEON_I2C) += radeon_i2c.o 12radeonfb-$(CONFIG_FB_RADEON_I2C) += radeon_i2c.o
13radeonfb-$(CONFIG_FB_RADEON_BACKLIGHT) += radeon_backlight.o
13radeonfb-objs := $(radeonfb-y) 14radeonfb-objs := $(radeonfb-y)
14 15
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index f7bbff4ddc6a..276a21530b95 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -46,14 +46,12 @@
46 */ 46 */
47 47
48 48
49#include <linux/config.h>
50#include <linux/module.h> 49#include <linux/module.h>
51#include <linux/moduleparam.h> 50#include <linux/moduleparam.h>
52#include <linux/kernel.h> 51#include <linux/kernel.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
54#include <linux/string.h> 53#include <linux/string.h>
55#include <linux/mm.h> 54#include <linux/mm.h>
56#include <linux/tty.h>
57#include <linux/slab.h> 55#include <linux/slab.h>
58#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
59#include <linux/delay.h> 57#include <linux/delay.h>
@@ -64,6 +62,7 @@
64#include <linux/pci.h> 62#include <linux/pci.h>
65#include <linux/ioport.h> 63#include <linux/ioport.h>
66#include <linux/console.h> 64#include <linux/console.h>
65#include <linux/backlight.h>
67#include <asm/io.h> 66#include <asm/io.h>
68 67
69#ifdef CONFIG_PPC_PMAC 68#ifdef CONFIG_PPC_PMAC
@@ -99,7 +98,7 @@
99 98
100#ifndef CONFIG_PPC_PMAC 99#ifndef CONFIG_PPC_PMAC
101/* default mode */ 100/* default mode */
102static struct fb_var_screeninfo default_var __initdata = { 101static struct fb_var_screeninfo default_var __devinitdata = {
103 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 102 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
104 640, 480, 640, 480, 0, 0, 8, 0, 103 640, 480, 640, 480, 0, 0, 8, 0,
105 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 104 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
@@ -122,7 +121,7 @@ static struct fb_var_screeninfo default_var = {
122 121
123/* default modedb mode */ 122/* default modedb mode */
124/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */ 123/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
125static struct fb_videomode defaultmode __initdata = { 124static struct fb_videomode defaultmode __devinitdata = {
126 .refresh = 60, 125 .refresh = 60,
127 .xres = 640, 126 .xres = 640,
128 .yres = 480, 127 .yres = 480,
@@ -334,7 +333,7 @@ static const struct aty128_meminfo sdr_sgram =
334static const struct aty128_meminfo ddr_sgram = 333static const struct aty128_meminfo ddr_sgram =
335 { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" }; 334 { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
336 335
337static struct fb_fix_screeninfo aty128fb_fix __initdata = { 336static struct fb_fix_screeninfo aty128fb_fix __devinitdata = {
338 .id = "ATY Rage128", 337 .id = "ATY Rage128",
339 .type = FB_TYPE_PACKED_PIXELS, 338 .type = FB_TYPE_PACKED_PIXELS,
340 .visual = FB_VISUAL_PSEUDOCOLOR, 339 .visual = FB_VISUAL_PSEUDOCOLOR,
@@ -344,15 +343,15 @@ static struct fb_fix_screeninfo aty128fb_fix __initdata = {
344 .accel = FB_ACCEL_ATI_RAGE128, 343 .accel = FB_ACCEL_ATI_RAGE128,
345}; 344};
346 345
347static char *mode_option __initdata = NULL; 346static char *mode_option __devinitdata = NULL;
348 347
349#ifdef CONFIG_PPC_PMAC 348#ifdef CONFIG_PPC_PMAC
350static int default_vmode __initdata = VMODE_1024_768_60; 349static int default_vmode __devinitdata = VMODE_1024_768_60;
351static int default_cmode __initdata = CMODE_8; 350static int default_cmode __devinitdata = CMODE_8;
352#endif 351#endif
353 352
354static int default_crt_on __initdata = 0; 353static int default_crt_on __devinitdata = 0;
355static int default_lcd_on __initdata = 1; 354static int default_lcd_on __devinitdata = 1;
356 355
357#ifdef CONFIG_MTRR 356#ifdef CONFIG_MTRR
358static int mtrr = 1; 357static int mtrr = 1;
@@ -444,9 +443,9 @@ static int aty128_encode_var(struct fb_var_screeninfo *var,
444static int aty128_decode_var(struct fb_var_screeninfo *var, 443static int aty128_decode_var(struct fb_var_screeninfo *var,
445 struct aty128fb_par *par); 444 struct aty128fb_par *par);
446#if 0 445#if 0
447static void __init aty128_get_pllinfo(struct aty128fb_par *par, 446static void __devinit aty128_get_pllinfo(struct aty128fb_par *par,
448 void __iomem *bios); 447 void __iomem *bios);
449static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); 448static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par);
450#endif 449#endif
451static void aty128_timings(struct aty128fb_par *par); 450static void aty128_timings(struct aty128fb_par *par);
452static void aty128_init_engine(struct aty128fb_par *par); 451static void aty128_init_engine(struct aty128fb_par *par);
@@ -457,6 +456,10 @@ static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
457static void wait_for_idle(struct aty128fb_par *par); 456static void wait_for_idle(struct aty128fb_par *par);
458static u32 depth_to_dst(u32 depth); 457static u32 depth_to_dst(u32 depth);
459 458
459#ifdef CONFIG_FB_ATY128_BACKLIGHT
460static void aty128_bl_set_power(struct fb_info *info, int power);
461#endif
462
460#define BIOS_IN8(v) (readb(bios + (v))) 463#define BIOS_IN8(v) (readb(bios + (v)))
461#define BIOS_IN16(v) (readb(bios + (v)) | \ 464#define BIOS_IN16(v) (readb(bios + (v)) | \
462 (readb(bios + (v) + 1) << 8)) 465 (readb(bios + (v) + 1) << 8))
@@ -480,16 +483,6 @@ static struct fb_ops aty128fb_ops = {
480 .fb_imageblit = cfb_imageblit, 483 .fb_imageblit = cfb_imageblit,
481}; 484};
482 485
483#ifdef CONFIG_PMAC_BACKLIGHT
484static int aty128_set_backlight_enable(int on, int level, void* data);
485static int aty128_set_backlight_level(int level, void* data);
486
487static struct backlight_controller aty128_backlight_controller = {
488 aty128_set_backlight_enable,
489 aty128_set_backlight_level
490};
491#endif /* CONFIG_PMAC_BACKLIGHT */
492
493 /* 486 /*
494 * Functions to read from/write to the mmio registers 487 * Functions to read from/write to the mmio registers
495 * - endian conversions may possibly be avoided by 488 * - endian conversions may possibly be avoided by
@@ -582,7 +575,7 @@ static void aty_pll_writeupdate(const struct aty128fb_par *par)
582 575
583 576
584/* write to the scratch register to test r/w functionality */ 577/* write to the scratch register to test r/w functionality */
585static int __init register_test(const struct aty128fb_par *par) 578static int __devinit register_test(const struct aty128fb_par *par)
586{ 579{
587 u32 val; 580 u32 val;
588 int flag = 0; 581 int flag = 0;
@@ -781,7 +774,7 @@ static u32 depth_to_dst(u32 depth)
781 774
782 775
783#ifndef __sparc__ 776#ifndef __sparc__
784static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) 777static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev)
785{ 778{
786 u16 dptr; 779 u16 dptr;
787 u8 rom_type; 780 u8 rom_type;
@@ -865,7 +858,7 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru
865 return NULL; 858 return NULL;
866} 859}
867 860
868static void __init aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) 861static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios)
869{ 862{
870 unsigned int bios_hdr; 863 unsigned int bios_hdr;
871 unsigned int bios_pll; 864 unsigned int bios_pll;
@@ -912,7 +905,7 @@ static void __iomem * __devinit aty128_find_mem_vbios(struct aty128fb_par *par)
912#endif /* ndef(__sparc__) */ 905#endif /* ndef(__sparc__) */
913 906
914/* fill in known card constants if pll_block is not available */ 907/* fill in known card constants if pll_block is not available */
915static void __init aty128_timings(struct aty128fb_par *par) 908static void __devinit aty128_timings(struct aty128fb_par *par)
916{ 909{
917#ifdef CONFIG_PPC_OF 910#ifdef CONFIG_PPC_OF
918 /* instead of a table lookup, assume OF has properly 911 /* instead of a table lookup, assume OF has properly
@@ -1258,19 +1251,21 @@ static void aty128_set_crt_enable(struct aty128fb_par *par, int on)
1258static void aty128_set_lcd_enable(struct aty128fb_par *par, int on) 1251static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
1259{ 1252{
1260 u32 reg; 1253 u32 reg;
1254#ifdef CONFIG_FB_ATY128_BACKLIGHT
1255 struct fb_info *info = pci_get_drvdata(par->pdev);
1256#endif
1261 1257
1262 if (on) { 1258 if (on) {
1263 reg = aty_ld_le32(LVDS_GEN_CNTL); 1259 reg = aty_ld_le32(LVDS_GEN_CNTL);
1264 reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION; 1260 reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION;
1265 reg &= ~LVDS_DISPLAY_DIS; 1261 reg &= ~LVDS_DISPLAY_DIS;
1266 aty_st_le32(LVDS_GEN_CNTL, reg); 1262 aty_st_le32(LVDS_GEN_CNTL, reg);
1267#ifdef CONFIG_PMAC_BACKLIGHT 1263#ifdef CONFIG_FB_ATY128_BACKLIGHT
1268 aty128_set_backlight_enable(get_backlight_enable(), 1264 aty128_bl_set_power(info, FB_BLANK_UNBLANK);
1269 get_backlight_level(), par);
1270#endif 1265#endif
1271 } else { 1266 } else {
1272#ifdef CONFIG_PMAC_BACKLIGHT 1267#ifdef CONFIG_FB_ATY128_BACKLIGHT
1273 aty128_set_backlight_enable(0, 0, par); 1268 aty128_bl_set_power(info, FB_BLANK_POWERDOWN);
1274#endif 1269#endif
1275 reg = aty_ld_le32(LVDS_GEN_CNTL); 1270 reg = aty_ld_le32(LVDS_GEN_CNTL);
1276 reg |= LVDS_DISPLAY_DIS; 1271 reg |= LVDS_DISPLAY_DIS;
@@ -1638,7 +1633,7 @@ static int aty128fb_sync(struct fb_info *info)
1638} 1633}
1639 1634
1640#ifndef MODULE 1635#ifndef MODULE
1641static int __init aty128fb_setup(char *options) 1636static int __devinit aty128fb_setup(char *options)
1642{ 1637{
1643 char *this_opt; 1638 char *this_opt;
1644 1639
@@ -1691,6 +1686,211 @@ static int __init aty128fb_setup(char *options)
1691} 1686}
1692#endif /* MODULE */ 1687#endif /* MODULE */
1693 1688
1689/* Backlight */
1690#ifdef CONFIG_FB_ATY128_BACKLIGHT
1691#define MAX_LEVEL 0xFF
1692
1693static struct backlight_properties aty128_bl_data;
1694
1695/* Call with fb_info->bl_mutex held */
1696static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
1697 int level)
1698{
1699 struct fb_info *info = pci_get_drvdata(par->pdev);
1700 int atylevel;
1701
1702 /* Get and convert the value */
1703 atylevel = MAX_LEVEL -
1704 (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
1705
1706 if (atylevel < 0)
1707 atylevel = 0;
1708 else if (atylevel > MAX_LEVEL)
1709 atylevel = MAX_LEVEL;
1710
1711 return atylevel;
1712}
1713
1714/* We turn off the LCD completely instead of just dimming the backlight.
1715 * This provides greater power saving and the display is useless without
1716 * backlight anyway
1717 */
1718#define BACKLIGHT_LVDS_OFF
1719/* That one prevents proper CRT output with LCD off */
1720#undef BACKLIGHT_DAC_OFF
1721
1722/* Call with fb_info->bl_mutex held */
1723static int __aty128_bl_update_status(struct backlight_device *bd)
1724{
1725 struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
1726 unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
1727 int level;
1728
1729 if (bd->props->power != FB_BLANK_UNBLANK ||
1730 bd->props->fb_blank != FB_BLANK_UNBLANK ||
1731 !par->lcd_on)
1732 level = 0;
1733 else
1734 level = bd->props->brightness;
1735
1736 reg |= LVDS_BL_MOD_EN | LVDS_BLON;
1737 if (level > 0) {
1738 reg |= LVDS_DIGION;
1739 if (!(reg & LVDS_ON)) {
1740 reg &= ~LVDS_BLON;
1741 aty_st_le32(LVDS_GEN_CNTL, reg);
1742 aty_ld_le32(LVDS_GEN_CNTL);
1743 mdelay(10);
1744 reg |= LVDS_BLON;
1745 aty_st_le32(LVDS_GEN_CNTL, reg);
1746 }
1747 reg &= ~LVDS_BL_MOD_LEVEL_MASK;
1748 reg |= (aty128_bl_get_level_brightness(par, level) << LVDS_BL_MOD_LEVEL_SHIFT);
1749#ifdef BACKLIGHT_LVDS_OFF
1750 reg |= LVDS_ON | LVDS_EN;
1751 reg &= ~LVDS_DISPLAY_DIS;
1752#endif
1753 aty_st_le32(LVDS_GEN_CNTL, reg);
1754#ifdef BACKLIGHT_DAC_OFF
1755 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));
1756#endif
1757 } else {
1758 reg &= ~LVDS_BL_MOD_LEVEL_MASK;
1759 reg |= (aty128_bl_get_level_brightness(par, 0) << LVDS_BL_MOD_LEVEL_SHIFT);
1760#ifdef BACKLIGHT_LVDS_OFF
1761 reg |= LVDS_DISPLAY_DIS;
1762 aty_st_le32(LVDS_GEN_CNTL, reg);
1763 aty_ld_le32(LVDS_GEN_CNTL);
1764 udelay(10);
1765 reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);
1766#endif
1767 aty_st_le32(LVDS_GEN_CNTL, reg);
1768#ifdef BACKLIGHT_DAC_OFF
1769 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);
1770#endif
1771 }
1772
1773 return 0;
1774}
1775
1776static int aty128_bl_update_status(struct backlight_device *bd)
1777{
1778 struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
1779 struct fb_info *info = pci_get_drvdata(par->pdev);
1780 int ret;
1781
1782 mutex_lock(&info->bl_mutex);
1783 ret = __aty128_bl_update_status(bd);
1784 mutex_unlock(&info->bl_mutex);
1785
1786 return ret;
1787}
1788
1789static int aty128_bl_get_brightness(struct backlight_device *bd)
1790{
1791 return bd->props->brightness;
1792}
1793
1794static struct backlight_properties aty128_bl_data = {
1795 .owner = THIS_MODULE,
1796 .get_brightness = aty128_bl_get_brightness,
1797 .update_status = aty128_bl_update_status,
1798 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
1799};
1800
1801static void aty128_bl_set_power(struct fb_info *info, int power)
1802{
1803 mutex_lock(&info->bl_mutex);
1804
1805 if (info->bl_dev) {
1806 down(&info->bl_dev->sem);
1807 info->bl_dev->props->power = power;
1808 __aty128_bl_update_status(info->bl_dev);
1809 up(&info->bl_dev->sem);
1810 }
1811
1812 mutex_unlock(&info->bl_mutex);
1813}
1814
1815static void aty128_bl_init(struct aty128fb_par *par)
1816{
1817 struct fb_info *info = pci_get_drvdata(par->pdev);
1818 struct backlight_device *bd;
1819 char name[12];
1820
1821 /* Could be extended to Rage128Pro LVDS output too */
1822 if (par->chip_gen != rage_M3)
1823 return;
1824
1825#ifdef CONFIG_PMAC_BACKLIGHT
1826 if (!pmac_has_backlight_type("ati"))
1827 return;
1828#endif
1829
1830 snprintf(name, sizeof(name), "aty128bl%d", info->node);
1831
1832 bd = backlight_device_register(name, par, &aty128_bl_data);
1833 if (IS_ERR(bd)) {
1834 info->bl_dev = NULL;
1835 printk(KERN_WARNING "aty128: Backlight registration failed\n");
1836 goto error;
1837 }
1838
1839 mutex_lock(&info->bl_mutex);
1840 info->bl_dev = bd;
1841 fb_bl_default_curve(info, 0,
1842 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
1843 219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
1844 mutex_unlock(&info->bl_mutex);
1845
1846 down(&bd->sem);
1847 bd->props->brightness = aty128_bl_data.max_brightness;
1848 bd->props->power = FB_BLANK_UNBLANK;
1849 bd->props->update_status(bd);
1850 up(&bd->sem);
1851
1852#ifdef CONFIG_PMAC_BACKLIGHT
1853 mutex_lock(&pmac_backlight_mutex);
1854 if (!pmac_backlight)
1855 pmac_backlight = bd;
1856 mutex_unlock(&pmac_backlight_mutex);
1857#endif
1858
1859 printk("aty128: Backlight initialized (%s)\n", name);
1860
1861 return;
1862
1863error:
1864 return;
1865}
1866
1867static void aty128_bl_exit(struct aty128fb_par *par)
1868{
1869 struct fb_info *info = pci_get_drvdata(par->pdev);
1870
1871#ifdef CONFIG_PMAC_BACKLIGHT
1872 mutex_lock(&pmac_backlight_mutex);
1873#endif
1874
1875 mutex_lock(&info->bl_mutex);
1876 if (info->bl_dev) {
1877#ifdef CONFIG_PMAC_BACKLIGHT
1878 if (pmac_backlight == info->bl_dev)
1879 pmac_backlight = NULL;
1880#endif
1881
1882 backlight_device_unregister(info->bl_dev);
1883 info->bl_dev = NULL;
1884
1885 printk("aty128: Backlight unloaded\n");
1886 }
1887 mutex_unlock(&info->bl_mutex);
1888
1889#ifdef CONFIG_PMAC_BACKLIGHT
1890 mutex_unlock(&pmac_backlight_mutex);
1891#endif
1892}
1893#endif /* CONFIG_FB_ATY128_BACKLIGHT */
1694 1894
1695/* 1895/*
1696 * Initialisation 1896 * Initialisation
@@ -1708,7 +1908,7 @@ static void aty128_early_resume(void *data)
1708} 1908}
1709#endif /* CONFIG_PPC_PMAC */ 1909#endif /* CONFIG_PPC_PMAC */
1710 1910
1711static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) 1911static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
1712{ 1912{
1713 struct fb_info *info = pci_get_drvdata(pdev); 1913 struct fb_info *info = pci_get_drvdata(pdev);
1714 struct aty128fb_par *par = info->par; 1914 struct aty128fb_par *par = info->par;
@@ -1717,9 +1917,6 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *
1717 u8 chip_rev; 1917 u8 chip_rev;
1718 u32 dac; 1918 u32 dac;
1719 1919
1720 if (!par->vram_size) /* may have already been probed */
1721 par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
1722
1723 /* Get the chip revision */ 1920 /* Get the chip revision */
1724 chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F; 1921 chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
1725 1922
@@ -1832,20 +2029,18 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *
1832 2029
1833 aty128_init_engine(par); 2030 aty128_init_engine(par);
1834 2031
1835 if (register_framebuffer(info) < 0)
1836 return 0;
1837
1838#ifdef CONFIG_PMAC_BACKLIGHT
1839 /* Could be extended to Rage128Pro LVDS output too */
1840 if (par->chip_gen == rage_M3)
1841 register_backlight_controller(&aty128_backlight_controller, par, "ati");
1842#endif /* CONFIG_PMAC_BACKLIGHT */
1843
1844 par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); 2032 par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
1845 par->pdev = pdev; 2033 par->pdev = pdev;
1846 par->asleep = 0; 2034 par->asleep = 0;
1847 par->lock_blank = 0; 2035 par->lock_blank = 0;
1848 2036
2037#ifdef CONFIG_FB_ATY128_BACKLIGHT
2038 aty128_bl_init(par);
2039#endif
2040
2041 if (register_framebuffer(info) < 0)
2042 return 0;
2043
1849 printk(KERN_INFO "fb%d: %s frame buffer device on %s\n", 2044 printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
1850 info->node, info->fix.id, video_card); 2045 info->node, info->fix.id, video_card);
1851 2046
@@ -1854,7 +2049,7 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *
1854 2049
1855#ifdef CONFIG_PCI 2050#ifdef CONFIG_PCI
1856/* register a card ++ajoshi */ 2051/* register a card ++ajoshi */
1857static int __init aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 2052static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1858{ 2053{
1859 unsigned long fb_addr, reg_addr; 2054 unsigned long fb_addr, reg_addr;
1860 struct aty128fb_par *par; 2055 struct aty128fb_par *par;
@@ -1895,7 +2090,6 @@ static int __init aty128_probe(struct pci_dev *pdev, const struct pci_device_id
1895 par = info->par; 2090 par = info->par;
1896 2091
1897 info->pseudo_palette = par->pseudo_palette; 2092 info->pseudo_palette = par->pseudo_palette;
1898 info->fix = aty128fb_fix;
1899 2093
1900 /* Virtualize mmio region */ 2094 /* Virtualize mmio region */
1901 info->fix.mmio_start = reg_addr; 2095 info->fix.mmio_start = reg_addr;
@@ -1981,6 +2175,10 @@ static void __devexit aty128_remove(struct pci_dev *pdev)
1981 2175
1982 par = info->par; 2176 par = info->par;
1983 2177
2178#ifdef CONFIG_FB_ATY128_BACKLIGHT
2179 aty128_bl_exit(par);
2180#endif
2181
1984 unregister_framebuffer(info); 2182 unregister_framebuffer(info);
1985#ifdef CONFIG_MTRR 2183#ifdef CONFIG_MTRR
1986 if (par->mtrr.vram_valid) 2184 if (par->mtrr.vram_valid)
@@ -2011,10 +2209,10 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2011 if (par->lock_blank || par->asleep) 2209 if (par->lock_blank || par->asleep)
2012 return 0; 2210 return 0;
2013 2211
2014#ifdef CONFIG_PMAC_BACKLIGHT 2212#ifdef CONFIG_FB_ATY128_BACKLIGHT
2015 if (machine_is(powermac) && blank) 2213 if (machine_is(powermac) && blank)
2016 set_backlight_enable(0); 2214 aty128_bl_set_power(fb, FB_BLANK_POWERDOWN);
2017#endif /* CONFIG_PMAC_BACKLIGHT */ 2215#endif
2018 2216
2019 if (blank & FB_BLANK_VSYNC_SUSPEND) 2217 if (blank & FB_BLANK_VSYNC_SUSPEND)
2020 state |= 2; 2218 state |= 2;
@@ -2029,10 +2227,12 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2029 aty128_set_crt_enable(par, par->crt_on && !blank); 2227 aty128_set_crt_enable(par, par->crt_on && !blank);
2030 aty128_set_lcd_enable(par, par->lcd_on && !blank); 2228 aty128_set_lcd_enable(par, par->lcd_on && !blank);
2031 } 2229 }
2032#ifdef CONFIG_PMAC_BACKLIGHT 2230
2231#ifdef CONFIG_FB_ATY128_BACKLIGHT
2033 if (machine_is(powermac) && !blank) 2232 if (machine_is(powermac) && !blank)
2034 set_backlight_enable(1); 2233 aty128_bl_set_power(fb, FB_BLANK_UNBLANK);
2035#endif /* CONFIG_PMAC_BACKLIGHT */ 2234#endif
2235
2036 return 0; 2236 return 0;
2037} 2237}
2038 2238
@@ -2138,73 +2338,6 @@ static int aty128fb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
2138 return -EINVAL; 2338 return -EINVAL;
2139} 2339}
2140 2340
2141#ifdef CONFIG_PMAC_BACKLIGHT
2142static int backlight_conv[] = {
2143 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
2144 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
2145};
2146
2147/* We turn off the LCD completely instead of just dimming the backlight.
2148 * This provides greater power saving and the display is useless without
2149 * backlight anyway
2150 */
2151#define BACKLIGHT_LVDS_OFF
2152/* That one prevents proper CRT output with LCD off */
2153#undef BACKLIGHT_DAC_OFF
2154
2155static int aty128_set_backlight_enable(int on, int level, void *data)
2156{
2157 struct aty128fb_par *par = data;
2158 unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
2159
2160 if (!par->lcd_on)
2161 on = 0;
2162 reg |= LVDS_BL_MOD_EN | LVDS_BLON;
2163 if (on && level > BACKLIGHT_OFF) {
2164 reg |= LVDS_DIGION;
2165 if (!(reg & LVDS_ON)) {
2166 reg &= ~LVDS_BLON;
2167 aty_st_le32(LVDS_GEN_CNTL, reg);
2168 (void)aty_ld_le32(LVDS_GEN_CNTL);
2169 mdelay(10);
2170 reg |= LVDS_BLON;
2171 aty_st_le32(LVDS_GEN_CNTL, reg);
2172 }
2173 reg &= ~LVDS_BL_MOD_LEVEL_MASK;
2174 reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);
2175#ifdef BACKLIGHT_LVDS_OFF
2176 reg |= LVDS_ON | LVDS_EN;
2177 reg &= ~LVDS_DISPLAY_DIS;
2178#endif
2179 aty_st_le32(LVDS_GEN_CNTL, reg);
2180#ifdef BACKLIGHT_DAC_OFF
2181 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));
2182#endif
2183 } else {
2184 reg &= ~LVDS_BL_MOD_LEVEL_MASK;
2185 reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);
2186#ifdef BACKLIGHT_LVDS_OFF
2187 reg |= LVDS_DISPLAY_DIS;
2188 aty_st_le32(LVDS_GEN_CNTL, reg);
2189 (void)aty_ld_le32(LVDS_GEN_CNTL);
2190 udelay(10);
2191 reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);
2192#endif
2193 aty_st_le32(LVDS_GEN_CNTL, reg);
2194#ifdef BACKLIGHT_DAC_OFF
2195 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);
2196#endif
2197 }
2198
2199 return 0;
2200}
2201
2202static int aty128_set_backlight_level(int level, void* data)
2203{
2204 return aty128_set_backlight_enable(1, level, data);
2205}
2206#endif /* CONFIG_PMAC_BACKLIGHT */
2207
2208#if 0 2341#if 0
2209 /* 2342 /*
2210 * Accelerated functions 2343 * Accelerated functions
@@ -2428,7 +2561,7 @@ static int aty128_pci_resume(struct pci_dev *pdev)
2428} 2561}
2429 2562
2430 2563
2431static int __init aty128fb_init(void) 2564static int __devinit aty128fb_init(void)
2432{ 2565{
2433#ifndef MODULE 2566#ifndef MODULE
2434 char *option = NULL; 2567 char *option = NULL;
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index e9b7a64c1ac4..55fb8b04489b 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -2,7 +2,6 @@
2 * ATI Frame Buffer Device Driver Core Definitions 2 * ATI Frame Buffer Device Driver Core Definitions
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <linux/spinlock.h> 5#include <linux/spinlock.h>
7#include <linux/wait.h> 6#include <linux/wait.h>
8 /* 7 /*
@@ -151,6 +150,7 @@ struct atyfb_par {
151 int lock_blank; 150 int lock_blank;
152 unsigned long res_start; 151 unsigned long res_start;
153 unsigned long res_size; 152 unsigned long res_size;
153 struct pci_dev *pdev;
154#ifdef __sparc__ 154#ifdef __sparc__
155 struct pci_mmap_map *mmap_map; 155 struct pci_mmap_map *mmap_map;
156 u8 mmaped; 156 u8 mmaped;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index eb6aa42be60e..19a71f045784 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -49,7 +49,6 @@
49******************************************************************************/ 49******************************************************************************/
50 50
51 51
52#include <linux/config.h>
53#include <linux/module.h> 52#include <linux/module.h>
54#include <linux/moduleparam.h> 53#include <linux/moduleparam.h>
55#include <linux/kernel.h> 54#include <linux/kernel.h>
@@ -66,6 +65,7 @@
66#include <linux/interrupt.h> 65#include <linux/interrupt.h>
67#include <linux/spinlock.h> 66#include <linux/spinlock.h>
68#include <linux/wait.h> 67#include <linux/wait.h>
68#include <linux/backlight.h>
69 69
70#include <asm/io.h> 70#include <asm/io.h>
71#include <asm/uaccess.h> 71#include <asm/uaccess.h>
@@ -315,12 +315,12 @@ static int vram;
315static int pll; 315static int pll;
316static int mclk; 316static int mclk;
317static int xclk; 317static int xclk;
318static int comp_sync __initdata = -1; 318static int comp_sync __devinitdata = -1;
319static char *mode; 319static char *mode;
320 320
321#ifdef CONFIG_PPC 321#ifdef CONFIG_PPC
322static int default_vmode __initdata = VMODE_CHOOSE; 322static int default_vmode __devinitdata = VMODE_CHOOSE;
323static int default_cmode __initdata = CMODE_CHOOSE; 323static int default_cmode __devinitdata = CMODE_CHOOSE;
324 324
325module_param_named(vmode, default_vmode, int, 0); 325module_param_named(vmode, default_vmode, int, 0);
326MODULE_PARM_DESC(vmode, "int: video mode for mac"); 326MODULE_PARM_DESC(vmode, "int: video mode for mac");
@@ -329,10 +329,10 @@ MODULE_PARM_DESC(cmode, "int: color mode for mac");
329#endif 329#endif
330 330
331#ifdef CONFIG_ATARI 331#ifdef CONFIG_ATARI
332static unsigned int mach64_count __initdata = 0; 332static unsigned int mach64_count __devinitdata = 0;
333static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, }; 333static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, };
334static unsigned long phys_size[FB_MAX] __initdata = { 0, }; 334static unsigned long phys_size[FB_MAX] __devinitdata = { 0, };
335static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; 335static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };
336#endif 336#endif
337 337
338/* top -> down is an evolution of mach64 chipset, any corrections? */ 338/* top -> down is an evolution of mach64 chipset, any corrections? */
@@ -582,7 +582,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p
582 * Apple monitor sense 582 * Apple monitor sense
583 */ 583 */
584 584
585static int __init read_aty_sense(const struct atyfb_par *par) 585static int __devinit read_aty_sense(const struct atyfb_par *par)
586{ 586{
587 int sense, i; 587 int sense, i;
588 588
@@ -1280,6 +1280,14 @@ static int atyfb_set_par(struct fb_info *info)
1280 1280
1281 par->accel_flags = var->accel_flags; /* hack */ 1281 par->accel_flags = var->accel_flags; /* hack */
1282 1282
1283 if (var->accel_flags) {
1284 info->fbops->fb_sync = atyfb_sync;
1285 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1286 } else {
1287 info->fbops->fb_sync = NULL;
1288 info->flags |= FBINFO_HWACCEL_DISABLED;
1289 }
1290
1283 if (par->blitter_may_be_busy) 1291 if (par->blitter_may_be_busy)
1284 wait_for_idle(par); 1292 wait_for_idle(par);
1285 1293
@@ -1559,7 +1567,7 @@ static int aty_enable_irq(struct atyfb_par *par, int reenable)
1559 u32 int_cntl; 1567 u32 int_cntl;
1560 1568
1561 if (!test_and_set_bit(0, &par->irq_flags)) { 1569 if (!test_and_set_bit(0, &par->irq_flags)) {
1562 if (request_irq(par->irq, aty_irq, SA_SHIRQ, "atyfb", par)) { 1570 if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) {
1563 clear_bit(0, &par->irq_flags); 1571 clear_bit(0, &par->irq_flags);
1564 return -EINVAL; 1572 return -EINVAL;
1565 } 1573 }
@@ -2115,47 +2123,171 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
2115 2123
2116#endif /* defined(CONFIG_PM) && defined(CONFIG_PCI) */ 2124#endif /* defined(CONFIG_PM) && defined(CONFIG_PCI) */
2117 2125
2118#ifdef CONFIG_PMAC_BACKLIGHT 2126/* Backlight */
2127#ifdef CONFIG_FB_ATY_BACKLIGHT
2128#define MAX_LEVEL 0xFF
2119 2129
2120 /* 2130static struct backlight_properties aty_bl_data;
2121 * LCD backlight control
2122 */
2123 2131
2124static int backlight_conv[] = { 2132/* Call with fb_info->bl_mutex held */
2125 0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d, 2133static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2126 0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff 2134{
2127}; 2135 struct fb_info *info = pci_get_drvdata(par->pdev);
2136 int atylevel;
2137
2138 /* Get and convert the value */
2139 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2140
2141 if (atylevel < 0)
2142 atylevel = 0;
2143 else if (atylevel > MAX_LEVEL)
2144 atylevel = MAX_LEVEL;
2128 2145
2129static int aty_set_backlight_enable(int on, int level, void *data) 2146 return atylevel;
2147}
2148
2149/* Call with fb_info->bl_mutex held */
2150static int __aty_bl_update_status(struct backlight_device *bd)
2130{ 2151{
2131 struct fb_info *info = (struct fb_info *) data; 2152 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2132 struct atyfb_par *par = (struct atyfb_par *) info->par;
2133 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); 2153 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2154 int level;
2155
2156 if (bd->props->power != FB_BLANK_UNBLANK ||
2157 bd->props->fb_blank != FB_BLANK_UNBLANK)
2158 level = 0;
2159 else
2160 level = bd->props->brightness;
2134 2161
2135 reg |= (BLMOD_EN | BIASMOD_EN); 2162 reg |= (BLMOD_EN | BIASMOD_EN);
2136 if (on && level > BACKLIGHT_OFF) { 2163 if (level > 0) {
2137 reg &= ~BIAS_MOD_LEVEL_MASK; 2164 reg &= ~BIAS_MOD_LEVEL_MASK;
2138 reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT); 2165 reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT);
2139 } else { 2166 } else {
2140 reg &= ~BIAS_MOD_LEVEL_MASK; 2167 reg &= ~BIAS_MOD_LEVEL_MASK;
2141 reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT); 2168 reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT);
2142 } 2169 }
2143 aty_st_lcd(LCD_MISC_CNTL, reg, par); 2170 aty_st_lcd(LCD_MISC_CNTL, reg, par);
2171
2144 return 0; 2172 return 0;
2145} 2173}
2146 2174
2147static int aty_set_backlight_level(int level, void *data) 2175static int aty_bl_update_status(struct backlight_device *bd)
2148{ 2176{
2149 return aty_set_backlight_enable(1, level, data); 2177 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2178 struct fb_info *info = pci_get_drvdata(par->pdev);
2179 int ret;
2180
2181 mutex_lock(&info->bl_mutex);
2182 ret = __aty_bl_update_status(bd);
2183 mutex_unlock(&info->bl_mutex);
2184
2185 return ret;
2150} 2186}
2151 2187
2152static struct backlight_controller aty_backlight_controller = { 2188static int aty_bl_get_brightness(struct backlight_device *bd)
2153 aty_set_backlight_enable, 2189{
2154 aty_set_backlight_level 2190 return bd->props->brightness;
2191}
2192
2193static struct backlight_properties aty_bl_data = {
2194 .owner = THIS_MODULE,
2195 .get_brightness = aty_bl_get_brightness,
2196 .update_status = aty_bl_update_status,
2197 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
2155}; 2198};
2156#endif /* CONFIG_PMAC_BACKLIGHT */
2157 2199
2158static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) 2200static void aty_bl_set_power(struct fb_info *info, int power)
2201{
2202 mutex_lock(&info->bl_mutex);
2203
2204 if (info->bl_dev) {
2205 down(&info->bl_dev->sem);
2206 info->bl_dev->props->power = power;
2207 __aty_bl_update_status(info->bl_dev);
2208 up(&info->bl_dev->sem);
2209 }
2210
2211 mutex_unlock(&info->bl_mutex);
2212}
2213
2214static void aty_bl_init(struct atyfb_par *par)
2215{
2216 struct fb_info *info = pci_get_drvdata(par->pdev);
2217 struct backlight_device *bd;
2218 char name[12];
2219
2220#ifdef CONFIG_PMAC_BACKLIGHT
2221 if (!pmac_has_backlight_type("ati"))
2222 return;
2223#endif
2224
2225 snprintf(name, sizeof(name), "atybl%d", info->node);
2226
2227 bd = backlight_device_register(name, par, &aty_bl_data);
2228 if (IS_ERR(bd)) {
2229 info->bl_dev = NULL;
2230 printk(KERN_WARNING "aty: Backlight registration failed\n");
2231 goto error;
2232 }
2233
2234 mutex_lock(&info->bl_mutex);
2235 info->bl_dev = bd;
2236 fb_bl_default_curve(info, 0,
2237 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2238 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2239 mutex_unlock(&info->bl_mutex);
2240
2241 down(&bd->sem);
2242 bd->props->brightness = aty_bl_data.max_brightness;
2243 bd->props->power = FB_BLANK_UNBLANK;
2244 bd->props->update_status(bd);
2245 up(&bd->sem);
2246
2247#ifdef CONFIG_PMAC_BACKLIGHT
2248 mutex_lock(&pmac_backlight_mutex);
2249 if (!pmac_backlight)
2250 pmac_backlight = bd;
2251 mutex_unlock(&pmac_backlight_mutex);
2252#endif
2253
2254 printk("aty: Backlight initialized (%s)\n", name);
2255
2256 return;
2257
2258error:
2259 return;
2260}
2261
2262static void aty_bl_exit(struct atyfb_par *par)
2263{
2264 struct fb_info *info = pci_get_drvdata(par->pdev);
2265
2266#ifdef CONFIG_PMAC_BACKLIGHT
2267 mutex_lock(&pmac_backlight_mutex);
2268#endif
2269
2270 mutex_lock(&info->bl_mutex);
2271 if (info->bl_dev) {
2272#ifdef CONFIG_PMAC_BACKLIGHT
2273 if (pmac_backlight == info->bl_dev)
2274 pmac_backlight = NULL;
2275#endif
2276
2277 backlight_device_unregister(info->bl_dev);
2278
2279 printk("aty: Backlight unloaded\n");
2280 }
2281 mutex_unlock(&info->bl_mutex);
2282
2283#ifdef CONFIG_PMAC_BACKLIGHT
2284 mutex_unlock(&pmac_backlight_mutex);
2285#endif
2286}
2287
2288#endif /* CONFIG_FB_ATY_BACKLIGHT */
2289
2290static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2159{ 2291{
2160 const int ragepro_tbl[] = { 2292 const int ragepro_tbl[] = {
2161 44, 50, 55, 66, 75, 80, 100 2293 44, 50, 55, 66, 75, 80, 100
@@ -2215,7 +2347,7 @@ static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
2215} 2347}
2216#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ 2348#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2217 2349
2218static int __init aty_init(struct fb_info *info, const char *name) 2350static int __devinit aty_init(struct fb_info *info, const char *name)
2219{ 2351{
2220 struct atyfb_par *par = (struct atyfb_par *) info->par; 2352 struct atyfb_par *par = (struct atyfb_par *) info->par;
2221 const char *ramname = NULL, *xtal; 2353 const char *ramname = NULL, *xtal;
@@ -2296,12 +2428,15 @@ static int __init aty_init(struct fb_info *info, const char *name)
2296 break; 2428 break;
2297 } 2429 }
2298 switch (clk_type) { 2430 switch (clk_type) {
2431#ifdef CONFIG_ATARI
2299 case CLK_ATI18818_1: 2432 case CLK_ATI18818_1:
2300 par->pll_ops = &aty_pll_ati18818_1; 2433 par->pll_ops = &aty_pll_ati18818_1;
2301 break; 2434 break;
2435#else
2302 case CLK_IBMRGB514: 2436 case CLK_IBMRGB514:
2303 par->pll_ops = &aty_pll_ibm514; 2437 par->pll_ops = &aty_pll_ibm514;
2304 break; 2438 break;
2439#endif
2305#if 0 /* dead code */ 2440#if 0 /* dead code */
2306 case CLK_STG1703: 2441 case CLK_STG1703:
2307 par->pll_ops = &aty_pll_stg1703; 2442 par->pll_ops = &aty_pll_stg1703;
@@ -2506,16 +2641,24 @@ static int __init aty_init(struct fb_info *info, const char *name)
2506 2641
2507 info->fbops = &atyfb_ops; 2642 info->fbops = &atyfb_ops;
2508 info->pseudo_palette = pseudo_palette; 2643 info->pseudo_palette = pseudo_palette;
2509 info->flags = FBINFO_FLAG_DEFAULT; 2644 info->flags = FBINFO_DEFAULT |
2645 FBINFO_HWACCEL_IMAGEBLIT |
2646 FBINFO_HWACCEL_FILLRECT |
2647 FBINFO_HWACCEL_COPYAREA |
2648 FBINFO_HWACCEL_YPAN;
2510 2649
2511#ifdef CONFIG_PMAC_BACKLIGHT 2650#ifdef CONFIG_PMAC_BACKLIGHT
2512 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { 2651 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2513 /* these bits let the 101 powerbook wake up from sleep -- paulus */ 2652 /* these bits let the 101 powerbook wake up from sleep -- paulus */
2514 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) 2653 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par)
2515 | (USE_F32KHZ | TRISTATE_MEM_EN), par); 2654 | (USE_F32KHZ | TRISTATE_MEM_EN), par);
2516 } else if (M64_HAS(MOBIL_BUS)) 2655 } else
2517 register_backlight_controller(&aty_backlight_controller, info, "ati"); 2656#endif
2518#endif /* CONFIG_PMAC_BACKLIGHT */ 2657 if (M64_HAS(MOBIL_BUS)) {
2658#ifdef CONFIG_FB_ATY_BACKLIGHT
2659 aty_bl_init (par);
2660#endif
2661 }
2519 2662
2520 memset(&var, 0, sizeof(var)); 2663 memset(&var, 0, sizeof(var));
2521#ifdef CONFIG_PPC 2664#ifdef CONFIG_PPC
@@ -2631,7 +2774,7 @@ aty_init_exit:
2631} 2774}
2632 2775
2633#ifdef CONFIG_ATARI 2776#ifdef CONFIG_ATARI
2634static int __init store_video_par(char *video_str, unsigned char m64_num) 2777static int __devinit store_video_par(char *video_str, unsigned char m64_num)
2635{ 2778{
2636 char *p; 2779 char *p;
2637 unsigned long vmembase, size, guiregbase; 2780 unsigned long vmembase, size, guiregbase;
@@ -2673,9 +2816,9 @@ static int atyfb_blank(int blank, struct fb_info *info)
2673 if (par->lock_blank || par->asleep) 2816 if (par->lock_blank || par->asleep)
2674 return 0; 2817 return 0;
2675 2818
2676#ifdef CONFIG_PMAC_BACKLIGHT 2819#ifdef CONFIG_FB_ATY_BACKLIGHT
2677 if (machine_is(powermac) && blank > FB_BLANK_NORMAL) 2820 if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
2678 set_backlight_enable(0); 2821 aty_bl_set_power(info, FB_BLANK_POWERDOWN);
2679#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2822#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2680 if (par->lcd_table && blank > FB_BLANK_NORMAL && 2823 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2681 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2824 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
@@ -2705,9 +2848,9 @@ static int atyfb_blank(int blank, struct fb_info *info)
2705 } 2848 }
2706 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2849 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2707 2850
2708#ifdef CONFIG_PMAC_BACKLIGHT 2851#ifdef CONFIG_FB_ATY_BACKLIGHT
2709 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) 2852 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
2710 set_backlight_enable(1); 2853 aty_bl_set_power(info, FB_BLANK_UNBLANK);
2711#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2854#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2712 if (par->lcd_table && blank <= FB_BLANK_NORMAL && 2855 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2713 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2856 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
@@ -2966,7 +3109,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2966 } 3109 }
2967 3110
2968 pcp = pdev->sysdata; 3111 pcp = pdev->sysdata;
2969 if (node == pcp->prom_node) { 3112 if (node == pcp->prom_node->node) {
2970 struct fb_var_screeninfo *var = &default_var; 3113 struct fb_var_screeninfo *var = &default_var;
2971 unsigned int N, P, Q, M, T, R; 3114 unsigned int N, P, Q, M, T, R;
2972 u32 v_total, h_total; 3115 u32 v_total, h_total;
@@ -3440,6 +3583,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
3440 par->res_start = res_start; 3583 par->res_start = res_start;
3441 par->res_size = res_size; 3584 par->res_size = res_size;
3442 par->irq = pdev->irq; 3585 par->irq = pdev->irq;
3586 par->pdev = pdev;
3443 3587
3444 /* Setup "info" structure */ 3588 /* Setup "info" structure */
3445#ifdef __sparc__ 3589#ifdef __sparc__
@@ -3571,6 +3715,11 @@ static void __devexit atyfb_remove(struct fb_info *info)
3571 aty_set_crtc(par, &saved_crtc); 3715 aty_set_crtc(par, &saved_crtc);
3572 par->pll_ops->set_pll(info, &saved_pll); 3716 par->pll_ops->set_pll(info, &saved_pll);
3573 3717
3718#ifdef CONFIG_FB_ATY_BACKLIGHT
3719 if (M64_HAS(MOBIL_BUS))
3720 aty_bl_exit(par);
3721#endif
3722
3574 unregister_framebuffer(info); 3723 unregister_framebuffer(info);
3575 3724
3576#ifdef CONFIG_MTRR 3725#ifdef CONFIG_MTRR
@@ -3640,7 +3789,7 @@ static struct pci_driver atyfb_driver = {
3640#endif /* CONFIG_PCI */ 3789#endif /* CONFIG_PCI */
3641 3790
3642#ifndef MODULE 3791#ifndef MODULE
3643static int __init atyfb_setup(char *options) 3792static int __devinit atyfb_setup(char *options)
3644{ 3793{
3645 char *this_opt; 3794 char *this_opt;
3646 3795
@@ -3712,7 +3861,7 @@ static int __init atyfb_setup(char *options)
3712} 3861}
3713#endif /* MODULE */ 3862#endif /* MODULE */
3714 3863
3715static int __init atyfb_init(void) 3864static int __devinit atyfb_init(void)
3716{ 3865{
3717#ifndef MODULE 3866#ifndef MODULE
3718 char *option = NULL; 3867 char *option = NULL;
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
index c98f4a442134..1490e5e1c232 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/aty/mach64_accel.c
@@ -200,8 +200,6 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
200 if (!area->width || !area->height) 200 if (!area->width || !area->height)
201 return; 201 return;
202 if (!par->accel_flags) { 202 if (!par->accel_flags) {
203 if (par->blitter_may_be_busy)
204 wait_for_idle(par);
205 cfb_copyarea(info, area); 203 cfb_copyarea(info, area);
206 return; 204 return;
207 } 205 }
@@ -248,8 +246,6 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
248 if (!rect->width || !rect->height) 246 if (!rect->width || !rect->height)
249 return; 247 return;
250 if (!par->accel_flags) { 248 if (!par->accel_flags) {
251 if (par->blitter_may_be_busy)
252 wait_for_idle(par);
253 cfb_fillrect(info, rect); 249 cfb_fillrect(info, rect);
254 return; 250 return;
255 } 251 }
@@ -288,14 +284,10 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
288 return; 284 return;
289 if (!par->accel_flags || 285 if (!par->accel_flags ||
290 (image->depth != 1 && info->var.bits_per_pixel != image->depth)) { 286 (image->depth != 1 && info->var.bits_per_pixel != image->depth)) {
291 if (par->blitter_may_be_busy)
292 wait_for_idle(par);
293
294 cfb_imageblit(info, image); 287 cfb_imageblit(info, image);
295 return; 288 return;
296 } 289 }
297 290
298 wait_for_idle(par);
299 pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par); 291 pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par);
300 host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN; 292 host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN;
301 293
@@ -425,8 +417,6 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
425 } 417 }
426 } 418 }
427 419
428 wait_for_idle(par);
429
430 /* restore pix_width */ 420 /* restore pix_width */
431 wait_for_fifo(1, par); 421 wait_for_fifo(1, par);
432 aty_st_le32(DP_PIX_WIDTH, pix_width_save, par); 422 aty_st_le32(DP_PIX_WIDTH, pix_width_save, par);
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index ad8b7496f853..2a7f381c330f 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -66,11 +66,6 @@ static const u8 cursor_bits_lookup[16] = {
66 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55 66 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
67}; 67};
68 68
69static const u8 cursor_mask_lookup[16] = {
70 0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02,
71 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
72};
73
74static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 69static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
75{ 70{
76 struct atyfb_par *par = (struct atyfb_par *) info->par; 71 struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -130,13 +125,13 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
130 fg_idx = cursor->image.fg_color; 125 fg_idx = cursor->image.fg_color;
131 bg_idx = cursor->image.bg_color; 126 bg_idx = cursor->image.bg_color;
132 127
133 fg = (info->cmap.red[fg_idx] << 24) | 128 fg = ((info->cmap.red[fg_idx] & 0xff) << 24) |
134 (info->cmap.green[fg_idx] << 16) | 129 ((info->cmap.green[fg_idx] & 0xff) << 16) |
135 (info->cmap.blue[fg_idx] << 8) | 15; 130 ((info->cmap.blue[fg_idx] & 0xff) << 8) | 0xff;
136 131
137 bg = (info->cmap.red[bg_idx] << 24) | 132 bg = ((info->cmap.red[bg_idx] & 0xff) << 24) |
138 (info->cmap.green[bg_idx] << 16) | 133 ((info->cmap.green[bg_idx] & 0xff) << 16) |
139 (info->cmap.blue[bg_idx] << 8); 134 ((info->cmap.blue[bg_idx] & 0xff) << 8);
140 135
141 wait_for_fifo(2, par); 136 wait_for_fifo(2, par);
142 aty_st_le32(CUR_CLR0, bg, par); 137 aty_st_le32(CUR_CLR0, bg, par);
@@ -166,19 +161,17 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
166 switch (cursor->rop) { 161 switch (cursor->rop) {
167 case ROP_XOR: 162 case ROP_XOR:
168 // Upper 4 bits of mask data 163 // Upper 4 bits of mask data
169 fb_writeb(cursor_mask_lookup[m >> 4 ] | 164 fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++);
170 cursor_bits_lookup[(b ^ m) >> 4], dst++);
171 // Lower 4 bits of mask 165 // Lower 4 bits of mask
172 fb_writeb(cursor_mask_lookup[m & 0x0f ] | 166 fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f],
173 cursor_bits_lookup[(b ^ m) & 0x0f], dst++); 167 dst++);
174 break; 168 break;
175 case ROP_COPY: 169 case ROP_COPY:
176 // Upper 4 bits of mask data 170 // Upper 4 bits of mask data
177 fb_writeb(cursor_mask_lookup[m >> 4 ] | 171 fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++);
178 cursor_bits_lookup[(b & m) >> 4], dst++);
179 // Lower 4 bits of mask 172 // Lower 4 bits of mask
180 fb_writeb(cursor_mask_lookup[m & 0x0f ] | 173 fb_writeb(cursor_bits_lookup[(b & m) & 0x0f],
181 cursor_bits_lookup[(b & m) & 0x0f], dst++); 174 dst++);
182 break; 175 break;
183 } 176 }
184 } 177 }
@@ -194,7 +187,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
194 return 0; 187 return 0;
195} 188}
196 189
197int __init aty_init_cursor(struct fb_info *info) 190int __devinit aty_init_cursor(struct fb_info *info)
198{ 191{
199 unsigned long addr; 192 unsigned long addr;
200 193
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
new file mode 100644
index 000000000000..585eb7b9e636
--- /dev/null
+++ b/drivers/video/aty/radeon_backlight.c
@@ -0,0 +1,247 @@
1/*
2 * Backlight code for ATI Radeon based graphic cards
3 *
4 * Copyright (c) 2000 Ani Joshi <ajoshi@kernel.crashing.org>
5 * Copyright (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
6 * Copyright (c) 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include "radeonfb.h"
14#include <linux/backlight.h>
15
16#ifdef CONFIG_PMAC_BACKLIGHT
17#include <asm/backlight.h>
18#endif
19
20#define MAX_RADEON_LEVEL 0xFF
21
22static struct backlight_properties radeon_bl_data;
23
24struct radeon_bl_privdata {
25 struct radeonfb_info *rinfo;
26 uint8_t negative;
27};
28
29static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata,
30 int level)
31{
32 struct fb_info *info = pdata->rinfo->info;
33 int rlevel;
34
35 mutex_lock(&info->bl_mutex);
36
37 /* Get and convert the value */
38 rlevel = pdata->rinfo->info->bl_curve[level] *
39 FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL;
40
41 mutex_unlock(&info->bl_mutex);
42
43 if (rlevel < 0)
44 rlevel = 0;
45 else if (rlevel > MAX_RADEON_LEVEL)
46 rlevel = MAX_RADEON_LEVEL;
47
48 if (pdata->negative)
49 rlevel = MAX_RADEON_LEVEL - rlevel;
50
51 return rlevel;
52}
53
54static int radeon_bl_update_status(struct backlight_device *bd)
55{
56 struct radeon_bl_privdata *pdata = class_get_devdata(&bd->class_dev);
57 struct radeonfb_info *rinfo = pdata->rinfo;
58 u32 lvds_gen_cntl, tmpPixclksCntl;
59 int level;
60
61 if (rinfo->mon1_type != MT_LCD)
62 return 0;
63
64 /* We turn off the LCD completely instead of just dimming the
65 * backlight. This provides some greater power saving and the display
66 * is useless without backlight anyway.
67 */
68 if (bd->props->power != FB_BLANK_UNBLANK ||
69 bd->props->fb_blank != FB_BLANK_UNBLANK)
70 level = 0;
71 else
72 level = bd->props->brightness;
73
74 del_timer_sync(&rinfo->lvds_timer);
75 radeon_engine_idle();
76
77 lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
78 if (level > 0) {
79 lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
80 if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) {
81 lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON);
82 lvds_gen_cntl |= LVDS_BLON | LVDS_EN;
83 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
84 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
85 lvds_gen_cntl |=
86 (radeon_bl_get_level_brightness(pdata, level) <<
87 LVDS_BL_MOD_LEVEL_SHIFT);
88 lvds_gen_cntl |= LVDS_ON;
89 lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN);
90 rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
91 mod_timer(&rinfo->lvds_timer,
92 jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
93 } else {
94 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
95 lvds_gen_cntl |=
96 (radeon_bl_get_level_brightness(pdata, level) <<
97 LVDS_BL_MOD_LEVEL_SHIFT);
98 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
99 }
100 rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
101 rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl
102 & LVDS_STATE_MASK;
103 } else {
104 /* Asic bug, when turning off LVDS_ON, we have to make sure
105 RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
106 */
107 tmpPixclksCntl = INPLL(PIXCLKS_CNTL);
108 if (rinfo->is_mobility || rinfo->is_IGP)
109 OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
110 lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN);
111 lvds_gen_cntl |= (radeon_bl_get_level_brightness(pdata, 0) <<
112 LVDS_BL_MOD_LEVEL_SHIFT);
113 lvds_gen_cntl |= LVDS_DISPLAY_DIS;
114 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
115 udelay(100);
116 lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN);
117 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
118 lvds_gen_cntl &= ~(LVDS_DIGON);
119 rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
120 mod_timer(&rinfo->lvds_timer,
121 jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
122 if (rinfo->is_mobility || rinfo->is_IGP)
123 OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl);
124 }
125 rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
126 rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
127
128 return 0;
129}
130
131static int radeon_bl_get_brightness(struct backlight_device *bd)
132{
133 return bd->props->brightness;
134}
135
136static struct backlight_properties radeon_bl_data = {
137 .owner = THIS_MODULE,
138 .get_brightness = radeon_bl_get_brightness,
139 .update_status = radeon_bl_update_status,
140 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
141};
142
143void radeonfb_bl_init(struct radeonfb_info *rinfo)
144{
145 struct backlight_device *bd;
146 struct radeon_bl_privdata *pdata;
147 char name[12];
148
149 if (rinfo->mon1_type != MT_LCD)
150 return;
151
152#ifdef CONFIG_PMAC_BACKLIGHT
153 if (!pmac_has_backlight_type("ati") &&
154 !pmac_has_backlight_type("mnca"))
155 return;
156#endif
157
158 pdata = kmalloc(sizeof(struct radeon_bl_privdata), GFP_KERNEL);
159 if (!pdata) {
160 printk("radeonfb: Memory allocation failed\n");
161 goto error;
162 }
163
164 snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
165
166 bd = backlight_device_register(name, pdata, &radeon_bl_data);
167 if (IS_ERR(bd)) {
168 rinfo->info->bl_dev = NULL;
169 printk("radeonfb: Backlight registration failed\n");
170 goto error;
171 }
172
173 pdata->rinfo = rinfo;
174
175 /* Pardon me for that hack... maybe some day we can figure out in what
176 * direction backlight should work on a given panel?
177 */
178 pdata->negative =
179 (rinfo->family != CHIP_FAMILY_RV200 &&
180 rinfo->family != CHIP_FAMILY_RV250 &&
181 rinfo->family != CHIP_FAMILY_RV280 &&
182 rinfo->family != CHIP_FAMILY_RV350);
183
184#ifdef CONFIG_PMAC_BACKLIGHT
185 pdata->negative = pdata->negative ||
186 machine_is_compatible("PowerBook4,3") ||
187 machine_is_compatible("PowerBook6,3") ||
188 machine_is_compatible("PowerBook6,5");
189#endif
190
191 mutex_lock(&rinfo->info->bl_mutex);
192 rinfo->info->bl_dev = bd;
193 fb_bl_default_curve(rinfo->info, 0,
194 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
195 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
196 mutex_unlock(&rinfo->info->bl_mutex);
197
198 down(&bd->sem);
199 bd->props->brightness = radeon_bl_data.max_brightness;
200 bd->props->power = FB_BLANK_UNBLANK;
201 bd->props->update_status(bd);
202 up(&bd->sem);
203
204#ifdef CONFIG_PMAC_BACKLIGHT
205 mutex_lock(&pmac_backlight_mutex);
206 if (!pmac_backlight)
207 pmac_backlight = bd;
208 mutex_unlock(&pmac_backlight_mutex);
209#endif
210
211 printk("radeonfb: Backlight initialized (%s)\n", name);
212
213 return;
214
215error:
216 kfree(pdata);
217 return;
218}
219
220void radeonfb_bl_exit(struct radeonfb_info *rinfo)
221{
222#ifdef CONFIG_PMAC_BACKLIGHT
223 mutex_lock(&pmac_backlight_mutex);
224#endif
225
226 mutex_lock(&rinfo->info->bl_mutex);
227 if (rinfo->info->bl_dev) {
228 struct radeon_bl_privdata *pdata;
229
230#ifdef CONFIG_PMAC_BACKLIGHT
231 if (pmac_backlight == rinfo->info->bl_dev)
232 pmac_backlight = NULL;
233#endif
234
235 pdata = class_get_devdata(&rinfo->info->bl_dev->class_dev);
236 backlight_device_unregister(rinfo->info->bl_dev);
237 kfree(pdata);
238 rinfo->info->bl_dev = NULL;
239
240 printk("radeonfb: Backlight unloaded\n");
241 }
242 mutex_unlock(&rinfo->info->bl_mutex);
243
244#ifdef CONFIG_PMAC_BACKLIGHT
245 mutex_unlock(&pmac_backlight_mutex);
246#endif
247}
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 387a18a47ac2..0ed577e7cc21 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -52,14 +52,12 @@
52 52
53#define RADEON_VERSION "0.2.0" 53#define RADEON_VERSION "0.2.0"
54 54
55#include <linux/config.h>
56#include <linux/module.h> 55#include <linux/module.h>
57#include <linux/moduleparam.h> 56#include <linux/moduleparam.h>
58#include <linux/kernel.h> 57#include <linux/kernel.h>
59#include <linux/errno.h> 58#include <linux/errno.h>
60#include <linux/string.h> 59#include <linux/string.h>
61#include <linux/mm.h> 60#include <linux/mm.h>
62#include <linux/tty.h>
63#include <linux/slab.h> 61#include <linux/slab.h>
64#include <linux/delay.h> 62#include <linux/delay.h>
65#include <linux/time.h> 63#include <linux/time.h>
@@ -78,10 +76,6 @@
78#include <asm/pci-bridge.h> 76#include <asm/pci-bridge.h>
79#include "../macmodes.h" 77#include "../macmodes.h"
80 78
81#ifdef CONFIG_PMAC_BACKLIGHT
82#include <asm/backlight.h>
83#endif
84
85#ifdef CONFIG_BOOTX_TEXT 79#ifdef CONFIG_BOOTX_TEXT
86#include <asm/btext.h> 80#include <asm/btext.h>
87#endif 81#endif
@@ -272,25 +266,13 @@ static int force_measure_pll = 0;
272#ifdef CONFIG_MTRR 266#ifdef CONFIG_MTRR
273static int nomtrr = 0; 267static int nomtrr = 0;
274#endif 268#endif
269static int force_sleep;
270static int ignore_devlist;
275 271
276/* 272/*
277 * prototypes 273 * prototypes
278 */ 274 */
279 275
280
281#ifdef CONFIG_PPC_OF
282
283#ifdef CONFIG_PMAC_BACKLIGHT
284static int radeon_set_backlight_enable(int on, int level, void *data);
285static int radeon_set_backlight_level(int level, void *data);
286static struct backlight_controller radeon_backlight_controller = {
287 radeon_set_backlight_enable,
288 radeon_set_backlight_level
289};
290#endif /* CONFIG_PMAC_BACKLIGHT */
291
292#endif /* CONFIG_PPC_OF */
293
294static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) 276static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
295{ 277{
296 if (!rinfo->bios_seg) 278 if (!rinfo->bios_seg)
@@ -431,11 +413,11 @@ static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo)
431static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo) 413static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
432{ 414{
433 struct device_node *dp = rinfo->of_node; 415 struct device_node *dp = rinfo->of_node;
434 u32 *val; 416 const u32 *val;
435 417
436 if (dp == NULL) 418 if (dp == NULL)
437 return -ENODEV; 419 return -ENODEV;
438 val = (u32 *) get_property(dp, "ATY,RefCLK", NULL); 420 val = get_property(dp, "ATY,RefCLK", NULL);
439 if (!val || !*val) { 421 if (!val || !*val) {
440 printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n"); 422 printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n");
441 return -EINVAL; 423 return -EINVAL;
@@ -443,11 +425,11 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
443 425
444 rinfo->pll.ref_clk = (*val) / 10; 426 rinfo->pll.ref_clk = (*val) / 10;
445 427
446 val = (u32 *) get_property(dp, "ATY,SCLK", NULL); 428 val = get_property(dp, "ATY,SCLK", NULL);
447 if (val && *val) 429 if (val && *val)
448 rinfo->pll.sclk = (*val) / 10; 430 rinfo->pll.sclk = (*val) / 10;
449 431
450 val = (u32 *) get_property(dp, "ATY,MCLK", NULL); 432 val = get_property(dp, "ATY,MCLK", NULL);
451 if (val && *val) 433 if (val && *val)
452 rinfo->pll.mclk = (*val) / 10; 434 rinfo->pll.mclk = (*val) / 10;
453 435
@@ -1913,116 +1895,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
1913 return 0; 1895 return 0;
1914} 1896}
1915 1897
1916
1917#ifdef CONFIG_PMAC_BACKLIGHT
1918
1919/* TODO: Dbl check these tables, we don't go up to full ON backlight
1920 * in these, possibly because we noticed MacOS doesn't, but I'd prefer
1921 * having some more official numbers from ATI
1922 */
1923static int backlight_conv_m6[] = {
1924 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
1925 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
1926};
1927static int backlight_conv_m7[] = {
1928 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
1929 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
1930};
1931
1932#define BACKLIGHT_LVDS_OFF
1933#undef BACKLIGHT_DAC_OFF
1934
1935/* We turn off the LCD completely instead of just dimming the backlight.
1936 * This provides some greater power saving and the display is useless
1937 * without backlight anyway.
1938 */
1939static int radeon_set_backlight_enable(int on, int level, void *data)
1940{
1941 struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
1942 u32 lvds_gen_cntl, tmpPixclksCntl;
1943 int* conv_table;
1944
1945 if (rinfo->mon1_type != MT_LCD)
1946 return 0;
1947
1948 /* Pardon me for that hack... maybe some day we can figure
1949 * out in what direction backlight should work on a given
1950 * panel ?
1951 */
1952 if ((rinfo->family == CHIP_FAMILY_RV200 ||
1953 rinfo->family == CHIP_FAMILY_RV250 ||
1954 rinfo->family == CHIP_FAMILY_RV280 ||
1955 rinfo->family == CHIP_FAMILY_RV350) &&
1956 !machine_is_compatible("PowerBook4,3") &&
1957 !machine_is_compatible("PowerBook6,3") &&
1958 !machine_is_compatible("PowerBook6,5"))
1959 conv_table = backlight_conv_m7;
1960 else
1961 conv_table = backlight_conv_m6;
1962
1963 del_timer_sync(&rinfo->lvds_timer);
1964 radeon_engine_idle();
1965
1966 lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
1967 if (on && (level > BACKLIGHT_OFF)) {
1968 lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
1969 if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) {
1970 lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON);
1971 lvds_gen_cntl |= LVDS_BLON | LVDS_EN;
1972 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
1973 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
1974 lvds_gen_cntl |= (conv_table[level] <<
1975 LVDS_BL_MOD_LEVEL_SHIFT);
1976 lvds_gen_cntl |= LVDS_ON;
1977 lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN);
1978 rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
1979 mod_timer(&rinfo->lvds_timer,
1980 jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
1981 } else {
1982 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
1983 lvds_gen_cntl |= (conv_table[level] <<
1984 LVDS_BL_MOD_LEVEL_SHIFT);
1985 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
1986 }
1987 rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
1988 rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl
1989 & LVDS_STATE_MASK;
1990 } else {
1991 /* Asic bug, when turning off LVDS_ON, we have to make sure
1992 RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
1993 */
1994 tmpPixclksCntl = INPLL(PIXCLKS_CNTL);
1995 if (rinfo->is_mobility || rinfo->is_IGP)
1996 OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
1997 lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN);
1998 lvds_gen_cntl |= (conv_table[0] <<
1999 LVDS_BL_MOD_LEVEL_SHIFT);
2000 lvds_gen_cntl |= LVDS_DISPLAY_DIS;
2001 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2002 udelay(100);
2003 lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN);
2004 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2005 lvds_gen_cntl &= ~(LVDS_DIGON);
2006 rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
2007 mod_timer(&rinfo->lvds_timer,
2008 jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
2009 if (rinfo->is_mobility || rinfo->is_IGP)
2010 OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl);
2011 }
2012 rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
2013 rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
2014
2015 return 0;
2016}
2017
2018
2019static int radeon_set_backlight_level(int level, void *data)
2020{
2021 return radeon_set_backlight_enable(1, level, data);
2022}
2023#endif /* CONFIG_PMAC_BACKLIGHT */
2024
2025
2026/* 1898/*
2027 * This reconfigure the card's internal memory map. In theory, we'd like 1899 * This reconfigure the card's internal memory map. In theory, we'd like
2028 * to setup the card's memory at the same address as it's PCI bus address, 1900 * to setup the card's memory at the same address as it's PCI bus address,
@@ -2457,9 +2329,9 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
2457 /* -2 is special: means ON on mobility chips and do not 2329 /* -2 is special: means ON on mobility chips and do not
2458 * change on others 2330 * change on others
2459 */ 2331 */
2460 radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1); 2332 radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep);
2461 } else 2333 } else
2462 radeonfb_pm_init(rinfo, default_dynclk); 2334 radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep);
2463 2335
2464 pci_set_drvdata(pdev, info); 2336 pci_set_drvdata(pdev, info);
2465 2337
@@ -2477,14 +2349,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
2477 MTRR_TYPE_WRCOMB, 1); 2349 MTRR_TYPE_WRCOMB, 1);
2478#endif 2350#endif
2479 2351
2480#ifdef CONFIG_PMAC_BACKLIGHT 2352 radeonfb_bl_init(rinfo);
2481 if (rinfo->mon1_type == MT_LCD) {
2482 register_backlight_controller(&radeon_backlight_controller,
2483 rinfo, "ati");
2484 register_backlight_controller(&radeon_backlight_controller,
2485 rinfo, "mnca");
2486 }
2487#endif
2488 2353
2489 printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name); 2354 printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name);
2490 2355
@@ -2514,7 +2379,6 @@ err_release_pci0:
2514err_release_fb: 2379err_release_fb:
2515 framebuffer_release(info); 2380 framebuffer_release(info);
2516err_disable: 2381err_disable:
2517 pci_disable_device(pdev);
2518err_out: 2382err_out:
2519 return ret; 2383 return ret;
2520} 2384}
@@ -2528,7 +2392,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
2528 2392
2529 if (!rinfo) 2393 if (!rinfo)
2530 return; 2394 return;
2531 2395
2396 radeonfb_bl_exit(rinfo);
2532 radeonfb_pm_exit(rinfo); 2397 radeonfb_pm_exit(rinfo);
2533 2398
2534 if (rinfo->mon1_EDID) 2399 if (rinfo->mon1_EDID)
@@ -2570,7 +2435,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
2570#endif 2435#endif
2571 fb_dealloc_cmap(&info->cmap); 2436 fb_dealloc_cmap(&info->cmap);
2572 framebuffer_release(info); 2437 framebuffer_release(info);
2573 pci_disable_device(pdev);
2574} 2438}
2575 2439
2576 2440
@@ -2615,6 +2479,12 @@ static int __init radeonfb_setup (char *options)
2615 force_measure_pll = 1; 2479 force_measure_pll = 1;
2616 } else if (!strncmp(this_opt, "ignore_edid", 11)) { 2480 } else if (!strncmp(this_opt, "ignore_edid", 11)) {
2617 ignore_edid = 1; 2481 ignore_edid = 1;
2482#if defined(CONFIG_PM) && defined(CONFIG_X86)
2483 } else if (!strncmp(this_opt, "force_sleep", 11)) {
2484 force_sleep = 1;
2485 } else if (!strncmp(this_opt, "ignore_devlist", 14)) {
2486 ignore_devlist = 1;
2487#endif
2618 } else 2488 } else
2619 mode_option = this_opt; 2489 mode_option = this_opt;
2620 } 2490 }
@@ -2670,3 +2540,9 @@ module_param(panel_yres, int, 0);
2670MODULE_PARM_DESC(panel_yres, "int: set panel yres"); 2540MODULE_PARM_DESC(panel_yres, "int: set panel yres");
2671module_param(mode_option, charp, 0); 2541module_param(mode_option, charp, 0);
2672MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); 2542MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
2543#if defined(CONFIG_PM) && defined(CONFIG_X86)
2544module_param(force_sleep, bool, 0);
2545MODULE_PARM_DESC(force_sleep, "bool: force D2 sleep mode on all hardware");
2546module_param(ignore_devlist, bool, 0);
2547MODULE_PARM_DESC(ignore_devlist, "bool: ignore workarounds for bugs in specific laptops");
2548#endif
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index a9d0414e4655..9aaca58c074a 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -1,4 +1,3 @@
1#include <linux/config.h>
2#include <linux/module.h> 1#include <linux/module.h>
3#include <linux/kernel.h> 2#include <linux/kernel.h>
4#include <linux/sched.h> 3#include <linux/sched.h>
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index 98c05bc0de44..ea531a6f45d1 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -64,13 +64,13 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
64{ 64{
65 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", 65 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
66 "EDID1", "EDID2", NULL }; 66 "EDID1", "EDID2", NULL };
67 u8 *pedid = NULL; 67 const u8 *pedid = NULL;
68 u8 *pmt = NULL; 68 const u8 *pmt = NULL;
69 u8 *tmp; 69 u8 *tmp;
70 int i, mt = MT_NONE; 70 int i, mt = MT_NONE;
71 71
72 RTRACE("analyzing OF properties...\n"); 72 RTRACE("analyzing OF properties...\n");
73 pmt = (u8 *)get_property(dp, "display-type", NULL); 73 pmt = get_property(dp, "display-type", NULL);
74 if (!pmt) 74 if (!pmt)
75 return MT_NONE; 75 return MT_NONE;
76 RTRACE("display-type: %s\n", pmt); 76 RTRACE("display-type: %s\n", pmt);
@@ -89,7 +89,7 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
89 } 89 }
90 90
91 for (i = 0; propnames[i] != NULL; ++i) { 91 for (i = 0; propnames[i] != NULL; ++i) {
92 pedid = (u8 *)get_property(dp, propnames[i], NULL); 92 pedid = get_property(dp, propnames[i], NULL);
93 if (pedid != NULL) 93 if (pedid != NULL)
94 break; 94 break;
95 } 95 }
@@ -124,14 +124,14 @@ static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_
124 return MT_NONE; 124 return MT_NONE;
125 125
126 if (rinfo->has_CRTC2) { 126 if (rinfo->has_CRTC2) {
127 char *pname; 127 const char *pname;
128 int len, second = 0; 128 int len, second = 0;
129 129
130 dp = dp->child; 130 dp = dp->child;
131 do { 131 do {
132 if (!dp) 132 if (!dp)
133 return MT_NONE; 133 return MT_NONE;
134 pname = (char *)get_property(dp, "name", NULL); 134 pname = get_property(dp, "name", NULL);
135 if (!pname) 135 if (!pname)
136 return MT_NONE; 136 return MT_NONE;
137 len = strlen(pname); 137 len = strlen(pname);
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index c7091761cef4..365de5dcc888 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -27,6 +27,99 @@
27 27
28#include "ati_ids.h" 28#include "ati_ids.h"
29 29
30static void radeon_reinitialize_M10(struct radeonfb_info *rinfo);
31
32/*
33 * Workarounds for bugs in PC laptops:
34 * - enable D2 sleep in some IBM Thinkpads
35 * - special case for Samsung P35
36 *
37 * Whitelist by subsystem vendor/device because
38 * its the subsystem vendor's fault!
39 */
40
41#if defined(CONFIG_PM) && defined(CONFIG_X86)
42struct radeon_device_id {
43 const char *ident; /* (arbitrary) Name */
44 const unsigned short subsystem_vendor; /* Subsystem Vendor ID */
45 const unsigned short subsystem_device; /* Subsystem Device ID */
46 const enum radeon_pm_mode pm_mode_modifier; /* modify pm_mode */
47 const reinit_function_ptr new_reinit_func; /* changed reinit_func */
48};
49
50#define BUGFIX(model, sv, sd, pm, fn) { \
51 .ident = model, \
52 .subsystem_vendor = sv, \
53 .subsystem_device = sd, \
54 .pm_mode_modifier = pm, \
55 .new_reinit_func = fn \
56}
57
58static struct radeon_device_id radeon_workaround_list[] = {
59 BUGFIX("IBM Thinkpad R32",
60 PCI_VENDOR_ID_IBM, 0x1905,
61 radeon_pm_d2, NULL),
62 BUGFIX("IBM Thinkpad R40",
63 PCI_VENDOR_ID_IBM, 0x0526,
64 radeon_pm_d2, NULL),
65 BUGFIX("IBM Thinkpad R40",
66 PCI_VENDOR_ID_IBM, 0x0527,
67 radeon_pm_d2, NULL),
68 BUGFIX("IBM Thinkpad R50/R51/T40/T41",
69 PCI_VENDOR_ID_IBM, 0x0531,
70 radeon_pm_d2, NULL),
71 BUGFIX("IBM Thinkpad R51/T40/T41/T42",
72 PCI_VENDOR_ID_IBM, 0x0530,
73 radeon_pm_d2, NULL),
74 BUGFIX("IBM Thinkpad T30",
75 PCI_VENDOR_ID_IBM, 0x0517,
76 radeon_pm_d2, NULL),
77 BUGFIX("IBM Thinkpad T40p",
78 PCI_VENDOR_ID_IBM, 0x054d,
79 radeon_pm_d2, NULL),
80 BUGFIX("IBM Thinkpad T42",
81 PCI_VENDOR_ID_IBM, 0x0550,
82 radeon_pm_d2, NULL),
83 BUGFIX("IBM Thinkpad X31/X32",
84 PCI_VENDOR_ID_IBM, 0x052f,
85 radeon_pm_d2, NULL),
86 BUGFIX("Samsung P35",
87 PCI_VENDOR_ID_SAMSUNG, 0xc00c,
88 radeon_pm_off, radeon_reinitialize_M10),
89 { .ident = NULL }
90};
91
92static int radeon_apply_workarounds(struct radeonfb_info *rinfo)
93{
94 struct radeon_device_id *id;
95
96 for (id = radeon_workaround_list; id->ident != NULL; id++ )
97 if ((id->subsystem_vendor == rinfo->pdev->subsystem_vendor ) &&
98 (id->subsystem_device == rinfo->pdev->subsystem_device )) {
99
100 /* we found a device that requires workaround */
101 printk(KERN_DEBUG "radeonfb: %s detected"
102 ", enabling workaround\n", id->ident);
103
104 rinfo->pm_mode |= id->pm_mode_modifier;
105
106 if (id->new_reinit_func != NULL)
107 rinfo->reinit_func = id->new_reinit_func;
108
109 return 1;
110 }
111 return 0; /* not found */
112}
113
114#else /* defined(CONFIG_PM) && defined(CONFIG_X86) */
115static inline int radeon_apply_workarounds(struct radeonfb_info *rinfo)
116{
117 return 0;
118}
119#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */
120
121
122
30static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo) 123static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
31{ 124{
32 u32 tmp; 125 u32 tmp;
@@ -852,18 +945,26 @@ static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
852 /* because both INPLL and OUTPLL take the same lock, that's why. */ 945 /* because both INPLL and OUTPLL take the same lock, that's why. */
853 tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND; 946 tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND;
854 OUTPLL( pllMCLK_MISC, tmp); 947 OUTPLL( pllMCLK_MISC, tmp);
855
856 /* AGP PLL control */
857 if (rinfo->family <= CHIP_FAMILY_RV280) {
858 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID);
859 948
860 OUTREG(BUS_CNTL1, 949 /* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset
861 (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK) 950 * and radeon chip dependent. Thus we only enable it on Mac for
862 | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX 951 * now (until we get more info on how to compute the correct
863 } else { 952 * value for various X86 bridges).
864 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1)); 953 */
865 OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000); 954#ifdef CONFIG_PPC_PMAC
955 if (machine_is(powermac)) {
956 /* AGP PLL control */
957 if (rinfo->family <= CHIP_FAMILY_RV280) {
958 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID);
959 OUTREG(BUS_CNTL1,
960 (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
961 | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX
962 } else {
963 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1));
964 OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000);
965 }
866 } 966 }
967#endif
867 968
868 OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) 969 OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL)
869 & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN)); 970 & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
@@ -1167,7 +1268,7 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
1167 0x21320032, 0xa1320032, 0x21320032, 0xffffffff, 1268 0x21320032, 0xa1320032, 0x21320032, 0xffffffff,
1168 0x31320032 }; 1269 0x31320032 };
1169 1270
1170 u32 *mrtable = default_mrtable; 1271 const u32 *mrtable = default_mrtable;
1171 int i, mrtable_size = ARRAY_SIZE(default_mrtable); 1272 int i, mrtable_size = ARRAY_SIZE(default_mrtable);
1172 1273
1173 mdelay(30); 1274 mdelay(30);
@@ -1186,7 +1287,7 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
1186 if (rinfo->of_node != NULL) { 1287 if (rinfo->of_node != NULL) {
1187 int size; 1288 int size;
1188 1289
1189 mrtable = (u32 *)get_property(rinfo->of_node, "ATY,MRT", &size); 1290 mrtable = get_property(rinfo->of_node, "ATY,MRT", &size);
1190 if (mrtable) 1291 if (mrtable)
1191 mrtable_size = size >> 2; 1292 mrtable_size = size >> 2;
1192 else 1293 else
@@ -2520,25 +2621,28 @@ static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo)
2520} 2621}
2521 2622
2522 2623
2523int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) 2624int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
2524{ 2625{
2525 struct fb_info *info = pci_get_drvdata(pdev); 2626 struct fb_info *info = pci_get_drvdata(pdev);
2526 struct radeonfb_info *rinfo = info->par; 2627 struct radeonfb_info *rinfo = info->par;
2527 int i; 2628 int i;
2528 2629
2529 if (state.event == pdev->dev.power.power_state.event) 2630 if (mesg.event == pdev->dev.power.power_state.event)
2530 return 0; 2631 return 0;
2531 2632
2532 printk(KERN_DEBUG "radeonfb (%s): suspending to state: %d...\n", 2633 printk(KERN_DEBUG "radeonfb (%s): suspending for event: %d...\n",
2533 pci_name(pdev), state.event); 2634 pci_name(pdev), mesg.event);
2534 2635
2535 /* For suspend-to-disk, we cheat here. We don't suspend anything and 2636 /* For suspend-to-disk, we cheat here. We don't suspend anything and
2536 * let fbcon continue drawing until we are all set. That shouldn't 2637 * let fbcon continue drawing until we are all set. That shouldn't
2537 * really cause any problem at this point, provided that the wakeup 2638 * really cause any problem at this point, provided that the wakeup
2538 * code knows that any state in memory may not match the HW 2639 * code knows that any state in memory may not match the HW
2539 */ 2640 */
2540 if (state.event == PM_EVENT_FREEZE) 2641 switch (mesg.event) {
2642 case PM_EVENT_FREEZE: /* about to take snapshot */
2643 case PM_EVENT_PRETHAW: /* before restoring snapshot */
2541 goto done; 2644 goto done;
2645 }
2542 2646
2543 acquire_console_sem(); 2647 acquire_console_sem();
2544 2648
@@ -2605,7 +2709,7 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2605 release_console_sem(); 2709 release_console_sem();
2606 2710
2607 done: 2711 done:
2608 pdev->dev.power.power_state = state; 2712 pdev->dev.power.power_state = mesg;
2609 2713
2610 return 0; 2714 return 0;
2611} 2715}
@@ -2713,7 +2817,7 @@ static void radeonfb_early_resume(void *data)
2713 2817
2714#endif /* CONFIG_PM */ 2818#endif /* CONFIG_PM */
2715 2819
2716void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) 2820void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep)
2717{ 2821{
2718 /* Find PM registers in config space if any*/ 2822 /* Find PM registers in config space if any*/
2719 rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); 2823 rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
@@ -2729,22 +2833,13 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
2729 } 2833 }
2730 2834
2731#if defined(CONFIG_PM) 2835#if defined(CONFIG_PM)
2836#if defined(CONFIG_PPC_PMAC)
2732 /* Check if we can power manage on suspend/resume. We can do 2837 /* Check if we can power manage on suspend/resume. We can do
2733 * D2 on M6, M7 and M9, and we can resume from D3 cold a few other 2838 * D2 on M6, M7 and M9, and we can resume from D3 cold a few other
2734 * "Mac" cards, but that's all. We need more infos about what the 2839 * "Mac" cards, but that's all. We need more infos about what the
2735 * BIOS does tho. Right now, all this PM stuff is pmac-only for that 2840 * BIOS does tho. Right now, all this PM stuff is pmac-only for that
2736 * reason. --BenH 2841 * reason. --BenH
2737 */ 2842 */
2738 /* Special case for Samsung P35 laptops
2739 */
2740 if ((rinfo->pdev->vendor == PCI_VENDOR_ID_ATI) &&
2741 (rinfo->pdev->device == PCI_CHIP_RV350_NP) &&
2742 (rinfo->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) &&
2743 (rinfo->pdev->subsystem_device == 0xc00c)) {
2744 rinfo->reinit_func = radeon_reinitialize_M10;
2745 rinfo->pm_mode |= radeon_pm_off;
2746 }
2747#if defined(CONFIG_PPC_PMAC)
2748 if (machine_is(powermac) && rinfo->of_node) { 2843 if (machine_is(powermac) && rinfo->of_node) {
2749 if (rinfo->is_mobility && rinfo->pm_reg && 2844 if (rinfo->is_mobility && rinfo->pm_reg &&
2750 rinfo->family <= CHIP_FAMILY_RV250) 2845 rinfo->family <= CHIP_FAMILY_RV250)
@@ -2790,6 +2885,18 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
2790 } 2885 }
2791#endif /* defined(CONFIG_PPC_PMAC) */ 2886#endif /* defined(CONFIG_PPC_PMAC) */
2792#endif /* defined(CONFIG_PM) */ 2887#endif /* defined(CONFIG_PM) */
2888
2889 if (ignore_devlist)
2890 printk(KERN_DEBUG
2891 "radeonfb: skipping test for device workarounds\n");
2892 else
2893 radeon_apply_workarounds(rinfo);
2894
2895 if (force_sleep) {
2896 printk(KERN_DEBUG
2897 "radeonfb: forcefully enabling D2 sleep mode\n");
2898 rinfo->pm_mode |= radeon_pm_d2;
2899 }
2793} 2900}
2794 2901
2795void radeonfb_pm_exit(struct radeonfb_info *rinfo) 2902void radeonfb_pm_exit(struct radeonfb_info *rinfo)
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 217e00ab4a2d..d5ff224a6258 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -1,7 +1,6 @@
1#ifndef __RADEONFB_H__ 1#ifndef __RADEONFB_H__
2#define __RADEONFB_H__ 2#define __RADEONFB_H__
3 3
4#include <linux/config.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/sched.h> 6#include <linux/sched.h>
@@ -274,6 +273,8 @@ enum radeon_pm_mode {
274 radeon_pm_off = 0x00000002, /* Can resume from D3 cold */ 273 radeon_pm_off = 0x00000002, /* Can resume from D3 cold */
275}; 274};
276 275
276typedef void (*reinit_function_ptr)(struct radeonfb_info *rinfo);
277
277struct radeonfb_info { 278struct radeonfb_info {
278 struct fb_info *info; 279 struct fb_info *info;
279 280
@@ -339,7 +340,7 @@ struct radeonfb_info {
339 int dynclk; 340 int dynclk;
340 int no_schedule; 341 int no_schedule;
341 enum radeon_pm_mode pm_mode; 342 enum radeon_pm_mode pm_mode;
342 void (*reinit_func)(struct radeonfb_info *rinfo); 343 reinit_function_ptr reinit_func;
343 344
344 /* Lock on register access */ 345 /* Lock on register access */
345 spinlock_t reg_lock; 346 spinlock_t reg_lock;
@@ -382,7 +383,7 @@ struct radeonfb_info {
382/* Note about this function: we have some rare cases where we must not schedule, 383/* Note about this function: we have some rare cases where we must not schedule,
383 * this typically happen with our special "wake up early" hook which allows us to 384 * this typically happen with our special "wake up early" hook which allows us to
384 * wake up the graphic chip (and thus get the console back) before everything else 385 * wake up the graphic chip (and thus get the console back) before everything else
385 * on some machines that support that mecanism. At this point, interrupts are off 386 * on some machines that support that mechanism. At this point, interrupts are off
386 * and scheduling is not permitted 387 * and scheduling is not permitted
387 */ 388 */
388static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) 389static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
@@ -601,7 +602,7 @@ extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8
601/* PM Functions */ 602/* PM Functions */
602extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state); 603extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state);
603extern int radeonfb_pci_resume(struct pci_dev *pdev); 604extern int radeonfb_pci_resume(struct pci_dev *pdev);
604extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk); 605extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep);
605extern void radeonfb_pm_exit(struct radeonfb_info *rinfo); 606extern void radeonfb_pm_exit(struct radeonfb_info *rinfo);
606 607
607/* Monitor probe functions */ 608/* Monitor probe functions */
@@ -625,4 +626,13 @@ extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_
625extern void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, 626extern void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
626 int reg_only); 627 int reg_only);
627 628
629/* Backlight functions */
630#ifdef CONFIG_FB_RADEON_BACKLIGHT
631extern void radeonfb_bl_init(struct radeonfb_info *rinfo);
632extern void radeonfb_bl_exit(struct radeonfb_info *rinfo);
633#else
634static inline void radeonfb_bl_init(struct radeonfb_info *rinfo) {}
635static inline void radeonfb_bl_exit(struct radeonfb_info *rinfo) {}
636#endif
637
628#endif /* __RADEONFB_H__ */ 638#endif /* __RADEONFB_H__ */
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 789450bb0bc9..f25d5d648333 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -7,6 +7,8 @@
7 * Karl Lessard <klessard@sunrisetelecom.com> 7 * Karl Lessard <klessard@sunrisetelecom.com>
8 * <c.pellegrin@exadron.com> 8 * <c.pellegrin@exadron.com>
9 * 9 *
10 * PM support added by Rodolfo Giometti <giometti@linux.it>
11 *
10 * Copyright 2002 MontaVista Software 12 * Copyright 2002 MontaVista Software
11 * Author: MontaVista Software, Inc. 13 * Author: MontaVista Software, Inc.
12 * ppopov@mvista.com or source@mvista.com 14 * ppopov@mvista.com or source@mvista.com
@@ -38,7 +40,6 @@
38 * with this program; if not, write to the Free Software Foundation, Inc., 40 * with this program; if not, write to the Free Software Foundation, Inc.,
39 * 675 Mass Ave, Cambridge, MA 02139, USA. 41 * 675 Mass Ave, Cambridge, MA 02139, USA.
40 */ 42 */
41#include <linux/config.h>
42#include <linux/module.h> 43#include <linux/module.h>
43#include <linux/kernel.h> 44#include <linux/kernel.h>
44#include <linux/errno.h> 45#include <linux/errno.h>
@@ -155,7 +156,7 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
155 156
156 info->fix.visual = FB_VISUAL_TRUECOLOR; 157 info->fix.visual = FB_VISUAL_TRUECOLOR;
157 info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */ 158 info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */
158 } 159 }
159 } else { 160 } else {
160 /* mono */ 161 /* mono */
161 info->fix.visual = FB_VISUAL_MONO10; 162 info->fix.visual = FB_VISUAL_MONO10;
@@ -163,20 +164,16 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
163 } 164 }
164 165
165 info->screen_size = info->fix.line_length * info->var.yres_virtual; 166 info->screen_size = info->fix.line_length * info->var.yres_virtual;
167 info->var.rotate = ((fbdev->panel->control_base&LCD_CONTROL_SM_MASK) \
168 >> LCD_CONTROL_SM_BIT) * 90;
166 169
167 /* Determine BPP mode and format */ 170 /* Determine BPP mode and format */
168 fbdev->regs->lcd_control = fbdev->panel->control_base | 171 fbdev->regs->lcd_control = fbdev->panel->control_base;
169 ((info->var.rotate/90) << LCD_CONTROL_SM_BIT);
170
171 fbdev->regs->lcd_intenable = 0;
172 fbdev->regs->lcd_intstatus = 0;
173
174 fbdev->regs->lcd_horztiming = fbdev->panel->horztiming; 172 fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
175
176 fbdev->regs->lcd_verttiming = fbdev->panel->verttiming; 173 fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
177
178 fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base; 174 fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
179 175 fbdev->regs->lcd_intenable = 0;
176 fbdev->regs->lcd_intstatus = 0;
180 fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys); 177 fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys);
181 178
182 if (panel_is_dual(fbdev->panel)) { 179 if (panel_is_dual(fbdev->panel)) {
@@ -205,6 +202,8 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
205 202
206 /* Resume controller */ 203 /* Resume controller */
207 fbdev->regs->lcd_control |= LCD_CONTROL_GO; 204 fbdev->regs->lcd_control |= LCD_CONTROL_GO;
205 mdelay(10);
206 au1100fb_fb_blank(VESA_NO_BLANKING, info);
208 207
209 return 0; 208 return 0;
210} 209}
@@ -602,17 +601,52 @@ int au1100fb_drv_remove(struct device *dev)
602 return 0; 601 return 0;
603} 602}
604 603
604#ifdef CONFIG_PM
605static u32 sys_clksrc;
606static struct au1100fb_regs fbregs;
607
605int au1100fb_drv_suspend(struct device *dev, pm_message_t state) 608int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
606{ 609{
607 /* TODO */ 610 struct au1100fb_device *fbdev = dev_get_drvdata(dev);
611
612 if (!fbdev)
613 return 0;
614
615 /* Save the clock source state */
616 sys_clksrc = au_readl(SYS_CLKSRC);
617
618 /* Blank the LCD */
619 au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
620
621 /* Stop LCD clocking */
622 au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC);
623
624 memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs));
625
608 return 0; 626 return 0;
609} 627}
610 628
611int au1100fb_drv_resume(struct device *dev) 629int au1100fb_drv_resume(struct device *dev)
612{ 630{
613 /* TODO */ 631 struct au1100fb_device *fbdev = dev_get_drvdata(dev);
632
633 if (!fbdev)
634 return 0;
635
636 memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs));
637
638 /* Restart LCD clocking */
639 au_writel(sys_clksrc, SYS_CLKSRC);
640
641 /* Unblank the LCD */
642 au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info);
643
614 return 0; 644 return 0;
615} 645}
646#else
647#define au1100fb_drv_suspend NULL
648#define au1100fb_drv_resume NULL
649#endif
616 650
617static struct device_driver au1100fb_driver = { 651static struct device_driver au1100fb_driver = {
618 .name = "au1100-lcd", 652 .name = "au1100-lcd",
@@ -706,8 +740,7 @@ void __exit au1100fb_cleanup(void)
706{ 740{
707 driver_unregister(&au1100fb_driver); 741 driver_unregister(&au1100fb_driver);
708 742
709 if (drv_info.opt_mode) 743 kfree(drv_info.opt_mode);
710 kfree(drv_info.opt_mode);
711} 744}
712 745
713module_init(au1100fb_init); 746module_init(au1100fb_init);
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 600d3e0e08b7..c6a5f0ccc107 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1694,7 +1694,7 @@ static int au1200fb_drv_probe(struct device *dev)
1694 1694
1695 /* Now hook interrupt too */ 1695 /* Now hook interrupt too */
1696 if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq, 1696 if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
1697 SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) { 1697 IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) {
1698 print_err("fail to request interrupt line %d (err: %d)", 1698 print_err("fail to request interrupt line %d (err: %d)",
1699 AU1200_LCD_INT, ret); 1699 AU1200_LCD_INT, ret);
1700 goto failed; 1700 goto failed;
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index b895eaaa73fd..02f15297a021 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -50,6 +50,14 @@ config BACKLIGHT_CORGI
50 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the 50 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
51 backlight driver. 51 backlight driver.
52 52
53config BACKLIGHT_LOCOMO
54 tristate "Sharp LOCOMO LCD/Backlight Driver"
55 depends on BACKLIGHT_DEVICE && SHARP_LOCOMO
56 default y
57 help
58 If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
59 enable the LCD/backlight driver.
60
53config BACKLIGHT_HP680 61config BACKLIGHT_HP680
54 tristate "HP Jornada 680 Backlight Driver" 62 tristate "HP Jornada 680 Backlight Driver"
55 depends on BACKLIGHT_DEVICE && SH_HP6XX 63 depends on BACKLIGHT_DEVICE && SH_HP6XX
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 744210c38e74..65e5553fc849 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -4,4 +4,4 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
4obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 4obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
5obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o 5obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o 6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
7obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o 7obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index a71e984c93d4..fe1488374f62 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -20,14 +20,14 @@
20 20
21#include <asm/cpu/dac.h> 21#include <asm/cpu/dac.h>
22#include <asm/hp6xx/hp6xx.h> 22#include <asm/hp6xx/hp6xx.h>
23#include <asm/hd64461/hd64461.h> 23#include <asm/hd64461.h>
24 24
25#define HP680_MAX_INTENSITY 255 25#define HP680_MAX_INTENSITY 255
26#define HP680_DEFAULT_INTENSITY 10 26#define HP680_DEFAULT_INTENSITY 10
27 27
28static int hp680bl_suspended; 28static int hp680bl_suspended;
29static int current_intensity = 0; 29static int current_intensity = 0;
30static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; 30static DEFINE_SPINLOCK(bl_lock);
31static struct backlight_device *hp680_backlight_device; 31static struct backlight_device *hp680_backlight_device;
32 32
33static void hp680bl_send_intensity(struct backlight_device *bd) 33static void hp680bl_send_intensity(struct backlight_device *bd)
@@ -163,6 +163,6 @@ static void __exit hp680bl_exit(void)
163module_init(hp680bl_init); 163module_init(hp680bl_init);
164module_exit(hp680bl_exit); 164module_exit(hp680bl_exit);
165 165
166MODULE_AUTHOR("Andriy Skulysh <askulysh@image.kiev.ua>"); 166MODULE_AUTHOR("Andriy Skulysh <askulysh@gmail.com>");
167MODULE_DESCRIPTION("HP Jornada 680 Backlight Driver"); 167MODULE_DESCRIPTION("HP Jornada 680 Backlight Driver");
168MODULE_LICENSE("GPL"); 168MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 60831bb23685..628571c63bac 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -11,12 +11,13 @@
11 */ 11 */
12 12
13/* LCD power functions */ 13/* LCD power functions */
14#include <linux/config.h>
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/init.h> 15#include <linux/init.h>
17#include <linux/delay.h> 16#include <linux/delay.h>
18#include <linux/device.h> 17#include <linux/device.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/fb.h>
20#include <linux/backlight.h>
20 21
21#include <asm/hardware/locomo.h> 22#include <asm/hardware/locomo.h>
22#include <asm/irq.h> 23#include <asm/irq.h>
@@ -25,23 +26,26 @@
25 26
26#include "../../../arch/arm/mach-sa1100/generic.h" 27#include "../../../arch/arm/mach-sa1100/generic.h"
27 28
29static struct backlight_device *locomolcd_bl_device;
28static struct locomo_dev *locomolcd_dev; 30static struct locomo_dev *locomolcd_dev;
31static unsigned long locomolcd_flags;
32#define LOCOMOLCD_SUSPENDED 0x01
29 33
30static void locomolcd_on(int comadj) 34static void locomolcd_on(int comadj)
31{ 35{
32 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0); 36 locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
33 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 1); 37 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
34 mdelay(2); 38 mdelay(2);
35 39
36 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0); 40 locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
37 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 1); 41 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
38 mdelay(2); 42 mdelay(2);
39 43
40 locomo_m62332_senddata(locomolcd_dev, comadj, 0); 44 locomo_m62332_senddata(locomolcd_dev, comadj, 0);
41 mdelay(5); 45 mdelay(5);
42 46
43 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0); 47 locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
44 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 1); 48 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
45 mdelay(10); 49 mdelay(10);
46 50
47 /* TFTCRST | CPSOUT=0 | CPSEN */ 51 /* TFTCRST | CPSOUT=0 | CPSEN */
@@ -54,8 +58,8 @@ static void locomolcd_on(int comadj)
54 locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC); 58 locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
55 mdelay(10); 59 mdelay(10);
56 60
57 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0); 61 locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
58 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 1); 62 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
59} 63}
60 64
61static void locomolcd_off(int comadj) 65static void locomolcd_off(int comadj)
@@ -64,16 +68,16 @@ static void locomolcd_off(int comadj)
64 locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC); 68 locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
65 mdelay(1); 69 mdelay(1);
66 70
67 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0); 71 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
68 mdelay(110); 72 mdelay(110);
69 73
70 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0); 74 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
71 mdelay(700); 75 mdelay(700);
72 76
73 /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */ 77 /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
74 locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC); 78 locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
75 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0); 79 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
76 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0); 80 locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
77} 81}
78 82
79void locomolcd_power(int on) 83void locomolcd_power(int on)
@@ -89,12 +93,10 @@ void locomolcd_power(int on)
89 } 93 }
90 94
91 /* read comadj */ 95 /* read comadj */
92 if (comadj == -1) { 96 if (comadj == -1 && machine_is_collie())
93 if (machine_is_poodle()) 97 comadj = 128;
94 comadj = 118; 98 if (comadj == -1 && machine_is_poodle())
95 if (machine_is_collie()) 99 comadj = 118;
96 comadj = 128;
97 }
98 100
99 if (on) 101 if (on)
100 locomolcd_on(comadj); 102 locomolcd_on(comadj);
@@ -105,26 +107,100 @@ void locomolcd_power(int on)
105} 107}
106EXPORT_SYMBOL(locomolcd_power); 108EXPORT_SYMBOL(locomolcd_power);
107 109
108static int poodle_lcd_probe(struct locomo_dev *dev) 110
111static int current_intensity;
112
113static int locomolcd_set_intensity(struct backlight_device *bd)
114{
115 int intensity = bd->props->brightness;
116
117 if (bd->props->power != FB_BLANK_UNBLANK)
118 intensity = 0;
119 if (bd->props->fb_blank != FB_BLANK_UNBLANK)
120 intensity = 0;
121 if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
122 intensity = 0;
123
124 switch (intensity) {
125 /* AC and non-AC are handled differently, but produce same results in sharp code? */
126 case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break;
127 case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break;
128 case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break;
129 case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break;
130 case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break;
131
132 default:
133 return -ENODEV;
134 }
135 current_intensity = intensity;
136 return 0;
137}
138
139static int locomolcd_get_intensity(struct backlight_device *bd)
140{
141 return current_intensity;
142}
143
144static struct backlight_properties locomobl_data = {
145 .owner = THIS_MODULE,
146 .get_brightness = locomolcd_get_intensity,
147 .update_status = locomolcd_set_intensity,
148 .max_brightness = 4,
149};
150
151#ifdef CONFIG_PM
152static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state)
153{
154 locomolcd_flags |= LOCOMOLCD_SUSPENDED;
155 locomolcd_set_intensity(locomolcd_bl_device);
156 return 0;
157}
158
159static int locomolcd_resume(struct locomo_dev *dev)
160{
161 locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
162 locomolcd_set_intensity(locomolcd_bl_device);
163 return 0;
164}
165#else
166#define locomolcd_suspend NULL
167#define locomolcd_resume NULL
168#endif
169
170static int locomolcd_probe(struct locomo_dev *ldev)
109{ 171{
110 unsigned long flags; 172 unsigned long flags;
111 173
112 local_irq_save(flags); 174 local_irq_save(flags);
113 locomolcd_dev = dev; 175 locomolcd_dev = ldev;
176
177 locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
114 178
115 /* the poodle_lcd_power function is called for the first time 179 /* the poodle_lcd_power function is called for the first time
116 * from fs_initcall, which is before locomo is activated. 180 * from fs_initcall, which is before locomo is activated.
117 * We need to recall poodle_lcd_power here*/ 181 * We need to recall poodle_lcd_power here*/
118#ifdef CONFIG_MACH_POODLE 182 if (machine_is_poodle())
119 locomolcd_power(1); 183 locomolcd_power(1);
120#endif 184
121 local_irq_restore(flags); 185 local_irq_restore(flags);
186
187 locomolcd_bl_device = backlight_device_register("locomo-bl", NULL, &locomobl_data);
188
189 if (IS_ERR (locomolcd_bl_device))
190 return PTR_ERR (locomolcd_bl_device);
191
192 /* Set up frontlight so that screen is readable */
193 locomobl_data.brightness = 2;
194 locomolcd_set_intensity(locomolcd_bl_device);
195
122 return 0; 196 return 0;
123} 197}
124 198
125static int poodle_lcd_remove(struct locomo_dev *dev) 199static int locomolcd_remove(struct locomo_dev *dev)
126{ 200{
127 unsigned long flags; 201 unsigned long flags;
202
203 backlight_device_unregister(locomolcd_bl_device);
128 local_irq_save(flags); 204 local_irq_save(flags);
129 locomolcd_dev = NULL; 205 locomolcd_dev = NULL;
130 local_irq_restore(flags); 206 local_irq_restore(flags);
@@ -136,19 +212,33 @@ static struct locomo_driver poodle_lcd_driver = {
136 .name = "locomo-backlight", 212 .name = "locomo-backlight",
137 }, 213 },
138 .devid = LOCOMO_DEVID_BACKLIGHT, 214 .devid = LOCOMO_DEVID_BACKLIGHT,
139 .probe = poodle_lcd_probe, 215 .probe = locomolcd_probe,
140 .remove = poodle_lcd_remove, 216 .remove = locomolcd_remove,
217 .suspend = locomolcd_suspend,
218 .resume = locomolcd_resume,
141}; 219};
142 220
143static int __init poodle_lcd_init(void) 221
222static int __init locomolcd_init(void)
144{ 223{
145 int ret = locomo_driver_register(&poodle_lcd_driver); 224 int ret = locomo_driver_register(&poodle_lcd_driver);
146 if (ret) return ret; 225 if (ret)
226 return ret;
147 227
148#ifdef CONFIG_SA1100_COLLIE 228#ifdef CONFIG_SA1100_COLLIE
149 sa1100fb_lcd_power = locomolcd_power; 229 sa1100fb_lcd_power = locomolcd_power;
150#endif 230#endif
151 return 0; 231 return 0;
152} 232}
153device_initcall(poodle_lcd_init);
154 233
234static void __exit locomolcd_exit(void)
235{
236 locomo_driver_unregister(&poodle_lcd_driver);
237}
238
239module_init(locomolcd_init);
240module_exit(locomolcd_exit);
241
242MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>");
243MODULE_DESCRIPTION("Collie LCD driver");
244MODULE_LICENSE("GPL");
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 6577fdfdfc16..c66e3d52cbf3 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -1,6 +1,6 @@
1/* bw2.c: BWTWO frame buffer driver 1/* bw2.c: BWTWO frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) 6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -19,14 +19,11 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20 20
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/sbus.h>
23#include <asm/oplib.h> 22#include <asm/oplib.h>
23#include <asm/prom.h>
24#include <asm/of_device.h>
24#include <asm/fbio.h> 25#include <asm/fbio.h>
25 26
26#ifdef CONFIG_SPARC32
27#include <asm/sun4paddr.h>
28#endif
29
30#include "sbuslib.h" 27#include "sbuslib.h"
31 28
32/* 29/*
@@ -59,30 +56,30 @@ static struct fb_ops bw2_ops = {
59#define BWTWO_REGISTER_OFFSET 0x400000 56#define BWTWO_REGISTER_OFFSET 0x400000
60 57
61struct bt_regs { 58struct bt_regs {
62 volatile u32 addr; 59 u32 addr;
63 volatile u32 color_map; 60 u32 color_map;
64 volatile u32 control; 61 u32 control;
65 volatile u32 cursor; 62 u32 cursor;
66}; 63};
67 64
68struct bw2_regs { 65struct bw2_regs {
69 struct bt_regs cmap; 66 struct bt_regs cmap;
70 volatile u8 control; 67 u8 control;
71 volatile u8 status; 68 u8 status;
72 volatile u8 cursor_start; 69 u8 cursor_start;
73 volatile u8 cursor_end; 70 u8 cursor_end;
74 volatile u8 h_blank_start; 71 u8 h_blank_start;
75 volatile u8 h_blank_end; 72 u8 h_blank_end;
76 volatile u8 h_sync_start; 73 u8 h_sync_start;
77 volatile u8 h_sync_end; 74 u8 h_sync_end;
78 volatile u8 comp_sync_end; 75 u8 comp_sync_end;
79 volatile u8 v_blank_start_high; 76 u8 v_blank_start_high;
80 volatile u8 v_blank_start_low; 77 u8 v_blank_start_low;
81 volatile u8 v_blank_end; 78 u8 v_blank_end;
82 volatile u8 v_sync_start; 79 u8 v_sync_start;
83 volatile u8 v_sync_end; 80 u8 v_sync_end;
84 volatile u8 xfer_holdoff_start; 81 u8 xfer_holdoff_start;
85 volatile u8 xfer_holdoff_end; 82 u8 xfer_holdoff_end;
86}; 83};
87 84
88/* Status Register Constants */ 85/* Status Register Constants */
@@ -117,9 +114,8 @@ struct bw2_par {
117#define BW2_FLAG_BLANKED 0x00000001 114#define BW2_FLAG_BLANKED 0x00000001
118 115
119 unsigned long physbase; 116 unsigned long physbase;
117 unsigned long which_io;
120 unsigned long fbsize; 118 unsigned long fbsize;
121
122 struct sbus_dev *sdev;
123}; 119};
124 120
125/** 121/**
@@ -174,9 +170,7 @@ static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
174 170
175 return sbusfb_mmap_helper(bw2_mmap_map, 171 return sbusfb_mmap_helper(bw2_mmap_map,
176 par->physbase, par->fbsize, 172 par->physbase, par->fbsize,
177 (par->sdev ? 173 par->which_io,
178 par->sdev->reg_addrs[0].which_io :
179 0),
180 vma); 174 vma);
181} 175}
182 176
@@ -288,139 +282,124 @@ static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
288struct all_info { 282struct all_info {
289 struct fb_info info; 283 struct fb_info info;
290 struct bw2_par par; 284 struct bw2_par par;
291 struct list_head list;
292}; 285};
293static LIST_HEAD(bw2_list);
294 286
295static void bw2_init_one(struct sbus_dev *sdev) 287static int __devinit bw2_init_one(struct of_device *op)
296{ 288{
289 struct device_node *dp = op->node;
297 struct all_info *all; 290 struct all_info *all;
298 struct resource *resp; 291 int linebytes, err;
299#ifdef CONFIG_SUN4
300 struct resource res;
301#endif
302 int linebytes;
303 292
304 all = kmalloc(sizeof(*all), GFP_KERNEL); 293 all = kzalloc(sizeof(*all), GFP_KERNEL);
305 if (!all) { 294 if (!all)
306 printk(KERN_ERR "bw2: Cannot allocate memory.\n"); 295 return -ENOMEM;
307 return;
308 }
309 memset(all, 0, sizeof(*all));
310
311 INIT_LIST_HEAD(&all->list);
312 296
313 spin_lock_init(&all->par.lock); 297 spin_lock_init(&all->par.lock);
314 all->par.sdev = sdev; 298
315 299 all->par.physbase = op->resource[0].start;
316#ifdef CONFIG_SUN4 300 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
317 if (!sdev) { 301
318 all->par.physbase = sun4_bwtwo_physaddr; 302 sbusfb_fill_var(&all->info.var, dp->node, 1);
319 res.start = sun4_bwtwo_physaddr; 303 linebytes = of_getintprop_default(dp, "linebytes",
320 res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1; 304 all->info.var.xres);
321 res.flags = IORESOURCE_IO; 305
322 resp = &res;
323 all->info.var.xres = all->info.var.xres_virtual = 1152;
324 all->info.var.yres = all->info.var.yres_virtual = 900;
325 all->info.var.bits_per_pixel = 1;
326 linebytes = 1152 / 8;
327 } else
328#else
329 {
330 BUG_ON(!sdev);
331 all->par.physbase = sdev->reg_addrs[0].phys_addr;
332 resp = &sdev->resource[0];
333 sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1);
334 linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
335 all->info.var.xres);
336 }
337#endif
338 all->info.var.red.length = all->info.var.green.length = 306 all->info.var.red.length = all->info.var.green.length =
339 all->info.var.blue.length = all->info.var.bits_per_pixel; 307 all->info.var.blue.length = all->info.var.bits_per_pixel;
340 all->info.var.red.offset = all->info.var.green.offset = 308 all->info.var.red.offset = all->info.var.green.offset =
341 all->info.var.blue.offset = 0; 309 all->info.var.blue.offset = 0;
342 310
343 all->par.regs = sbus_ioremap(resp, BWTWO_REGISTER_OFFSET, 311 all->par.regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET,
344 sizeof(struct bw2_regs), "bw2 regs"); 312 sizeof(struct bw2_regs), "bw2 regs");
345 313
346 if (sdev && !prom_getbool(sdev->prom_node, "width")) 314 if (!of_find_property(dp, "width", NULL))
347 bw2_do_default_mode(&all->par, &all->info, &linebytes); 315 bw2_do_default_mode(&all->par, &all->info, &linebytes);
348 316
349 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 317 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
350 318
351 all->info.flags = FBINFO_DEFAULT; 319 all->info.flags = FBINFO_DEFAULT;
352 all->info.fbops = &bw2_ops; 320 all->info.fbops = &bw2_ops;
353#if defined(CONFIG_SPARC32) 321
354 if (sdev) 322 all->info.screen_base =
355 all->info.screen_base = (char __iomem *) 323 sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
356 prom_getintdefault(sdev->prom_node, "address", 0);
357#endif
358 if (!all->info.screen_base)
359 all->info.screen_base =
360 sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram");
361 all->info.par = &all->par; 324 all->info.par = &all->par;
362 325
363 bw2_blank(0, &all->info); 326 bw2_blank(0, &all->info);
364 327
365 bw2_init_fix(&all->info, linebytes); 328 bw2_init_fix(&all->info, linebytes);
366 329
367 if (register_framebuffer(&all->info) < 0) { 330 err= register_framebuffer(&all->info);
368 printk(KERN_ERR "bw2: Could not register framebuffer.\n"); 331 if (err < 0) {
332 of_iounmap(all->par.regs, sizeof(struct bw2_regs));
333 of_iounmap(all->info.screen_base, all->par.fbsize);
369 kfree(all); 334 kfree(all);
370 return; 335 return err;
371 } 336 }
372 337
373 list_add(&all->list, &bw2_list); 338 dev_set_drvdata(&op->dev, all);
339
340 printk("%s: bwtwo at %lx:%lx\n",
341 dp->full_name,
342 all->par.which_io, all->par.physbase);
374 343
375 printk("bw2: bwtwo at %lx:%lx\n", 344 return 0;
376 (long) (sdev ? sdev->reg_addrs[0].which_io : 0),
377 (long) all->par.physbase);
378} 345}
379 346
380int __init bw2_init(void) 347static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id *match)
381{ 348{
382 struct sbus_bus *sbus; 349 struct of_device *op = to_of_device(&dev->dev);
383 struct sbus_dev *sdev;
384 350
385 if (fb_get_options("bw2fb", NULL)) 351 return bw2_init_one(op);
386 return -ENODEV; 352}
387 353
388#ifdef CONFIG_SUN4 354static int __devexit bw2_remove(struct of_device *dev)
389 bw2_init_one(NULL); 355{
390#endif 356 struct all_info *all = dev_get_drvdata(&dev->dev);
391 for_all_sbusdev(sdev, sbus) { 357
392 if (!strcmp(sdev->prom_name, "bwtwo")) 358 unregister_framebuffer(&all->info);
393 bw2_init_one(sdev); 359
394 } 360 of_iounmap(all->par.regs, sizeof(struct bw2_regs));
361 of_iounmap(all->info.screen_base, all->par.fbsize);
362
363 kfree(all);
364
365 dev_set_drvdata(&dev->dev, NULL);
395 366
396 return 0; 367 return 0;
397} 368}
398 369
399void __exit bw2_exit(void) 370static struct of_device_id bw2_match[] = {
400{ 371 {
401 struct list_head *pos, *tmp; 372 .name = "bwtwo",
373 },
374 {},
375};
376MODULE_DEVICE_TABLE(of, bw2_match);
402 377
403 list_for_each_safe(pos, tmp, &bw2_list) { 378static struct of_platform_driver bw2_driver = {
404 struct all_info *all = list_entry(pos, typeof(*all), list); 379 .name = "bw2",
380 .match_table = bw2_match,
381 .probe = bw2_probe,
382 .remove = __devexit_p(bw2_remove),
383};
405 384
406 unregister_framebuffer(&all->info); 385static int __init bw2_init(void)
407 kfree(all); 386{
408 } 387 if (fb_get_options("bw2fb", NULL))
388 return -ENODEV;
389
390 return of_register_driver(&bw2_driver, &of_bus_type);
409} 391}
410 392
411int __init 393static void __exit bw2_exit(void)
412bw2_setup(char *arg)
413{ 394{
414 /* No cmdline options yet... */ 395 return of_unregister_driver(&bw2_driver);
415 return 0;
416} 396}
417 397
418module_init(bw2_init);
419 398
420#ifdef MODULE 399module_init(bw2_init);
421module_exit(bw2_exit); 400module_exit(bw2_exit);
422#endif
423 401
424MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets"); 402MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets");
425MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 403MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
404MODULE_VERSION("2.0");
426MODULE_LICENSE("GPL"); 405MODULE_LICENSE("GPL");
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 74415325b016..6faea4034e3d 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -24,7 +24,6 @@
24 24
25 25
26 26
27#include <linux/config.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/kernel.h> 28#include <linux/kernel.h>
30#include <linux/string.h> 29#include <linux/string.h>
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index e5ff62e9cfb8..f00b50aab606 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -17,7 +17,6 @@
17 * the native cpu endians. I also need to deal with MSB position in the word. 17 * the native cpu endians. I also need to deal with MSB position in the word.
18 * 18 *
19 */ 19 */
20#include <linux/config.h>
21#include <linux/module.h> 20#include <linux/module.h>
22#include <linux/string.h> 21#include <linux/string.h>
23#include <linux/fb.h> 22#include <linux/fb.h>
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 8ba6152db2fd..51d35386a945 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -29,7 +29,6 @@
29 * Also need to add code to deal with cards endians that are different than 29 * Also need to add code to deal with cards endians that are different than
30 * the native cpu endians. I also need to deal with MSB position in the word. 30 * the native cpu endians. I also need to deal with MSB position in the word.
31 */ 31 */
32#include <linux/config.h>
33#include <linux/module.h> 32#include <linux/module.h>
34#include <linux/string.h> 33#include <linux/string.h>
35#include <linux/fb.h> 34#include <linux/fb.h>
@@ -230,6 +229,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
230 tab = cfb_tab16; 229 tab = cfb_tab16;
231 break; 230 break;
232 case 32: 231 case 32:
232 default:
233 tab = cfb_tab32; 233 tab = cfb_tab32;
234 break; 234 break;
235 } 235 }
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 63b6c79c8a0a..7f926c619b61 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -1,6 +1,6 @@
1/* cg14.c: CGFOURTEEN frame buffer driver 1/* cg14.c: CGFOURTEEN frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) 5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 * 6 *
@@ -18,8 +18,8 @@
18#include <linux/mm.h> 18#include <linux/mm.h>
19 19
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/sbus.h> 21#include <asm/prom.h>
22#include <asm/oplib.h> 22#include <asm/of_device.h>
23#include <asm/fbio.h> 23#include <asm/fbio.h>
24 24
25#include "sbuslib.h" 25#include "sbuslib.h"
@@ -99,73 +99,73 @@ static struct fb_ops cg14_ops = {
99#define CG14_MCR_PIXMODE_32 3 99#define CG14_MCR_PIXMODE_32 3
100 100
101struct cg14_regs{ 101struct cg14_regs{
102 volatile u8 mcr; /* Master Control Reg */ 102 u8 mcr; /* Master Control Reg */
103 volatile u8 ppr; /* Packed Pixel Reg */ 103 u8 ppr; /* Packed Pixel Reg */
104 volatile u8 tms[2]; /* Test Mode Status Regs */ 104 u8 tms[2]; /* Test Mode Status Regs */
105 volatile u8 msr; /* Master Status Reg */ 105 u8 msr; /* Master Status Reg */
106 volatile u8 fsr; /* Fault Status Reg */ 106 u8 fsr; /* Fault Status Reg */
107 volatile u8 rev; /* Revision & Impl */ 107 u8 rev; /* Revision & Impl */
108 volatile u8 ccr; /* Clock Control Reg */ 108 u8 ccr; /* Clock Control Reg */
109 volatile u32 tmr; /* Test Mode Read Back */ 109 u32 tmr; /* Test Mode Read Back */
110 volatile u8 mod; /* Monitor Operation Data Reg */ 110 u8 mod; /* Monitor Operation Data Reg */
111 volatile u8 acr; /* Aux Control */ 111 u8 acr; /* Aux Control */
112 u8 xxx0[6]; 112 u8 xxx0[6];
113 volatile u16 hct; /* Hor Counter */ 113 u16 hct; /* Hor Counter */
114 volatile u16 vct; /* Vert Counter */ 114 u16 vct; /* Vert Counter */
115 volatile u16 hbs; /* Hor Blank Start */ 115 u16 hbs; /* Hor Blank Start */
116 volatile u16 hbc; /* Hor Blank Clear */ 116 u16 hbc; /* Hor Blank Clear */
117 volatile u16 hss; /* Hor Sync Start */ 117 u16 hss; /* Hor Sync Start */
118 volatile u16 hsc; /* Hor Sync Clear */ 118 u16 hsc; /* Hor Sync Clear */
119 volatile u16 csc; /* Composite Sync Clear */ 119 u16 csc; /* Composite Sync Clear */
120 volatile u16 vbs; /* Vert Blank Start */ 120 u16 vbs; /* Vert Blank Start */
121 volatile u16 vbc; /* Vert Blank Clear */ 121 u16 vbc; /* Vert Blank Clear */
122 volatile u16 vss; /* Vert Sync Start */ 122 u16 vss; /* Vert Sync Start */
123 volatile u16 vsc; /* Vert Sync Clear */ 123 u16 vsc; /* Vert Sync Clear */
124 volatile u16 xcs; 124 u16 xcs;
125 volatile u16 xcc; 125 u16 xcc;
126 volatile u16 fsa; /* Fault Status Address */ 126 u16 fsa; /* Fault Status Address */
127 volatile u16 adr; /* Address Registers */ 127 u16 adr; /* Address Registers */
128 u8 xxx1[0xce]; 128 u8 xxx1[0xce];
129 volatile u8 pcg[0x100]; /* Pixel Clock Generator */ 129 u8 pcg[0x100]; /* Pixel Clock Generator */
130 volatile u32 vbr; /* Frame Base Row */ 130 u32 vbr; /* Frame Base Row */
131 volatile u32 vmcr; /* VBC Master Control */ 131 u32 vmcr; /* VBC Master Control */
132 volatile u32 vcr; /* VBC refresh */ 132 u32 vcr; /* VBC refresh */
133 volatile u32 vca; /* VBC Config */ 133 u32 vca; /* VBC Config */
134}; 134};
135 135
136#define CG14_CCR_ENABLE 0x04 136#define CG14_CCR_ENABLE 0x04
137#define CG14_CCR_SELECT 0x02 /* HW/Full screen */ 137#define CG14_CCR_SELECT 0x02 /* HW/Full screen */
138 138
139struct cg14_cursor { 139struct cg14_cursor {
140 volatile u32 cpl0[32]; /* Enable plane 0 */ 140 u32 cpl0[32]; /* Enable plane 0 */
141 volatile u32 cpl1[32]; /* Color selection plane */ 141 u32 cpl1[32]; /* Color selection plane */
142 volatile u8 ccr; /* Cursor Control Reg */ 142 u8 ccr; /* Cursor Control Reg */
143 u8 xxx0[3]; 143 u8 xxx0[3];
144 volatile u16 cursx; /* Cursor x,y position */ 144 u16 cursx; /* Cursor x,y position */
145 volatile u16 cursy; /* Cursor x,y position */ 145 u16 cursy; /* Cursor x,y position */
146 volatile u32 color0; 146 u32 color0;
147 volatile u32 color1; 147 u32 color1;
148 u32 xxx1[0x1bc]; 148 u32 xxx1[0x1bc];
149 volatile u32 cpl0i[32]; /* Enable plane 0 autoinc */ 149 u32 cpl0i[32]; /* Enable plane 0 autoinc */
150 volatile u32 cpl1i[32]; /* Color selection autoinc */ 150 u32 cpl1i[32]; /* Color selection autoinc */
151}; 151};
152 152
153struct cg14_dac { 153struct cg14_dac {
154 volatile u8 addr; /* Address Register */ 154 u8 addr; /* Address Register */
155 u8 xxx0[255]; 155 u8 xxx0[255];
156 volatile u8 glut; /* Gamma table */ 156 u8 glut; /* Gamma table */
157 u8 xxx1[255]; 157 u8 xxx1[255];
158 volatile u8 select; /* Register Select */ 158 u8 select; /* Register Select */
159 u8 xxx2[255]; 159 u8 xxx2[255];
160 volatile u8 mode; /* Mode Register */ 160 u8 mode; /* Mode Register */
161}; 161};
162 162
163struct cg14_xlut{ 163struct cg14_xlut{
164 volatile u8 x_xlut [256]; 164 u8 x_xlut [256];
165 volatile u8 x_xlutd [256]; 165 u8 x_xlutd [256];
166 u8 xxx0[0x600]; 166 u8 xxx0[0x600];
167 volatile u8 x_xlut_inc [256]; 167 u8 x_xlut_inc [256];
168 volatile u8 x_xlutd_inc [256]; 168 u8 x_xlutd_inc [256];
169}; 169};
170 170
171/* Color look up table (clut) */ 171/* Color look up table (clut) */
@@ -204,7 +204,6 @@ struct cg14_par {
204 204
205 int mode; 205 int mode;
206 int ramsize; 206 int ramsize;
207 struct sbus_dev *sdev;
208}; 207};
209 208
210static void __cg14_reset(struct cg14_par *par) 209static void __cg14_reset(struct cg14_par *par)
@@ -355,14 +354,9 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
355 * Initialisation 354 * Initialisation
356 */ 355 */
357 356
358static void cg14_init_fix(struct fb_info *info, int linebytes) 357static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
359{ 358{
360 struct cg14_par *par = (struct cg14_par *)info->par; 359 const char *name = dp->name;
361 const char *name;
362
363 name = "cgfourteen";
364 if (par->sdev)
365 name = par->sdev->prom_name;
366 360
367 strlcpy(info->fix.id, name, sizeof(info->fix.id)); 361 strlcpy(info->fix.id, name, sizeof(info->fix.id));
368 362
@@ -456,98 +450,81 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = {
456struct all_info { 450struct all_info {
457 struct fb_info info; 451 struct fb_info info;
458 struct cg14_par par; 452 struct cg14_par par;
459 struct list_head list;
460}; 453};
461static LIST_HEAD(cg14_list);
462 454
463static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node) 455static void cg14_unmap_regs(struct all_info *all)
464{ 456{
465 struct all_info *all; 457 if (all->par.regs)
466 unsigned long phys, rphys; 458 of_iounmap(all->par.regs, sizeof(struct cg14_regs));
467 u32 bases[6]; 459 if (all->par.clut)
468 int is_8mb, linebytes, i; 460 of_iounmap(all->par.clut, sizeof(struct cg14_clut));
469 461 if (all->par.cursor)
470 if (!sdev) { 462 of_iounmap(all->par.cursor, sizeof(struct cg14_cursor));
471 if (prom_getproperty(node, "address", 463 if (all->info.screen_base)
472 (char *) &bases[0], sizeof(bases)) <= 0 464 of_iounmap(all->info.screen_base, all->par.fbsize);
473 || !bases[0]) { 465}
474 printk(KERN_ERR "cg14: Device is not mapped.\n");
475 return;
476 }
477 if (__get_iospace(bases[0]) != __get_iospace(bases[1])) {
478 printk(KERN_ERR "cg14: I/O spaces don't match.\n");
479 return;
480 }
481 }
482 466
483 all = kmalloc(sizeof(*all), GFP_KERNEL); 467static int __devinit cg14_init_one(struct of_device *op)
484 if (!all) { 468{
485 printk(KERN_ERR "cg14: Cannot allocate memory.\n"); 469 struct device_node *dp = op->node;
486 return; 470 struct all_info *all;
487 } 471 int is_8mb, linebytes, i, err;
488 memset(all, 0, sizeof(*all));
489 472
490 INIT_LIST_HEAD(&all->list); 473 all = kzalloc(sizeof(*all), GFP_KERNEL);
474 if (!all)
475 return -ENOMEM;
491 476
492 spin_lock_init(&all->par.lock); 477 spin_lock_init(&all->par.lock);
493 478
494 sbusfb_fill_var(&all->info.var, node, 8); 479 sbusfb_fill_var(&all->info.var, dp->node, 8);
495 all->info.var.red.length = 8; 480 all->info.var.red.length = 8;
496 all->info.var.green.length = 8; 481 all->info.var.green.length = 8;
497 all->info.var.blue.length = 8; 482 all->info.var.blue.length = 8;
498 483
499 linebytes = prom_getintdefault(node, "linebytes", 484 linebytes = of_getintprop_default(dp, "linebytes",
500 all->info.var.xres); 485 all->info.var.xres);
501 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 486 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
502 487
503 all->par.sdev = sdev; 488 if (!strcmp(dp->parent->name, "sbus") ||
504 if (sdev) { 489 !strcmp(dp->parent->name, "sbi")) {
505 rphys = sdev->reg_addrs[0].phys_addr; 490 all->par.physbase = op->resource[0].start;
506 all->par.physbase = phys = sdev->reg_addrs[1].phys_addr; 491 all->par.iospace = op->resource[0].flags & IORESOURCE_BITS;
507 all->par.iospace = sdev->reg_addrs[0].which_io;
508
509 all->par.regs = sbus_ioremap(&sdev->resource[0], 0,
510 sizeof(struct cg14_regs),
511 "cg14 regs");
512 all->par.clut = sbus_ioremap(&sdev->resource[0], CG14_CLUT1,
513 sizeof(struct cg14_clut),
514 "cg14 clut");
515 all->par.cursor = sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS,
516 sizeof(struct cg14_cursor),
517 "cg14 cursor");
518 all->info.screen_base = sbus_ioremap(&sdev->resource[1], 0,
519 all->par.fbsize, "cg14 ram");
520 } else { 492 } else {
521 rphys = __get_phys(bases[0]); 493 all->par.physbase = op->resource[1].start;
522 all->par.physbase = phys = __get_phys(bases[1]); 494 all->par.iospace = op->resource[0].flags & IORESOURCE_BITS;
523 all->par.iospace = __get_iospace(bases[0]);
524 all->par.regs = (struct cg14_regs __iomem *)(unsigned long)bases[0];
525 all->par.clut = (struct cg14_clut __iomem *)((unsigned long)bases[0] +
526 CG14_CLUT1);
527 all->par.cursor =
528 (struct cg14_cursor __iomem *)((unsigned long)bases[0] +
529 CG14_CURSORREGS);
530
531 all->info.screen_base = (char __iomem *)(unsigned long)bases[1];
532 } 495 }
533 496
534 prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases)); 497 all->par.regs = of_ioremap(&op->resource[0], 0,
535 is_8mb = (bases[5] == 0x800000); 498 sizeof(struct cg14_regs), "cg14 regs");
499 all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1,
500 sizeof(struct cg14_clut), "cg14 clut");
501 all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS,
502 sizeof(struct cg14_cursor), "cg14 cursor");
536 503
537 if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) { 504 all->info.screen_base = of_ioremap(&op->resource[1], 0,
538 extern void __cg14_mmap_sized_wrongly(void); 505 all->par.fbsize, "cg14 ram");
539 506
540 __cg14_mmap_sized_wrongly(); 507 if (!all->par.regs || !all->par.clut || !all->par.cursor ||
541 } 508 !all->info.screen_base)
509 cg14_unmap_regs(all);
510
511 is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
512 (8 * 1024 * 1024));
513
514 BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map));
542 515
543 memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map)); 516 memcpy(&all->par.mmap_map, &__cg14_mmap_map,
517 sizeof(all->par.mmap_map));
518
544 for (i = 0; i < CG14_MMAP_ENTRIES; i++) { 519 for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
545 struct sbus_mmap_map *map = &all->par.mmap_map[i]; 520 struct sbus_mmap_map *map = &all->par.mmap_map[i];
546 521
547 if (!map->size) 522 if (!map->size)
548 break; 523 break;
549 if (map->poff & 0x80000000) 524 if (map->poff & 0x80000000)
550 map->poff = (map->poff & 0x7fffffff) + rphys - phys; 525 map->poff = (map->poff & 0x7fffffff) +
526 (op->resource[0].start -
527 op->resource[1].start);
551 if (is_8mb && 528 if (is_8mb &&
552 map->size >= 0x100000 && 529 map->size >= 0x100000 &&
553 map->size <= 0x400000) 530 map->size <= 0x400000)
@@ -564,84 +541,87 @@ static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
564 __cg14_reset(&all->par); 541 __cg14_reset(&all->par);
565 542
566 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 543 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
567 printk(KERN_ERR "cg14: Could not allocate color map.\n"); 544 cg14_unmap_regs(all);
568 kfree(all); 545 kfree(all);
569 return; 546 return -ENOMEM;
570 } 547 }
571 fb_set_cmap(&all->info.cmap, &all->info); 548 fb_set_cmap(&all->info.cmap, &all->info);
572 549
573 cg14_init_fix(&all->info, linebytes); 550 cg14_init_fix(&all->info, linebytes, dp);
574 551
575 if (register_framebuffer(&all->info) < 0) { 552 err = register_framebuffer(&all->info);
576 printk(KERN_ERR "cg14: Could not register framebuffer.\n"); 553 if (err < 0) {
577 fb_dealloc_cmap(&all->info.cmap); 554 fb_dealloc_cmap(&all->info.cmap);
555 cg14_unmap_regs(all);
578 kfree(all); 556 kfree(all);
579 return; 557 return err;
580 } 558 }
581 559
582 list_add(&all->list, &cg14_list); 560 dev_set_drvdata(&op->dev, all);
583 561
584 printk("cg14: cgfourteen at %lx:%lx, %dMB\n", 562 printk("%s: cgfourteen at %lx:%lx, %dMB\n",
585 all->par.iospace, all->par.physbase, all->par.ramsize >> 20); 563 dp->full_name,
564 all->par.iospace, all->par.physbase,
565 all->par.ramsize >> 20);
586 566
567 return 0;
587} 568}
588 569
589int __init cg14_init(void) 570static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id *match)
590{ 571{
591 struct sbus_bus *sbus; 572 struct of_device *op = to_of_device(&dev->dev);
592 struct sbus_dev *sdev;
593 573
594 if (fb_get_options("cg14fb", NULL)) 574 return cg14_init_one(op);
595 return -ENODEV; 575}
596 576
597#ifdef CONFIG_SPARC32 577static int __devexit cg14_remove(struct of_device *dev)
598 { 578{
599 int root, node; 579 struct all_info *all = dev_get_drvdata(&dev->dev);
600 580
601 root = prom_getchild(prom_root_node); 581 unregister_framebuffer(&all->info);
602 root = prom_searchsiblings(root, "obio"); 582 fb_dealloc_cmap(&all->info.cmap);
603 if (root) { 583
604 node = prom_searchsiblings(prom_getchild(root), 584 cg14_unmap_regs(all);
605 "cgfourteen"); 585
606 if (node) 586 kfree(all);
607 cg14_init_one(NULL, node, root); 587
608 } 588 dev_set_drvdata(&dev->dev, NULL);
609 }
610#endif
611 for_all_sbusdev(sdev, sbus) {
612 if (!strcmp(sdev->prom_name, "cgfourteen"))
613 cg14_init_one(sdev, sdev->prom_node, sbus->prom_node);
614 }
615 589
616 return 0; 590 return 0;
617} 591}
618 592
619void __exit cg14_exit(void) 593static struct of_device_id cg14_match[] = {
620{ 594 {
621 struct list_head *pos, *tmp; 595 .name = "cgfourteen",
596 },
597 {},
598};
599MODULE_DEVICE_TABLE(of, cg14_match);
622 600
623 list_for_each_safe(pos, tmp, &cg14_list) { 601static struct of_platform_driver cg14_driver = {
624 struct all_info *all = list_entry(pos, typeof(*all), list); 602 .name = "cg14",
603 .match_table = cg14_match,
604 .probe = cg14_probe,
605 .remove = __devexit_p(cg14_remove),
606};
625 607
626 unregister_framebuffer(&all->info); 608int __init cg14_init(void)
627 fb_dealloc_cmap(&all->info.cmap); 609{
628 kfree(all); 610 if (fb_get_options("cg14fb", NULL))
629 } 611 return -ENODEV;
612
613 return of_register_driver(&cg14_driver, &of_bus_type);
630} 614}
631 615
632int __init 616void __exit cg14_exit(void)
633cg14_setup(char *arg)
634{ 617{
635 /* No cmdline options yet... */ 618 of_unregister_driver(&cg14_driver);
636 return 0;
637} 619}
638 620
639module_init(cg14_init); 621module_init(cg14_init);
640
641#ifdef MODULE
642module_exit(cg14_exit); 622module_exit(cg14_exit);
643#endif
644 623
645MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets"); 624MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets");
646MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 625MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
626MODULE_VERSION("2.0");
647MODULE_LICENSE("GPL"); 627MODULE_LICENSE("GPL");
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 3de6e1b5ab2f..9c8c753ef454 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -1,6 +1,6 @@
1/* cg3.c: CGTHREE frame buffer driver 1/* cg3.c: CGTHREE frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) 6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,9 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20 20
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/sbus.h>
23#include <asm/oplib.h> 22#include <asm/oplib.h>
23#include <asm/prom.h>
24#include <asm/of_device.h>
24#include <asm/fbio.h> 25#include <asm/fbio.h>
25 26
26#include "sbuslib.h" 27#include "sbuslib.h"
@@ -80,30 +81,30 @@ enum cg3_type {
80}; 81};
81 82
82struct bt_regs { 83struct bt_regs {
83 volatile u32 addr; 84 u32 addr;
84 volatile u32 color_map; 85 u32 color_map;
85 volatile u32 control; 86 u32 control;
86 volatile u32 cursor; 87 u32 cursor;
87}; 88};
88 89
89struct cg3_regs { 90struct cg3_regs {
90 struct bt_regs cmap; 91 struct bt_regs cmap;
91 volatile u8 control; 92 u8 control;
92 volatile u8 status; 93 u8 status;
93 volatile u8 cursor_start; 94 u8 cursor_start;
94 volatile u8 cursor_end; 95 u8 cursor_end;
95 volatile u8 h_blank_start; 96 u8 h_blank_start;
96 volatile u8 h_blank_end; 97 u8 h_blank_end;
97 volatile u8 h_sync_start; 98 u8 h_sync_start;
98 volatile u8 h_sync_end; 99 u8 h_sync_end;
99 volatile u8 comp_sync_end; 100 u8 comp_sync_end;
100 volatile u8 v_blank_start_high; 101 u8 v_blank_start_high;
101 volatile u8 v_blank_start_low; 102 u8 v_blank_start_low;
102 volatile u8 v_blank_end; 103 u8 v_blank_end;
103 volatile u8 v_sync_start; 104 u8 v_sync_start;
104 volatile u8 v_sync_end; 105 u8 v_sync_end;
105 volatile u8 xfer_holdoff_start; 106 u8 xfer_holdoff_start;
106 volatile u8 xfer_holdoff_end; 107 u8 xfer_holdoff_end;
107}; 108};
108 109
109/* Offset of interesting structures in the OBIO space */ 110/* Offset of interesting structures in the OBIO space */
@@ -120,9 +121,8 @@ struct cg3_par {
120#define CG3_FLAG_RDI 0x00000002 121#define CG3_FLAG_RDI 0x00000002
121 122
122 unsigned long physbase; 123 unsigned long physbase;
124 unsigned long which_io;
123 unsigned long fbsize; 125 unsigned long fbsize;
124
125 struct sbus_dev *sdev;
126}; 126};
127 127
128/** 128/**
@@ -235,7 +235,7 @@ static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
235 235
236 return sbusfb_mmap_helper(cg3_mmap_map, 236 return sbusfb_mmap_helper(cg3_mmap_map,
237 par->physbase, par->fbsize, 237 par->physbase, par->fbsize,
238 par->sdev->reg_addrs[0].which_io, 238 par->which_io,
239 vma); 239 vma);
240} 240}
241 241
@@ -252,11 +252,9 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
252 */ 252 */
253 253
254static void 254static void
255cg3_init_fix(struct fb_info *info, int linebytes) 255cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
256{ 256{
257 struct cg3_par *par = (struct cg3_par *)info->par; 257 strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
258
259 strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
260 258
261 info->fix.type = FB_TYPE_PACKED_PIXELS; 259 info->fix.type = FB_TYPE_PACKED_PIXELS;
262 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 260 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -267,16 +265,15 @@ cg3_init_fix(struct fb_info *info, int linebytes)
267} 265}
268 266
269static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var, 267static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
270 struct sbus_dev *sdev) 268 struct device_node *dp)
271{ 269{
272 char buffer[40]; 270 char *params;
273 char *p; 271 char *p;
274 int ww, hh; 272 int ww, hh;
275 273
276 *buffer = 0; 274 params = of_get_property(dp, "params", NULL);
277 prom_getstring(sdev->prom_node, "params", buffer, sizeof(buffer)); 275 if (params) {
278 if (*buffer) { 276 ww = simple_strtoul(params, &p, 10);
279 ww = simple_strtoul(buffer, &p, 10);
280 if (ww && *p == 'x') { 277 if (ww && *p == 'x') {
281 hh = simple_strtoul(p + 1, &p, 10); 278 hh = simple_strtoul(p + 1, &p, 10);
282 if (hh && *p == '-') { 279 if (hh && *p == '-') {
@@ -348,11 +345,11 @@ static void cg3_do_default_mode(struct cg3_par *par)
348 sbus_writeb(p[1], regp); 345 sbus_writeb(p[1], regp);
349 } 346 }
350 for (p = cg3_dacvals; *p; p += 2) { 347 for (p = cg3_dacvals; *p; p += 2) {
351 volatile u8 __iomem *regp; 348 u8 __iomem *regp;
352 349
353 regp = (volatile u8 __iomem *)&par->regs->cmap.addr; 350 regp = (u8 __iomem *)&par->regs->cmap.addr;
354 sbus_writeb(p[0], regp); 351 sbus_writeb(p[0], regp);
355 regp = (volatile u8 __iomem *)&par->regs->cmap.control; 352 regp = (u8 __iomem *)&par->regs->cmap.control;
356 sbus_writeb(p[1], regp); 353 sbus_writeb(p[1], regp);
357 } 354 }
358} 355}
@@ -360,129 +357,137 @@ static void cg3_do_default_mode(struct cg3_par *par)
360struct all_info { 357struct all_info {
361 struct fb_info info; 358 struct fb_info info;
362 struct cg3_par par; 359 struct cg3_par par;
363 struct list_head list;
364}; 360};
365static LIST_HEAD(cg3_list);
366 361
367static void cg3_init_one(struct sbus_dev *sdev) 362static int __devinit cg3_init_one(struct of_device *op)
368{ 363{
364 struct device_node *dp = op->node;
369 struct all_info *all; 365 struct all_info *all;
370 int linebytes; 366 int linebytes, err;
371
372 all = kmalloc(sizeof(*all), GFP_KERNEL);
373 if (!all) {
374 printk(KERN_ERR "cg3: Cannot allocate memory.\n");
375 return;
376 }
377 memset(all, 0, sizeof(*all));
378 367
379 INIT_LIST_HEAD(&all->list); 368 all = kzalloc(sizeof(*all), GFP_KERNEL);
369 if (!all)
370 return -ENOMEM;
380 371
381 spin_lock_init(&all->par.lock); 372 spin_lock_init(&all->par.lock);
382 all->par.sdev = sdev;
383 373
384 all->par.physbase = sdev->reg_addrs[0].phys_addr; 374 all->par.physbase = op->resource[0].start;
375 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
385 376
386 sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 377 sbusfb_fill_var(&all->info.var, dp->node, 8);
387 all->info.var.red.length = 8; 378 all->info.var.red.length = 8;
388 all->info.var.green.length = 8; 379 all->info.var.green.length = 8;
389 all->info.var.blue.length = 8; 380 all->info.var.blue.length = 8;
390 if (!strcmp(sdev->prom_name, "cgRDI")) 381 if (!strcmp(dp->name, "cgRDI"))
391 all->par.flags |= CG3_FLAG_RDI; 382 all->par.flags |= CG3_FLAG_RDI;
392 if (all->par.flags & CG3_FLAG_RDI) 383 if (all->par.flags & CG3_FLAG_RDI)
393 cg3_rdi_maybe_fixup_var(&all->info.var, sdev); 384 cg3_rdi_maybe_fixup_var(&all->info.var, dp);
394 385
395 linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 386 linebytes = of_getintprop_default(dp, "linebytes",
396 all->info.var.xres); 387 all->info.var.xres);
397 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 388 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
398 389
399 all->par.regs = sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET, 390 all->par.regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET,
400 sizeof(struct cg3_regs), "cg3 regs"); 391 sizeof(struct cg3_regs), "cg3 regs");
401 392
402 all->info.flags = FBINFO_DEFAULT; 393 all->info.flags = FBINFO_DEFAULT;
403 all->info.fbops = &cg3_ops; 394 all->info.fbops = &cg3_ops;
404#ifdef CONFIG_SPARC32 395 all->info.screen_base =
405 all->info.screen_base = (char __iomem *) 396 of_ioremap(&op->resource[0], CG3_RAM_OFFSET,
406 prom_getintdefault(sdev->prom_node, "address", 0); 397 all->par.fbsize, "cg3 ram");
407#endif
408 if (!all->info.screen_base)
409 all->info.screen_base =
410 sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
411 all->par.fbsize, "cg3 ram");
412 all->info.par = &all->par; 398 all->info.par = &all->par;
413 399
414 cg3_blank(0, &all->info); 400 cg3_blank(0, &all->info);
415 401
416 if (!prom_getbool(sdev->prom_node, "width")) 402 if (!of_find_property(dp, "width", NULL))
417 cg3_do_default_mode(&all->par); 403 cg3_do_default_mode(&all->par);
418 404
419 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 405 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
420 printk(KERN_ERR "cg3: Could not allocate color map.\n"); 406 of_iounmap(all->par.regs, sizeof(struct cg3_regs));
407 of_iounmap(all->info.screen_base, all->par.fbsize);
421 kfree(all); 408 kfree(all);
422 return; 409 return -ENOMEM;
423 } 410 }
424 fb_set_cmap(&all->info.cmap, &all->info); 411 fb_set_cmap(&all->info.cmap, &all->info);
425 412
426 cg3_init_fix(&all->info, linebytes); 413 cg3_init_fix(&all->info, linebytes, dp);
427 414
428 if (register_framebuffer(&all->info) < 0) { 415 err = register_framebuffer(&all->info);
429 printk(KERN_ERR "cg3: Could not register framebuffer.\n"); 416 if (err < 0) {
430 fb_dealloc_cmap(&all->info.cmap); 417 fb_dealloc_cmap(&all->info.cmap);
418 of_iounmap(all->par.regs, sizeof(struct cg3_regs));
419 of_iounmap(all->info.screen_base, all->par.fbsize);
431 kfree(all); 420 kfree(all);
432 return; 421 return err;
433 } 422 }
434 423
435 list_add(&all->list, &cg3_list); 424 dev_set_drvdata(&op->dev, all);
425
426 printk("%s: cg3 at %lx:%lx\n",
427 dp->full_name, all->par.which_io, all->par.physbase);
436 428
437 printk("cg3: %s at %lx:%lx\n", 429 return 0;
438 sdev->prom_name,
439 (long) sdev->reg_addrs[0].which_io,
440 (long) sdev->reg_addrs[0].phys_addr);
441} 430}
442 431
443int __init cg3_init(void) 432static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id *match)
444{ 433{
445 struct sbus_bus *sbus; 434 struct of_device *op = to_of_device(&dev->dev);
446 struct sbus_dev *sdev;
447 435
448 if (fb_get_options("cg3fb", NULL)) 436 return cg3_init_one(op);
449 return -ENODEV; 437}
450 438
451 for_all_sbusdev(sdev, sbus) { 439static int __devexit cg3_remove(struct of_device *dev)
452 if (!strcmp(sdev->prom_name, "cgthree") || 440{
453 !strcmp(sdev->prom_name, "cgRDI")) 441 struct all_info *all = dev_get_drvdata(&dev->dev);
454 cg3_init_one(sdev); 442
455 } 443 unregister_framebuffer(&all->info);
444 fb_dealloc_cmap(&all->info.cmap);
445
446 of_iounmap(all->par.regs, sizeof(struct cg3_regs));
447 of_iounmap(all->info.screen_base, all->par.fbsize);
448
449 kfree(all);
450
451 dev_set_drvdata(&dev->dev, NULL);
456 452
457 return 0; 453 return 0;
458} 454}
459 455
460void __exit cg3_exit(void) 456static struct of_device_id cg3_match[] = {
461{ 457 {
462 struct list_head *pos, *tmp; 458 .name = "cgthree",
459 },
460 {
461 .name = "cgRDI",
462 },
463 {},
464};
465MODULE_DEVICE_TABLE(of, cg3_match);
463 466
464 list_for_each_safe(pos, tmp, &cg3_list) { 467static struct of_platform_driver cg3_driver = {
465 struct all_info *all = list_entry(pos, typeof(*all), list); 468 .name = "cg3",
469 .match_table = cg3_match,
470 .probe = cg3_probe,
471 .remove = __devexit_p(cg3_remove),
472};
466 473
467 unregister_framebuffer(&all->info); 474static int __init cg3_init(void)
468 fb_dealloc_cmap(&all->info.cmap); 475{
469 kfree(all); 476 if (fb_get_options("cg3fb", NULL))
470 } 477 return -ENODEV;
478
479 return of_register_driver(&cg3_driver, &of_bus_type);
471} 480}
472 481
473int __init 482static void __exit cg3_exit(void)
474cg3_setup(char *arg)
475{ 483{
476 /* No cmdline options yet... */ 484 of_unregister_driver(&cg3_driver);
477 return 0;
478} 485}
479 486
480module_init(cg3_init); 487module_init(cg3_init);
481
482#ifdef MODULE
483module_exit(cg3_exit); 488module_exit(cg3_exit);
484#endif
485 489
486MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets"); 490MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets");
487MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 491MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
492MODULE_VERSION("2.0");
488MODULE_LICENSE("GPL"); 493MODULE_LICENSE("GPL");
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 7aab91ead681..64146be2eeb0 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -1,6 +1,6 @@
1/* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver 1/* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) 6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,8 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20 20
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/sbus.h> 22#include <asm/prom.h>
23#include <asm/oplib.h> 23#include <asm/of_device.h>
24#include <asm/fbio.h> 24#include <asm/fbio.h>
25 25
26#include "sbuslib.h" 26#include "sbuslib.h"
@@ -164,89 +164,89 @@ static struct fb_ops cg6_ops = {
164 164
165/* The contents are unknown */ 165/* The contents are unknown */
166struct cg6_tec { 166struct cg6_tec {
167 volatile int tec_matrix; 167 int tec_matrix;
168 volatile int tec_clip; 168 int tec_clip;
169 volatile int tec_vdc; 169 int tec_vdc;
170}; 170};
171 171
172struct cg6_thc { 172struct cg6_thc {
173 uint thc_pad0[512]; 173 u32 thc_pad0[512];
174 volatile uint thc_hs; /* hsync timing */ 174 u32 thc_hs; /* hsync timing */
175 volatile uint thc_hsdvs; 175 u32 thc_hsdvs;
176 volatile uint thc_hd; 176 u32 thc_hd;
177 volatile uint thc_vs; /* vsync timing */ 177 u32 thc_vs; /* vsync timing */
178 volatile uint thc_vd; 178 u32 thc_vd;
179 volatile uint thc_refresh; 179 u32 thc_refresh;
180 volatile uint thc_misc; 180 u32 thc_misc;
181 uint thc_pad1[56]; 181 u32 thc_pad1[56];
182 volatile uint thc_cursxy; /* cursor x,y position (16 bits each) */ 182 u32 thc_cursxy; /* cursor x,y position (16 bits each) */
183 volatile uint thc_cursmask[32]; /* cursor mask bits */ 183 u32 thc_cursmask[32]; /* cursor mask bits */
184 volatile uint thc_cursbits[32]; /* what to show where mask enabled */ 184 u32 thc_cursbits[32]; /* what to show where mask enabled */
185}; 185};
186 186
187struct cg6_fbc { 187struct cg6_fbc {
188 u32 xxx0[1]; 188 u32 xxx0[1];
189 volatile u32 mode; 189 u32 mode;
190 volatile u32 clip; 190 u32 clip;
191 u32 xxx1[1]; 191 u32 xxx1[1];
192 volatile u32 s; 192 u32 s;
193 volatile u32 draw; 193 u32 draw;
194 volatile u32 blit; 194 u32 blit;
195 volatile u32 font; 195 u32 font;
196 u32 xxx2[24]; 196 u32 xxx2[24];
197 volatile u32 x0, y0, z0, color0; 197 u32 x0, y0, z0, color0;
198 volatile u32 x1, y1, z1, color1; 198 u32 x1, y1, z1, color1;
199 volatile u32 x2, y2, z2, color2; 199 u32 x2, y2, z2, color2;
200 volatile u32 x3, y3, z3, color3; 200 u32 x3, y3, z3, color3;
201 volatile u32 offx, offy; 201 u32 offx, offy;
202 u32 xxx3[2]; 202 u32 xxx3[2];
203 volatile u32 incx, incy; 203 u32 incx, incy;
204 u32 xxx4[2]; 204 u32 xxx4[2];
205 volatile u32 clipminx, clipminy; 205 u32 clipminx, clipminy;
206 u32 xxx5[2]; 206 u32 xxx5[2];
207 volatile u32 clipmaxx, clipmaxy; 207 u32 clipmaxx, clipmaxy;
208 u32 xxx6[2]; 208 u32 xxx6[2];
209 volatile u32 fg; 209 u32 fg;
210 volatile u32 bg; 210 u32 bg;
211 volatile u32 alu; 211 u32 alu;
212 volatile u32 pm; 212 u32 pm;
213 volatile u32 pixelm; 213 u32 pixelm;
214 u32 xxx7[2]; 214 u32 xxx7[2];
215 volatile u32 patalign; 215 u32 patalign;
216 volatile u32 pattern[8]; 216 u32 pattern[8];
217 u32 xxx8[432]; 217 u32 xxx8[432];
218 volatile u32 apointx, apointy, apointz; 218 u32 apointx, apointy, apointz;
219 u32 xxx9[1]; 219 u32 xxx9[1];
220 volatile u32 rpointx, rpointy, rpointz; 220 u32 rpointx, rpointy, rpointz;
221 u32 xxx10[5]; 221 u32 xxx10[5];
222 volatile u32 pointr, pointg, pointb, pointa; 222 u32 pointr, pointg, pointb, pointa;
223 volatile u32 alinex, aliney, alinez; 223 u32 alinex, aliney, alinez;
224 u32 xxx11[1]; 224 u32 xxx11[1];
225 volatile u32 rlinex, rliney, rlinez; 225 u32 rlinex, rliney, rlinez;
226 u32 xxx12[5]; 226 u32 xxx12[5];
227 volatile u32 liner, lineg, lineb, linea; 227 u32 liner, lineg, lineb, linea;
228 volatile u32 atrix, atriy, atriz; 228 u32 atrix, atriy, atriz;
229 u32 xxx13[1]; 229 u32 xxx13[1];
230 volatile u32 rtrix, rtriy, rtriz; 230 u32 rtrix, rtriy, rtriz;
231 u32 xxx14[5]; 231 u32 xxx14[5];
232 volatile u32 trir, trig, trib, tria; 232 u32 trir, trig, trib, tria;
233 volatile u32 aquadx, aquady, aquadz; 233 u32 aquadx, aquady, aquadz;
234 u32 xxx15[1]; 234 u32 xxx15[1];
235 volatile u32 rquadx, rquady, rquadz; 235 u32 rquadx, rquady, rquadz;
236 u32 xxx16[5]; 236 u32 xxx16[5];
237 volatile u32 quadr, quadg, quadb, quada; 237 u32 quadr, quadg, quadb, quada;
238 volatile u32 arectx, arecty, arectz; 238 u32 arectx, arecty, arectz;
239 u32 xxx17[1]; 239 u32 xxx17[1];
240 volatile u32 rrectx, rrecty, rrectz; 240 u32 rrectx, rrecty, rrectz;
241 u32 xxx18[5]; 241 u32 xxx18[5];
242 volatile u32 rectr, rectg, rectb, recta; 242 u32 rectr, rectg, rectb, recta;
243}; 243};
244 244
245struct bt_regs { 245struct bt_regs {
246 volatile u32 addr; 246 u32 addr;
247 volatile u32 color_map; 247 u32 color_map;
248 volatile u32 control; 248 u32 control;
249 volatile u32 cursor; 249 u32 cursor;
250}; 250};
251 251
252struct cg6_par { 252struct cg6_par {
@@ -255,15 +255,14 @@ struct cg6_par {
255 struct cg6_fbc __iomem *fbc; 255 struct cg6_fbc __iomem *fbc;
256 struct cg6_thc __iomem *thc; 256 struct cg6_thc __iomem *thc;
257 struct cg6_tec __iomem *tec; 257 struct cg6_tec __iomem *tec;
258 volatile u32 __iomem *fhc; 258 u32 __iomem *fhc;
259 259
260 u32 flags; 260 u32 flags;
261#define CG6_FLAG_BLANKED 0x00000001 261#define CG6_FLAG_BLANKED 0x00000001
262 262
263 unsigned long physbase; 263 unsigned long physbase;
264 unsigned long which_io;
264 unsigned long fbsize; 265 unsigned long fbsize;
265
266 struct sbus_dev *sdev;
267}; 266};
268 267
269static int cg6_sync(struct fb_info *info) 268static int cg6_sync(struct fb_info *info)
@@ -529,8 +528,7 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
529 528
530 return sbusfb_mmap_helper(cg6_mmap_map, 529 return sbusfb_mmap_helper(cg6_mmap_map,
531 par->physbase, par->fbsize, 530 par->physbase, par->fbsize,
532 par->sdev->reg_addrs[0].which_io, 531 par->which_io, vma);
533 vma);
534} 532}
535 533
536static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 534static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
@@ -658,62 +656,75 @@ static void cg6_chip_init(struct fb_info *info)
658struct all_info { 656struct all_info {
659 struct fb_info info; 657 struct fb_info info;
660 struct cg6_par par; 658 struct cg6_par par;
661 struct list_head list;
662}; 659};
663static LIST_HEAD(cg6_list);
664 660
665static void cg6_init_one(struct sbus_dev *sdev) 661static void cg6_unmap_regs(struct all_info *all)
666{ 662{
667 struct all_info *all; 663 if (all->par.fbc)
668 int linebytes; 664 of_iounmap(all->par.fbc, 4096);
665 if (all->par.tec)
666 of_iounmap(all->par.tec, sizeof(struct cg6_tec));
667 if (all->par.thc)
668 of_iounmap(all->par.thc, sizeof(struct cg6_thc));
669 if (all->par.bt)
670 of_iounmap(all->par.bt, sizeof(struct bt_regs));
671 if (all->par.fhc)
672 of_iounmap(all->par.fhc, sizeof(u32));
673
674 if (all->info.screen_base)
675 of_iounmap(all->info.screen_base, all->par.fbsize);
676}
669 677
670 all = kmalloc(sizeof(*all), GFP_KERNEL); 678static int __devinit cg6_init_one(struct of_device *op)
671 if (!all) { 679{
672 printk(KERN_ERR "cg6: Cannot allocate memory.\n"); 680 struct device_node *dp = op->node;
673 return; 681 struct all_info *all;
674 } 682 int linebytes, err;
675 memset(all, 0, sizeof(*all));
676 683
677 INIT_LIST_HEAD(&all->list); 684 all = kzalloc(sizeof(*all), GFP_KERNEL);
685 if (!all)
686 return -ENOMEM;
678 687
679 spin_lock_init(&all->par.lock); 688 spin_lock_init(&all->par.lock);
680 all->par.sdev = sdev;
681 689
682 all->par.physbase = sdev->reg_addrs[0].phys_addr; 690 all->par.physbase = op->resource[0].start;
691 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
683 692
684 sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 693 sbusfb_fill_var(&all->info.var, dp->node, 8);
685 all->info.var.red.length = 8; 694 all->info.var.red.length = 8;
686 all->info.var.green.length = 8; 695 all->info.var.green.length = 8;
687 all->info.var.blue.length = 8; 696 all->info.var.blue.length = 8;
688 697
689 linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 698 linebytes = of_getintprop_default(dp, "linebytes",
690 all->info.var.xres); 699 all->info.var.xres);
691 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 700 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
692 if (prom_getbool(sdev->prom_node, "dblbuf")) 701 if (of_find_property(dp, "dblbuf", NULL))
693 all->par.fbsize *= 4; 702 all->par.fbsize *= 4;
694 703
695 all->par.fbc = sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET, 704 all->par.fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET,
696 4096, "cgsix fbc"); 705 4096, "cgsix fbc");
697 all->par.tec = sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET, 706 all->par.tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET,
698 sizeof(struct cg6_tec), "cgsix tec"); 707 sizeof(struct cg6_tec), "cgsix tec");
699 all->par.thc = sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET, 708 all->par.thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET,
700 sizeof(struct cg6_thc), "cgsix thc"); 709 sizeof(struct cg6_thc), "cgsix thc");
701 all->par.bt = sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET, 710 all->par.bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET,
702 sizeof(struct bt_regs), "cgsix dac"); 711 sizeof(struct bt_regs), "cgsix dac");
703 all->par.fhc = sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET, 712 all->par.fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET,
704 sizeof(u32), "cgsix fhc"); 713 sizeof(u32), "cgsix fhc");
705 714
706 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | 715 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT |
707 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; 716 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
708 all->info.fbops = &cg6_ops; 717 all->info.fbops = &cg6_ops;
709#ifdef CONFIG_SPARC32 718
710 all->info.screen_base = (char __iomem *) 719 all->info.screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET,
711 prom_getintdefault(sdev->prom_node, "address", 0); 720 all->par.fbsize, "cgsix ram");
712#endif 721 if (!all->par.fbc || !all->par.tec || !all->par.thc ||
713 if (!all->info.screen_base) 722 !all->par.bt || !all->par.fhc || !all->info.screen_base) {
714 all->info.screen_base = 723 cg6_unmap_regs(all);
715 sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET, 724 kfree(all);
716 all->par.fbsize, "cgsix ram"); 725 return -ENOMEM;
726 }
727
717 all->info.par = &all->par; 728 all->info.par = &all->par;
718 729
719 all->info.var.accel_flags = FB_ACCELF_TEXT; 730 all->info.var.accel_flags = FB_ACCELF_TEXT;
@@ -723,72 +734,90 @@ static void cg6_init_one(struct sbus_dev *sdev)
723 cg6_blank(0, &all->info); 734 cg6_blank(0, &all->info);
724 735
725 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 736 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
726 printk(KERN_ERR "cg6: Could not allocate color map.\n"); 737 cg6_unmap_regs(all);
727 kfree(all); 738 kfree(all);
728 return; 739 return -ENOMEM;
729 } 740 }
730 741
731 fb_set_cmap(&all->info.cmap, &all->info); 742 fb_set_cmap(&all->info.cmap, &all->info);
732 cg6_init_fix(&all->info, linebytes); 743 cg6_init_fix(&all->info, linebytes);
733 744
734 if (register_framebuffer(&all->info) < 0) { 745 err = register_framebuffer(&all->info);
735 printk(KERN_ERR "cg6: Could not register framebuffer.\n"); 746 if (err < 0) {
747 cg6_unmap_regs(all);
736 fb_dealloc_cmap(&all->info.cmap); 748 fb_dealloc_cmap(&all->info.cmap);
737 kfree(all); 749 kfree(all);
738 return; 750 return err;
739 } 751 }
740 752
741 list_add(&all->list, &cg6_list); 753 dev_set_drvdata(&op->dev, all);
742 754
743 printk("cg6: CGsix [%s] at %lx:%lx\n", 755 printk("%s: CGsix [%s] at %lx:%lx\n",
756 dp->full_name,
744 all->info.fix.id, 757 all->info.fix.id,
745 (long) sdev->reg_addrs[0].which_io, 758 all->par.which_io, all->par.physbase);
746 (long) sdev->reg_addrs[0].phys_addr); 759
760 return 0;
747} 761}
748 762
749int __init cg6_init(void) 763static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id *match)
750{ 764{
751 struct sbus_bus *sbus; 765 struct of_device *op = to_of_device(&dev->dev);
752 struct sbus_dev *sdev;
753 766
754 if (fb_get_options("cg6fb", NULL)) 767 return cg6_init_one(op);
755 return -ENODEV; 768}
756 769
757 for_all_sbusdev(sdev, sbus) { 770static int __devexit cg6_remove(struct of_device *dev)
758 if (!strcmp(sdev->prom_name, "cgsix") || 771{
759 !strcmp(sdev->prom_name, "cgthree+")) 772 struct all_info *all = dev_get_drvdata(&dev->dev);
760 cg6_init_one(sdev); 773
761 } 774 unregister_framebuffer(&all->info);
775 fb_dealloc_cmap(&all->info.cmap);
776
777 cg6_unmap_regs(all);
778
779 kfree(all);
780
781 dev_set_drvdata(&dev->dev, NULL);
762 782
763 return 0; 783 return 0;
764} 784}
765 785
766void __exit cg6_exit(void) 786static struct of_device_id cg6_match[] = {
767{ 787 {
768 struct list_head *pos, *tmp; 788 .name = "cgsix",
789 },
790 {
791 .name = "cgthree+",
792 },
793 {},
794};
795MODULE_DEVICE_TABLE(of, cg6_match);
769 796
770 list_for_each_safe(pos, tmp, &cg6_list) { 797static struct of_platform_driver cg6_driver = {
771 struct all_info *all = list_entry(pos, typeof(*all), list); 798 .name = "cg6",
799 .match_table = cg6_match,
800 .probe = cg6_probe,
801 .remove = __devexit_p(cg6_remove),
802};
772 803
773 unregister_framebuffer(&all->info); 804static int __init cg6_init(void)
774 fb_dealloc_cmap(&all->info.cmap); 805{
775 kfree(all); 806 if (fb_get_options("cg6fb", NULL))
776 } 807 return -ENODEV;
808
809 return of_register_driver(&cg6_driver, &of_bus_type);
777} 810}
778 811
779int __init 812static void __exit cg6_exit(void)
780cg6_setup(char *arg)
781{ 813{
782 /* No cmdline options yet... */ 814 of_unregister_driver(&cg6_driver);
783 return 0;
784} 815}
785 816
786module_init(cg6_init); 817module_init(cg6_init);
787
788#ifdef MODULE
789module_exit(cg6_exit); 818module_exit(cg6_exit);
790#endif
791 819
792MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets"); 820MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets");
793MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 821MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
822MODULE_VERSION("2.0");
794MODULE_LICENSE("GPL"); 823MODULE_LICENSE("GPL");
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 72ff6bf75e5e..73cb426bf2d7 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -14,13 +14,11 @@
14 * more details. 14 * more details.
15 */ 15 */
16 16
17#include <linux/config.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/errno.h> 19#include <linux/errno.h>
21#include <linux/string.h> 20#include <linux/string.h>
22#include <linux/mm.h> 21#include <linux/mm.h>
23#include <linux/tty.h>
24#include <linux/slab.h> 22#include <linux/slab.h>
25#include <linux/vmalloc.h> 23#include <linux/vmalloc.h>
26#include <linux/delay.h> 24#include <linux/delay.h>
@@ -148,9 +146,23 @@ static int chipsfb_set_par(struct fb_info *info)
148static int chipsfb_blank(int blank, struct fb_info *info) 146static int chipsfb_blank(int blank, struct fb_info *info)
149{ 147{
150#ifdef CONFIG_PMAC_BACKLIGHT 148#ifdef CONFIG_PMAC_BACKLIGHT
151 // used to disable backlight only for blank > 1, but it seems 149 mutex_lock(&pmac_backlight_mutex);
152 // useful at blank = 1 too (saves battery, extends backlight life) 150
153 set_backlight_enable(!blank); 151 if (pmac_backlight) {
152 /* used to disable backlight only for blank > 1, but it seems
153 * useful at blank = 1 too (saves battery, extends backlight
154 * life)
155 */
156 down(&pmac_backlight->sem);
157 if (blank)
158 pmac_backlight->props->power = FB_BLANK_POWERDOWN;
159 else
160 pmac_backlight->props->power = FB_BLANK_UNBLANK;
161 pmac_backlight->props->update_status(pmac_backlight);
162 up(&pmac_backlight->sem);
163 }
164
165 mutex_unlock(&pmac_backlight_mutex);
154#endif /* CONFIG_PMAC_BACKLIGHT */ 166#endif /* CONFIG_PMAC_BACKLIGHT */
155 167
156 return 1; /* get fb_blank to set the colormap to all black */ 168 return 1; /* get fb_blank to set the colormap to all black */
@@ -401,7 +413,14 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
401 413
402#ifdef CONFIG_PMAC_BACKLIGHT 414#ifdef CONFIG_PMAC_BACKLIGHT
403 /* turn on the backlight */ 415 /* turn on the backlight */
404 set_backlight_enable(1); 416 mutex_lock(&pmac_backlight_mutex);
417 if (pmac_backlight) {
418 down(&pmac_backlight->sem);
419 pmac_backlight->props->power = FB_BLANK_UNBLANK;
420 pmac_backlight->props->update_status(pmac_backlight);
421 up(&pmac_backlight->sem);
422 }
423 mutex_unlock(&pmac_backlight_mutex);
405#endif /* CONFIG_PMAC_BACKLIGHT */ 424#endif /* CONFIG_PMAC_BACKLIGHT */
406 425
407#ifdef CONFIG_PPC 426#ifdef CONFIG_PPC
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 1103010af54a..daf43f535a0b 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -36,13 +36,11 @@
36 36
37#define CIRRUSFB_VERSION "2.0-pre2" 37#define CIRRUSFB_VERSION "2.0-pre2"
38 38
39#include <linux/config.h>
40#include <linux/module.h> 39#include <linux/module.h>
41#include <linux/kernel.h> 40#include <linux/kernel.h>
42#include <linux/errno.h> 41#include <linux/errno.h>
43#include <linux/string.h> 42#include <linux/string.h>
44#include <linux/mm.h> 43#include <linux/mm.h>
45#include <linux/tty.h>
46#include <linux/slab.h> 44#include <linux/slab.h>
47#include <linux/delay.h> 45#include <linux/delay.h>
48#include <linux/fb.h> 46#include <linux/fb.h>
@@ -2227,7 +2225,6 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo)
2227 release_region(0x3C0, 32); 2225 release_region(0x3C0, 32);
2228 pci_release_regions(pdev); 2226 pci_release_regions(pdev);
2229 framebuffer_release(cinfo->info); 2227 framebuffer_release(cinfo->info);
2230 pci_disable_device(pdev);
2231} 2228}
2232#endif /* CONFIG_PCI */ 2229#endif /* CONFIG_PCI */
2233 2230
@@ -2458,7 +2455,6 @@ err_release_regions:
2458err_release_fb: 2455err_release_fb:
2459 framebuffer_release(info); 2456 framebuffer_release(info);
2460err_disable: 2457err_disable:
2461 pci_disable_device(pdev);
2462err_out: 2458err_out:
2463 return ret; 2459 return ret;
2464} 2460}
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 4444bef68fba..aa3935df852a 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
6 6
7config VGA_CONSOLE 7config VGA_CONSOLE
8 bool "VGA text console" if EMBEDDED || !X86 8 bool "VGA text console" if EMBEDDED || !X86
9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE 9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH
10 default y 10 default y
11 help 11 help
12 Saying Y here will allow you to use Linux in text mode through a 12 Saying Y here will allow you to use Linux in text mode through a
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index eea422eb1ab5..308850df16fe 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -10,7 +10,6 @@
10 * more details. 10 * more details.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/string.h> 14#include <linux/string.h>
16#include <linux/fb.h> 15#include <linux/fb.h>
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index 1ecda91e5a9c..d9315d99445f 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -7,9 +7,9 @@
7 7
8#include <linux/types.h> 8#include <linux/types.h>
9#include <linux/kdev_t.h> 9#include <linux/kdev_t.h>
10#include <linux/tty.h>
11#include <linux/console.h> 10#include <linux/console.h>
12#include <linux/vt_kern.h> 11#include <linux/vt_kern.h>
12#include <linux/screen_info.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15 15
@@ -22,7 +22,6 @@
22#define DUMMY_ROWS ORIG_VIDEO_LINES 22#define DUMMY_ROWS ORIG_VIDEO_LINES
23#elif defined(__hppa__) 23#elif defined(__hppa__)
24/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */ 24/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */
25#include <linux/config.h>
26#define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS 25#define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS
27#define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS 26#define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS
28#else 27#else
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 47ba1a79adcd..1b4f75d1f8a9 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -58,14 +58,12 @@
58 58
59#undef FBCONDEBUG 59#undef FBCONDEBUG
60 60
61#include <linux/config.h>
62#include <linux/module.h> 61#include <linux/module.h>
63#include <linux/types.h> 62#include <linux/types.h>
64#include <linux/sched.h> 63#include <linux/sched.h>
65#include <linux/fs.h> 64#include <linux/fs.h>
66#include <linux/kernel.h> 65#include <linux/kernel.h>
67#include <linux/delay.h> /* MSch: for IRQ probe */ 66#include <linux/delay.h> /* MSch: for IRQ probe */
68#include <linux/tty.h>
69#include <linux/console.h> 67#include <linux/console.h>
70#include <linux/string.h> 68#include <linux/string.h>
71#include <linux/kd.h> 69#include <linux/kd.h>
@@ -125,6 +123,8 @@ static int softback_lines;
125static int first_fb_vc; 123static int first_fb_vc;
126static int last_fb_vc = MAX_NR_CONSOLES - 1; 124static int last_fb_vc = MAX_NR_CONSOLES - 1;
127static int fbcon_is_default = 1; 125static int fbcon_is_default = 1;
126static int fbcon_has_exited;
127
128/* font data */ 128/* font data */
129static char fontname[40]; 129static char fontname[40];
130 130
@@ -140,7 +140,6 @@ static const struct consw fb_con;
140 140
141#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row) 141#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
142 142
143static void fbcon_free_font(struct display *);
144static int fbcon_set_origin(struct vc_data *); 143static int fbcon_set_origin(struct vc_data *);
145 144
146#define CURSOR_DRAW_DELAY (1) 145#define CURSOR_DRAW_DELAY (1)
@@ -194,6 +193,9 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
194 int line, int count, int dy); 193 int line, int count, int dy);
195static void fbcon_modechanged(struct fb_info *info); 194static void fbcon_modechanged(struct fb_info *info);
196static void fbcon_set_all_vcs(struct fb_info *info); 195static void fbcon_set_all_vcs(struct fb_info *info);
196static void fbcon_start(void);
197static void fbcon_exit(void);
198static struct class_device *fbcon_class_device;
197 199
198#ifdef CONFIG_MAC 200#ifdef CONFIG_MAC
199/* 201/*
@@ -252,7 +254,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
252 if (!ops || ops->currcon < 0 || rotate > 3) 254 if (!ops || ops->currcon < 0 || rotate > 3)
253 return; 255 return;
254 256
255 for (i = 0; i < MAX_NR_CONSOLES; i++) { 257 for (i = first_fb_vc; i <= last_fb_vc; i++) {
256 vc = vc_cons[i].d; 258 vc = vc_cons[i].d;
257 if (!vc || vc->vc_mode != KD_TEXT || 259 if (!vc || vc->vc_mode != KD_TEXT ||
258 registered_fb[con2fb_map[i]] != info) 260 registered_fb[con2fb_map[i]] != info)
@@ -389,15 +391,18 @@ static void fb_flashcursor(void *private)
389 int c; 391 int c;
390 int mode; 392 int mode;
391 393
392 if (ops->currcon != -1) 394 acquire_console_sem();
395 if (ops && ops->currcon != -1)
393 vc = vc_cons[ops->currcon].d; 396 vc = vc_cons[ops->currcon].d;
394 397
395 if (!vc || !CON_IS_VISIBLE(vc) || 398 if (!vc || !CON_IS_VISIBLE(vc) ||
396 fbcon_is_inactive(vc, info) || 399 fbcon_is_inactive(vc, info) ||
397 registered_fb[con2fb_map[vc->vc_num]] != info || 400 registered_fb[con2fb_map[vc->vc_num]] != info ||
398 vc_cons[ops->currcon].d->vc_deccm != 1) 401 vc_cons[ops->currcon].d->vc_deccm != 1) {
402 release_console_sem();
399 return; 403 return;
400 acquire_console_sem(); 404 }
405
401 p = &fb_display[vc->vc_num]; 406 p = &fb_display[vc->vc_num];
402 c = scr_readw((u16 *) vc->vc_pos); 407 c = scr_readw((u16 *) vc->vc_pos);
403 mode = (!ops->cursor_flash || ops->cursor_state.enable) ? 408 mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
@@ -528,7 +533,7 @@ static int search_fb_in_map(int idx)
528{ 533{
529 int i, retval = 0; 534 int i, retval = 0;
530 535
531 for (i = 0; i < MAX_NR_CONSOLES; i++) { 536 for (i = first_fb_vc; i <= last_fb_vc; i++) {
532 if (con2fb_map[i] == idx) 537 if (con2fb_map[i] == idx)
533 retval = 1; 538 retval = 1;
534 } 539 }
@@ -539,7 +544,7 @@ static int search_for_mapped_con(void)
539{ 544{
540 int i, retval = 0; 545 int i, retval = 0;
541 546
542 for (i = 0; i < MAX_NR_CONSOLES; i++) { 547 for (i = first_fb_vc; i <= last_fb_vc; i++) {
543 if (con2fb_map[i] != -1) 548 if (con2fb_map[i] != -1)
544 retval = 1; 549 retval = 1;
545 } 550 }
@@ -561,6 +566,7 @@ static int fbcon_takeover(int show_logo)
561 566
562 err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, 567 err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
563 fbcon_is_default); 568 fbcon_is_default);
569
564 if (err) { 570 if (err) {
565 for (i = first_fb_vc; i <= last_fb_vc; i++) { 571 for (i = first_fb_vc; i <= last_fb_vc; i++) {
566 con2fb_map[i] = -1; 572 con2fb_map[i] = -1;
@@ -795,8 +801,8 @@ static int set_con2fb_map(int unit, int newidx, int user)
795 if (oldidx == newidx) 801 if (oldidx == newidx)
796 return 0; 802 return 0;
797 803
798 if (!info) 804 if (!info || fbcon_has_exited)
799 err = -EINVAL; 805 return -EINVAL;
800 806
801 if (!err && !search_for_mapped_con()) { 807 if (!err && !search_for_mapped_con()) {
802 info_idx = newidx; 808 info_idx = newidx;
@@ -832,6 +838,9 @@ static int set_con2fb_map(int unit, int newidx, int user)
832 con2fb_init_display(vc, info, unit, show_logo); 838 con2fb_init_display(vc, info, unit, show_logo);
833 } 839 }
834 840
841 if (!search_fb_in_map(info_idx))
842 info_idx = newidx;
843
835 release_console_sem(); 844 release_console_sem();
836 return err; 845 return err;
837} 846}
@@ -1034,6 +1043,7 @@ static const char *fbcon_startup(void)
1034#endif /* CONFIG_MAC */ 1043#endif /* CONFIG_MAC */
1035 1044
1036 fbcon_add_cursor_timer(info); 1045 fbcon_add_cursor_timer(info);
1046 fbcon_has_exited = 0;
1037 return display_desc; 1047 return display_desc;
1038} 1048}
1039 1049
@@ -1061,17 +1071,36 @@ static void fbcon_init(struct vc_data *vc, int init)
1061 1071
1062 /* If we are not the first console on this 1072 /* If we are not the first console on this
1063 fb, copy the font from that console */ 1073 fb, copy the font from that console */
1064 t = &fb_display[svc->vc_num]; 1074 t = &fb_display[fg_console];
1065 if (!vc->vc_font.data) { 1075 if (!p->fontdata) {
1066 vc->vc_font.data = (void *)(p->fontdata = t->fontdata); 1076 if (t->fontdata) {
1067 vc->vc_font.width = (*default_mode)->vc_font.width; 1077 struct vc_data *fvc = vc_cons[fg_console].d;
1068 vc->vc_font.height = (*default_mode)->vc_font.height; 1078
1069 p->userfont = t->userfont; 1079 vc->vc_font.data = (void *)(p->fontdata =
1070 if (p->userfont) 1080 fvc->vc_font.data);
1071 REFCOUNT(p->fontdata)++; 1081 vc->vc_font.width = fvc->vc_font.width;
1082 vc->vc_font.height = fvc->vc_font.height;
1083 p->userfont = t->userfont;
1084
1085 if (p->userfont)
1086 REFCOUNT(p->fontdata)++;
1087 } else {
1088 const struct font_desc *font = NULL;
1089
1090 if (!fontname[0] || !(font = find_font(fontname)))
1091 font = get_default_font(info->var.xres,
1092 info->var.yres);
1093 vc->vc_font.width = font->width;
1094 vc->vc_font.height = font->height;
1095 vc->vc_font.data = (void *)(p->fontdata = font->data);
1096 vc->vc_font.charcount = 256; /* FIXME Need to
1097 support more fonts */
1098 }
1072 } 1099 }
1100
1073 if (p->userfont) 1101 if (p->userfont)
1074 charcnt = FNTCHARCNT(p->fontdata); 1102 charcnt = FNTCHARCNT(p->fontdata);
1103
1075 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 1104 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1076 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1105 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1077 if (charcnt == 256) { 1106 if (charcnt == 256) {
@@ -1145,13 +1174,47 @@ static void fbcon_init(struct vc_data *vc, int init)
1145 ops->p = &fb_display[fg_console]; 1174 ops->p = &fb_display[fg_console];
1146} 1175}
1147 1176
1177static void fbcon_free_font(struct display *p)
1178{
1179 if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
1180 kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
1181 p->fontdata = NULL;
1182 p->userfont = 0;
1183}
1184
1148static void fbcon_deinit(struct vc_data *vc) 1185static void fbcon_deinit(struct vc_data *vc)
1149{ 1186{
1150 struct display *p = &fb_display[vc->vc_num]; 1187 struct display *p = &fb_display[vc->vc_num];
1188 struct fb_info *info;
1189 struct fbcon_ops *ops;
1190 int idx;
1151 1191
1152 if (info_idx != -1)
1153 return;
1154 fbcon_free_font(p); 1192 fbcon_free_font(p);
1193 idx = con2fb_map[vc->vc_num];
1194
1195 if (idx == -1)
1196 goto finished;
1197
1198 info = registered_fb[idx];
1199
1200 if (!info)
1201 goto finished;
1202
1203 ops = info->fbcon_par;
1204
1205 if (!ops)
1206 goto finished;
1207
1208 if (CON_IS_VISIBLE(vc))
1209 fbcon_del_cursor_timer(info);
1210
1211 ops->flags &= ~FBCON_FLAGS_INIT;
1212finished:
1213
1214 if (!con_is_bound(&fb_con))
1215 fbcon_exit();
1216
1217 return;
1155} 1218}
1156 1219
1157/* ====================================================================== */ 1220/* ====================================================================== */
@@ -2099,12 +2162,11 @@ static int fbcon_switch(struct vc_data *vc)
2099 if (info->fbops->fb_set_par) 2162 if (info->fbops->fb_set_par)
2100 info->fbops->fb_set_par(info); 2163 info->fbops->fb_set_par(info);
2101 2164
2102 if (old_info != info) { 2165 if (old_info != info)
2103 fbcon_del_cursor_timer(old_info); 2166 fbcon_del_cursor_timer(old_info);
2104 fbcon_add_cursor_timer(info);
2105 }
2106 } 2167 }
2107 2168
2169 fbcon_add_cursor_timer(info);
2108 set_blitting_type(vc, info); 2170 set_blitting_type(vc, info);
2109 ops->cursor_reset = 1; 2171 ops->cursor_reset = 1;
2110 2172
@@ -2222,14 +2284,6 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2222 return 0; 2284 return 0;
2223} 2285}
2224 2286
2225static void fbcon_free_font(struct display *p)
2226{
2227 if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
2228 kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
2229 p->fontdata = NULL;
2230 p->userfont = 0;
2231}
2232
2233static int fbcon_get_font(struct vc_data *vc, struct console_font *font) 2287static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
2234{ 2288{
2235 u8 *fontdata = vc->vc_font.data; 2289 u8 *fontdata = vc->vc_font.data;
@@ -2443,7 +2497,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
2443 2497
2444 FNTSUM(new_data) = csum; 2498 FNTSUM(new_data) = csum;
2445 /* Check if the same font is on some other console already */ 2499 /* Check if the same font is on some other console already */
2446 for (i = 0; i < MAX_NR_CONSOLES; i++) { 2500 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2447 struct vc_data *tmp = vc_cons[i].d; 2501 struct vc_data *tmp = vc_cons[i].d;
2448 2502
2449 if (fb_display[i].userfont && 2503 if (fb_display[i].userfont &&
@@ -2768,7 +2822,7 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2768 if (!ops || ops->currcon < 0) 2822 if (!ops || ops->currcon < 0)
2769 return; 2823 return;
2770 2824
2771 for (i = 0; i < MAX_NR_CONSOLES; i++) { 2825 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2772 vc = vc_cons[i].d; 2826 vc = vc_cons[i].d;
2773 if (!vc || vc->vc_mode != KD_TEXT || 2827 if (!vc || vc->vc_mode != KD_TEXT ||
2774 registered_fb[con2fb_map[i]] != info) 2828 registered_fb[con2fb_map[i]] != info)
@@ -2830,22 +2884,57 @@ static int fbcon_mode_deleted(struct fb_info *info,
2830 return found; 2884 return found;
2831} 2885}
2832 2886
2887static int fbcon_fb_unregistered(int idx)
2888{
2889 int i;
2890
2891 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2892 if (con2fb_map[i] == idx)
2893 con2fb_map[i] = -1;
2894 }
2895
2896 if (idx == info_idx) {
2897 info_idx = -1;
2898
2899 for (i = 0; i < FB_MAX; i++) {
2900 if (registered_fb[i] != NULL) {
2901 info_idx = i;
2902 break;
2903 }
2904 }
2905 }
2906
2907 if (info_idx != -1) {
2908 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2909 if (con2fb_map[i] == -1)
2910 con2fb_map[i] = info_idx;
2911 }
2912 }
2913
2914 if (!num_registered_fb)
2915 unregister_con_driver(&fb_con);
2916
2917 return 0;
2918}
2919
2833static int fbcon_fb_registered(int idx) 2920static int fbcon_fb_registered(int idx)
2834{ 2921{
2835 int ret = 0, i; 2922 int ret = 0, i;
2836 2923
2837 if (info_idx == -1) { 2924 if (info_idx == -1) {
2838 for (i = 0; i < MAX_NR_CONSOLES; i++) { 2925 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2839 if (con2fb_map_boot[i] == idx) { 2926 if (con2fb_map_boot[i] == idx) {
2840 info_idx = idx; 2927 info_idx = idx;
2841 break; 2928 break;
2842 } 2929 }
2843 } 2930 }
2931
2844 if (info_idx != -1) 2932 if (info_idx != -1)
2845 ret = fbcon_takeover(1); 2933 ret = fbcon_takeover(1);
2846 } else { 2934 } else {
2847 for (i = 0; i < MAX_NR_CONSOLES; i++) { 2935 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2848 if (con2fb_map_boot[i] == idx) 2936 if (con2fb_map_boot[i] == idx &&
2937 con2fb_map[i] == -1)
2849 set_con2fb_map(i, idx, 0); 2938 set_con2fb_map(i, idx, 0);
2850 } 2939 }
2851 } 2940 }
@@ -2882,7 +2971,7 @@ static void fbcon_new_modelist(struct fb_info *info)
2882 struct fb_var_screeninfo var; 2971 struct fb_var_screeninfo var;
2883 struct fb_videomode *mode; 2972 struct fb_videomode *mode;
2884 2973
2885 for (i = 0; i < MAX_NR_CONSOLES; i++) { 2974 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2886 if (registered_fb[con2fb_map[i]] != info) 2975 if (registered_fb[con2fb_map[i]] != info)
2887 continue; 2976 continue;
2888 if (!fb_display[i].mode) 2977 if (!fb_display[i].mode)
@@ -2910,6 +2999,14 @@ static int fbcon_event_notify(struct notifier_block *self,
2910 struct fb_con2fbmap *con2fb; 2999 struct fb_con2fbmap *con2fb;
2911 int ret = 0; 3000 int ret = 0;
2912 3001
3002 /*
3003 * ignore all events except driver registration and deregistration
3004 * if fbcon is not active
3005 */
3006 if (fbcon_has_exited && !(action == FB_EVENT_FB_REGISTERED ||
3007 action == FB_EVENT_FB_UNREGISTERED))
3008 goto done;
3009
2913 switch(action) { 3010 switch(action) {
2914 case FB_EVENT_SUSPEND: 3011 case FB_EVENT_SUSPEND:
2915 fbcon_suspended(info); 3012 fbcon_suspended(info);
@@ -2930,6 +3027,9 @@ static int fbcon_event_notify(struct notifier_block *self,
2930 case FB_EVENT_FB_REGISTERED: 3027 case FB_EVENT_FB_REGISTERED:
2931 ret = fbcon_fb_registered(info->node); 3028 ret = fbcon_fb_registered(info->node);
2932 break; 3029 break;
3030 case FB_EVENT_FB_UNREGISTERED:
3031 ret = fbcon_fb_unregistered(info->node);
3032 break;
2933 case FB_EVENT_SET_CONSOLE_MAP: 3033 case FB_EVENT_SET_CONSOLE_MAP:
2934 con2fb = event->data; 3034 con2fb = event->data;
2935 ret = set_con2fb_map(con2fb->console - 1, 3035 ret = set_con2fb_map(con2fb->console - 1,
@@ -2945,16 +3045,9 @@ static int fbcon_event_notify(struct notifier_block *self,
2945 case FB_EVENT_NEW_MODELIST: 3045 case FB_EVENT_NEW_MODELIST:
2946 fbcon_new_modelist(info); 3046 fbcon_new_modelist(info);
2947 break; 3047 break;
2948 case FB_EVENT_SET_CON_ROTATE:
2949 fbcon_rotate(info, *(int *)event->data);
2950 break;
2951 case FB_EVENT_GET_CON_ROTATE:
2952 ret = fbcon_get_rotate(info);
2953 break;
2954 case FB_EVENT_SET_CON_ROTATE_ALL:
2955 fbcon_rotate_all(info, *(int *)event->data);
2956 } 3048 }
2957 3049
3050done:
2958 return ret; 3051 return ret;
2959} 3052}
2960 3053
@@ -2992,27 +3085,181 @@ static struct notifier_block fbcon_event_notifier = {
2992 .notifier_call = fbcon_event_notify, 3085 .notifier_call = fbcon_event_notify,
2993}; 3086};
2994 3087
2995static int __init fb_console_init(void) 3088static ssize_t store_rotate(struct class_device *class_device,
3089 const char *buf, size_t count)
2996{ 3090{
2997 int i; 3091 struct fb_info *info;
3092 int rotate, idx;
3093 char **last = NULL;
3094
3095 if (fbcon_has_exited)
3096 return count;
2998 3097
2999 acquire_console_sem(); 3098 acquire_console_sem();
3000 fb_register_client(&fbcon_event_notifier); 3099 idx = con2fb_map[fg_console];
3100
3101 if (idx == -1 || registered_fb[idx] == NULL)
3102 goto err;
3103
3104 info = registered_fb[idx];
3105 rotate = simple_strtoul(buf, last, 0);
3106 fbcon_rotate(info, rotate);
3107err:
3001 release_console_sem(); 3108 release_console_sem();
3109 return count;
3110}
3002 3111
3003 for (i = 0; i < MAX_NR_CONSOLES; i++) 3112static ssize_t store_rotate_all(struct class_device *class_device,
3004 con2fb_map[i] = -1; 3113 const char *buf, size_t count)
3114{
3115 struct fb_info *info;
3116 int rotate, idx;
3117 char **last = NULL;
3118
3119 if (fbcon_has_exited)
3120 return count;
3121
3122 acquire_console_sem();
3123 idx = con2fb_map[fg_console];
3124
3125 if (idx == -1 || registered_fb[idx] == NULL)
3126 goto err;
3005 3127
3128 info = registered_fb[idx];
3129 rotate = simple_strtoul(buf, last, 0);
3130 fbcon_rotate_all(info, rotate);
3131err:
3132 release_console_sem();
3133 return count;
3134}
3135
3136static ssize_t show_rotate(struct class_device *class_device, char *buf)
3137{
3138 struct fb_info *info;
3139 int rotate = 0, idx;
3140
3141 if (fbcon_has_exited)
3142 return 0;
3143
3144 acquire_console_sem();
3145 idx = con2fb_map[fg_console];
3146
3147 if (idx == -1 || registered_fb[idx] == NULL)
3148 goto err;
3149
3150 info = registered_fb[idx];
3151 rotate = fbcon_get_rotate(info);
3152err:
3153 release_console_sem();
3154 return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
3155}
3156
3157static struct class_device_attribute class_device_attrs[] = {
3158 __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
3159 __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all),
3160};
3161
3162static int fbcon_init_class_device(void)
3163{
3164 int i;
3165
3166 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
3167 class_device_create_file(fbcon_class_device,
3168 &class_device_attrs[i]);
3169 return 0;
3170}
3171
3172static void fbcon_start(void)
3173{
3006 if (num_registered_fb) { 3174 if (num_registered_fb) {
3175 int i;
3176
3177 acquire_console_sem();
3178
3007 for (i = 0; i < FB_MAX; i++) { 3179 for (i = 0; i < FB_MAX; i++) {
3008 if (registered_fb[i] != NULL) { 3180 if (registered_fb[i] != NULL) {
3009 info_idx = i; 3181 info_idx = i;
3010 break; 3182 break;
3011 } 3183 }
3012 } 3184 }
3185
3186 release_console_sem();
3013 fbcon_takeover(0); 3187 fbcon_takeover(0);
3014 } 3188 }
3189}
3190
3191static void fbcon_exit(void)
3192{
3193 struct fb_info *info;
3194 int i, j, mapped;
3195
3196 if (fbcon_has_exited)
3197 return;
3198
3199#ifdef CONFIG_ATARI
3200 free_irq(IRQ_AUTO_4, fb_vbl_handler);
3201#endif
3202#ifdef CONFIG_MAC
3203 if (MACH_IS_MAC && vbl_detected)
3204 free_irq(IRQ_MAC_VBL, fb_vbl_handler);
3205#endif
3206
3207 kfree((void *)softback_buf);
3208 softback_buf = 0UL;
3209
3210 for (i = 0; i < FB_MAX; i++) {
3211 mapped = 0;
3212 info = registered_fb[i];
3213
3214 if (info == NULL)
3215 continue;
3216
3217 for (j = first_fb_vc; j <= last_fb_vc; j++) {
3218 if (con2fb_map[j] == i)
3219 mapped = 1;
3220 }
3221
3222 if (mapped) {
3223 if (info->fbops->fb_release)
3224 info->fbops->fb_release(info, 0);
3225 module_put(info->fbops->owner);
3226
3227 if (info->fbcon_par) {
3228 fbcon_del_cursor_timer(info);
3229 kfree(info->fbcon_par);
3230 info->fbcon_par = NULL;
3231 }
3015 3232
3233 if (info->queue.func == fb_flashcursor)
3234 info->queue.func = NULL;
3235 }
3236 }
3237
3238 fbcon_has_exited = 1;
3239}
3240
3241static int __init fb_console_init(void)
3242{
3243 int i;
3244
3245 acquire_console_sem();
3246 fb_register_client(&fbcon_event_notifier);
3247 fbcon_class_device =
3248 class_device_create(fb_class, NULL, MKDEV(0, 0), NULL, "fbcon");
3249
3250 if (IS_ERR(fbcon_class_device)) {
3251 printk(KERN_WARNING "Unable to create class_device "
3252 "for fbcon; errno = %ld\n",
3253 PTR_ERR(fbcon_class_device));
3254 fbcon_class_device = NULL;
3255 } else
3256 fbcon_init_class_device();
3257
3258 for (i = 0; i < MAX_NR_CONSOLES; i++)
3259 con2fb_map[i] = -1;
3260
3261 release_console_sem();
3262 fbcon_start();
3016 return 0; 3263 return 0;
3017} 3264}
3018 3265
@@ -3020,12 +3267,24 @@ module_init(fb_console_init);
3020 3267
3021#ifdef MODULE 3268#ifdef MODULE
3022 3269
3270static void __exit fbcon_deinit_class_device(void)
3271{
3272 int i;
3273
3274 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
3275 class_device_remove_file(fbcon_class_device,
3276 &class_device_attrs[i]);
3277}
3278
3023static void __exit fb_console_exit(void) 3279static void __exit fb_console_exit(void)
3024{ 3280{
3025 acquire_console_sem(); 3281 acquire_console_sem();
3026 fb_unregister_client(&fbcon_event_notifier); 3282 fb_unregister_client(&fbcon_event_notifier);
3283 fbcon_deinit_class_device();
3284 class_device_destroy(fb_class, MKDEV(0, 0));
3285 fbcon_exit();
3027 release_console_sem(); 3286 release_console_sem();
3028 give_up_console(&fb_con); 3287 unregister_con_driver(&fb_con);
3029} 3288}
3030 3289
3031module_exit(fb_console_exit); 3290module_exit(fb_console_exit);
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index c38c3d8e7a74..f244ad066d68 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -11,7 +11,6 @@
11#ifndef _VIDEO_FBCON_H 11#ifndef _VIDEO_FBCON_H
12#define _VIDEO_FBCON_H 12#define _VIDEO_FBCON_H
13 13
14#include <linux/config.h>
15#include <linux/types.h> 14#include <linux/types.h>
16#include <linux/vt_buffer.h> 15#include <linux/vt_buffer.h>
17#include <linux/vt_kern.h> 16#include <linux/vt_kern.h>
@@ -175,6 +174,7 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
175#endif 174#endif
176extern void fbcon_set_bitops(struct fbcon_ops *ops); 175extern void fbcon_set_bitops(struct fbcon_ops *ops);
177extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); 176extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
177extern struct class *fb_class;
178 178
179#define FBCON_ATTRIBUTE_UNDERLINE 1 179#define FBCON_ATTRIBUTE_UNDERLINE 1
180#define FBCON_ATTRIBUTE_REVERSE 2 180#define FBCON_ATTRIBUTE_REVERSE 2
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 990289a69b78..4481c80b8b2a 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -8,7 +8,6 @@
8 * more details. 8 * more details.
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/string.h> 12#include <linux/string.h>
14#include <linux/fb.h> 13#include <linux/fb.h>
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index d44c5fa515fb..7f92c06afea7 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -8,7 +8,6 @@
8 * more details. 8 * more details.
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/string.h> 12#include <linux/string.h>
14#include <linux/fb.h> 13#include <linux/fb.h>
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c
index 2dc091fbd5c9..00884e013f0f 100644
--- a/drivers/video/console/fbcon_rotate.c
+++ b/drivers/video/console/fbcon_rotate.c
@@ -8,7 +8,6 @@
8 * more details. 8 * more details.
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/string.h> 12#include <linux/string.h>
14#include <linux/fb.h> 13#include <linux/fb.h>
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index f56ed068a5bc..ab91005e64dc 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -8,7 +8,6 @@
8 * more details. 8 * more details.
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/string.h> 12#include <linux/string.h>
14#include <linux/fb.h> 13#include <linux/fb.h>
diff --git a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index 2d2e39632e2d..40f3d4eeb198 100644
--- a/drivers/video/console/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
@@ -1,6 +1,5 @@
1/* Acorn-like font definition, with PC graphics characters */ 1/* Acorn-like font definition, with PC graphics characters */
2 2
3#include <linux/config.h>
4#include <linux/font.h> 3#include <linux/font.h>
5 4
6static const unsigned char acorndata_8x8[] = { 5static const unsigned char acorndata_8x8[] = {
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 0cc1bfda76a6..c960728b7e82 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -12,7 +12,6 @@
12 * for more details. 12 * for more details.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/string.h> 17#include <linux/string.h>
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 7f939d066a5a..eb4d03fa5391 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -31,7 +31,6 @@
31#include <linux/fs.h> 31#include <linux/fs.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/tty.h>
35#include <linux/console.h> 34#include <linux/console.h>
36#include <linux/string.h> 35#include <linux/string.h>
37#include <linux/kd.h> 36#include <linux/kd.h>
@@ -198,7 +197,7 @@ static int __init mdacon_setup(char *str)
198__setup("mdacon=", mdacon_setup); 197__setup("mdacon=", mdacon_setup);
199#endif 198#endif
200 199
201static int __init mda_detect(void) 200static int mda_detect(void)
202{ 201{
203 int count=0; 202 int count=0;
204 u16 *p, p_save; 203 u16 *p, p_save;
@@ -283,7 +282,7 @@ static int __init mda_detect(void)
283 return 1; 282 return 1;
284} 283}
285 284
286static void __init mda_initialize(void) 285static void mda_initialize(void)
287{ 286{
288 write_mda_b(97, 0x00); /* horizontal total */ 287 write_mda_b(97, 0x00); /* horizontal total */
289 write_mda_b(80, 0x01); /* horizontal displayed */ 288 write_mda_b(80, 0x01); /* horizontal displayed */
@@ -308,7 +307,7 @@ static void __init mda_initialize(void)
308 outb_p(0x00, mda_gfx_port); 307 outb_p(0x00, mda_gfx_port);
309} 308}
310 309
311static const char __init *mdacon_startup(void) 310static const char *mdacon_startup(void)
312{ 311{
313 mda_num_columns = 80; 312 mda_num_columns = 80;
314 mda_num_lines = 25; 313 mda_num_lines = 25;
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index e99fe30e568c..7fa1afeae8dc 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -12,7 +12,6 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/tty.h>
16#include <linux/kd.h> 15#include <linux/kd.h>
17#include <linux/selection.h> 16#include <linux/selection.h>
18#include <linux/console.h> 17#include <linux/console.h>
@@ -51,6 +50,7 @@ static int topscan;
51static int xcurs_correction = 29; 50static int xcurs_correction = 29;
52static int newport_xsize; 51static int newport_xsize;
53static int newport_ysize; 52static int newport_ysize;
53static int newport_has_init;
54 54
55static int newport_set_def_font(int unit, struct console_font *op); 55static int newport_set_def_font(int unit, struct console_font *op);
56 56
@@ -283,6 +283,15 @@ static void newport_get_revisions(void)
283 xcurs_correction = 21; 283 xcurs_correction = 21;
284} 284}
285 285
286static void newport_exit(void)
287{
288 int i;
289
290 /* free memory used by user font */
291 for (i = 0; i < MAX_NR_CONSOLES; i++)
292 newport_set_def_font(i, NULL);
293}
294
286/* Can't be __init, take_over_console may call it later */ 295/* Can't be __init, take_over_console may call it later */
287static const char *newport_startup(void) 296static const char *newport_startup(void)
288{ 297{
@@ -290,8 +299,10 @@ static const char *newport_startup(void)
290 299
291 if (!sgi_gfxaddr) 300 if (!sgi_gfxaddr)
292 return NULL; 301 return NULL;
293 npregs = (struct newport_regs *) /* ioremap cannot fail */ 302
294 ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); 303 if (!npregs)
304 npregs = (struct newport_regs *)/* ioremap cannot fail */
305 ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
295 npregs->cset.config = NPORT_CFG_GD0; 306 npregs->cset.config = NPORT_CFG_GD0;
296 307
297 if (newport_wait(npregs)) 308 if (newport_wait(npregs))
@@ -307,11 +318,11 @@ static const char *newport_startup(void)
307 newport_reset(); 318 newport_reset();
308 newport_get_revisions(); 319 newport_get_revisions();
309 newport_get_screensize(); 320 newport_get_screensize();
321 newport_has_init = 1;
310 322
311 return "SGI Newport"; 323 return "SGI Newport";
312 324
313out_unmap: 325out_unmap:
314 iounmap((void *)npregs);
315 return NULL; 326 return NULL;
316} 327}
317 328
@@ -324,11 +335,10 @@ static void newport_init(struct vc_data *vc, int init)
324 335
325static void newport_deinit(struct vc_data *c) 336static void newport_deinit(struct vc_data *c)
326{ 337{
327 int i; 338 if (!con_is_bound(&newport_con) && newport_has_init) {
328 339 newport_exit();
329 /* free memory used by user font */ 340 newport_has_init = 0;
330 for (i = 0; i < MAX_NR_CONSOLES; i++) 341 }
331 newport_set_def_font(i, NULL);
332} 342}
333 343
334static void newport_clear(struct vc_data *vc, int sy, int sx, int height, 344static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
@@ -728,16 +738,23 @@ const struct consw newport_con = {
728#ifdef MODULE 738#ifdef MODULE
729static int __init newport_console_init(void) 739static int __init newport_console_init(void)
730{ 740{
741
742 if (!sgi_gfxaddr)
743 return NULL;
744
745 if (!npregs)
746 npregs = (struct newport_regs *)/* ioremap cannot fail */
747 ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
748
731 return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); 749 return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
732} 750}
751module_init(newport_console_init);
733 752
734static void __exit newport_console_exit(void) 753static void __exit newport_console_exit(void)
735{ 754{
736 give_up_console(&newport_con); 755 give_up_console(&newport_con);
737 iounmap((void *)npregs); 756 iounmap((void *)npregs);
738} 757}
739
740module_init(newport_console_init);
741module_exit(newport_console_exit); 758module_exit(newport_console_exit);
742#endif 759#endif
743 760
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
index 04f42fcaac59..b78eac63459f 100644
--- a/drivers/video/console/promcon.c
+++ b/drivers/video/console/promcon.c
@@ -5,13 +5,11 @@
5 * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) 5 * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/kernel.h> 9#include <linux/kernel.h>
11#include <linux/errno.h> 10#include <linux/errno.h>
12#include <linux/string.h> 11#include <linux/string.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
14#include <linux/tty.h>
15#include <linux/slab.h> 13#include <linux/slab.h>
16#include <linux/delay.h> 14#include <linux/delay.h>
17#include <linux/console.h> 15#include <linux/console.h>
@@ -109,7 +107,7 @@ promcon_end(struct vc_data *conp, char *b)
109 return b - p; 107 return b - p;
110} 108}
111 109
112const char __init *promcon_startup(void) 110const char *promcon_startup(void)
113{ 111{
114 const char *display_desc = "PROM"; 112 const char *display_desc = "PROM";
115 int node; 113 int node;
@@ -133,7 +131,7 @@ const char __init *promcon_startup(void)
133 return display_desc; 131 return display_desc;
134} 132}
135 133
136static void __init 134static void
137promcon_init_unimap(struct vc_data *conp) 135promcon_init_unimap(struct vc_data *conp)
138{ 136{
139 mm_segment_t old_fs = get_fs(); 137 mm_segment_t old_fs = get_fs();
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 3957fc7523e2..557c563e4aed 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/tty.h>
14#include <linux/fb.h> 13#include <linux/fb.h>
15#include <linux/slab.h> 14#include <linux/slab.h>
16 15
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index fd5940f41271..45586aaabd1e 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -37,7 +37,6 @@
37 37
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/tty.h>
41#include <linux/console.h> 40#include <linux/console.h>
42#include <linux/errno.h> 41#include <linux/errno.h>
43#include <linux/vt_kern.h> 42#include <linux/vt_kern.h>
@@ -75,7 +74,7 @@ static inline void cursor_undrawn(void)
75 cursor_drawn = 0; 74 cursor_drawn = 0;
76} 75}
77 76
78static const char *__init sticon_startup(void) 77static const char *sticon_startup(void)
79{ 78{
80 return "STI console"; 79 return "STI console";
81} 80}
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 74ac2acaf72c..88e7038eab88 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -13,7 +13,6 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/types.h> 17#include <linux/types.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 153352ca9461..d981fe4d86c6 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -8,7 +8,6 @@
8 * more details. 8 * more details.
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/string.h> 12#include <linux/string.h>
14#include <linux/fb.h> 13#include <linux/fb.h>
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index e64d42e2449e..0a2c10a1abf8 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -33,13 +33,11 @@
33 * more details. 33 * more details.
34 */ 34 */
35 35
36#include <linux/config.h>
37#include <linux/module.h> 36#include <linux/module.h>
38#include <linux/types.h> 37#include <linux/types.h>
39#include <linux/sched.h> 38#include <linux/sched.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
41#include <linux/kernel.h> 40#include <linux/kernel.h>
42#include <linux/tty.h>
43#include <linux/console.h> 41#include <linux/console.h>
44#include <linux/string.h> 42#include <linux/string.h>
45#include <linux/kd.h> 43#include <linux/kd.h>
@@ -49,6 +47,7 @@
49#include <linux/spinlock.h> 47#include <linux/spinlock.h>
50#include <linux/ioport.h> 48#include <linux/ioport.h>
51#include <linux/init.h> 49#include <linux/init.h>
50#include <linux/screen_info.h>
52#include <linux/smp_lock.h> 51#include <linux/smp_lock.h>
53#include <video/vga.h> 52#include <video/vga.h>
54#include <asm/io.h> 53#include <asm/io.h>
@@ -114,6 +113,7 @@ static int vga_512_chars;
114static int vga_video_font_height; 113static int vga_video_font_height;
115static int vga_scan_lines; 114static int vga_scan_lines;
116static unsigned int vga_rolled_over = 0; 115static unsigned int vga_rolled_over = 0;
116static int vga_init_done;
117 117
118static int __init no_scroll(char *str) 118static int __init no_scroll(char *str)
119{ 119{
@@ -190,7 +190,7 @@ static void vgacon_scrollback_init(int pitch)
190 } 190 }
191} 191}
192 192
193static void __init vgacon_scrollback_startup(void) 193static void vgacon_scrollback_startup(void)
194{ 194{
195 vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE 195 vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE
196 * 1024); 196 * 1024);
@@ -355,7 +355,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
355} 355}
356#endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ 356#endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
357 357
358static const char __init *vgacon_startup(void) 358static const char *vgacon_startup(void)
359{ 359{
360 const char *display_desc = NULL; 360 const char *display_desc = NULL;
361 u16 saved1, saved2; 361 u16 saved1, saved2;
@@ -389,7 +389,7 @@ static const char __init *vgacon_startup(void)
389 vga_video_port_val = VGA_CRT_DM; 389 vga_video_port_val = VGA_CRT_DM;
390 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { 390 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
391 static struct resource ega_console_resource = 391 static struct resource ega_console_resource =
392 { "ega", 0x3B0, 0x3BF }; 392 { .name = "ega", .start = 0x3B0, .end = 0x3BF };
393 vga_video_type = VIDEO_TYPE_EGAM; 393 vga_video_type = VIDEO_TYPE_EGAM;
394 vga_vram_size = 0x8000; 394 vga_vram_size = 0x8000;
395 display_desc = "EGA+"; 395 display_desc = "EGA+";
@@ -397,9 +397,9 @@ static const char __init *vgacon_startup(void)
397 &ega_console_resource); 397 &ega_console_resource);
398 } else { 398 } else {
399 static struct resource mda1_console_resource = 399 static struct resource mda1_console_resource =
400 { "mda", 0x3B0, 0x3BB }; 400 { .name = "mda", .start = 0x3B0, .end = 0x3BB };
401 static struct resource mda2_console_resource = 401 static struct resource mda2_console_resource =
402 { "mda", 0x3BF, 0x3BF }; 402 { .name = "mda", .start = 0x3BF, .end = 0x3BF };
403 vga_video_type = VIDEO_TYPE_MDA; 403 vga_video_type = VIDEO_TYPE_MDA;
404 vga_vram_size = 0x2000; 404 vga_vram_size = 0x2000;
405 display_desc = "*MDA"; 405 display_desc = "*MDA";
@@ -422,14 +422,14 @@ static const char __init *vgacon_startup(void)
422 422
423 if (!ORIG_VIDEO_ISVGA) { 423 if (!ORIG_VIDEO_ISVGA) {
424 static struct resource ega_console_resource 424 static struct resource ega_console_resource
425 = { "ega", 0x3C0, 0x3DF }; 425 = { .name = "ega", .start = 0x3C0, .end = 0x3DF };
426 vga_video_type = VIDEO_TYPE_EGAC; 426 vga_video_type = VIDEO_TYPE_EGAC;
427 display_desc = "EGA"; 427 display_desc = "EGA";
428 request_resource(&ioport_resource, 428 request_resource(&ioport_resource,
429 &ega_console_resource); 429 &ega_console_resource);
430 } else { 430 } else {
431 static struct resource vga_console_resource 431 static struct resource vga_console_resource
432 = { "vga+", 0x3C0, 0x3DF }; 432 = { .name = "vga+", .start = 0x3C0, .end = 0x3DF };
433 vga_video_type = VIDEO_TYPE_VGAC; 433 vga_video_type = VIDEO_TYPE_VGAC;
434 display_desc = "VGA+"; 434 display_desc = "VGA+";
435 request_resource(&ioport_resource, 435 request_resource(&ioport_resource,
@@ -473,7 +473,7 @@ static const char __init *vgacon_startup(void)
473 } 473 }
474 } else { 474 } else {
475 static struct resource cga_console_resource = 475 static struct resource cga_console_resource =
476 { "cga", 0x3D4, 0x3D5 }; 476 { .name = "cga", .start = 0x3D4, .end = 0x3D5 };
477 vga_video_type = VIDEO_TYPE_CGA; 477 vga_video_type = VIDEO_TYPE_CGA;
478 vga_vram_size = 0x2000; 478 vga_vram_size = 0x2000;
479 display_desc = "*CGA"; 479 display_desc = "*CGA";
@@ -523,7 +523,12 @@ static const char __init *vgacon_startup(void)
523 523
524 vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; 524 vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH;
525 vgacon_yres = vga_scan_lines; 525 vgacon_yres = vga_scan_lines;
526 vgacon_scrollback_startup(); 526
527 if (!vga_init_done) {
528 vgacon_scrollback_startup();
529 vga_init_done = 1;
530 }
531
527 return display_desc; 532 return display_desc;
528} 533}
529 534
@@ -531,10 +536,20 @@ static void vgacon_init(struct vc_data *c, int init)
531{ 536{
532 unsigned long p; 537 unsigned long p;
533 538
534 /* We cannot be loaded as a module, therefore init is always 1 */ 539 /*
540 * We cannot be loaded as a module, therefore init is always 1,
541 * but vgacon_init can be called more than once, and init will
542 * not be 1.
543 */
535 c->vc_can_do_color = vga_can_do_color; 544 c->vc_can_do_color = vga_can_do_color;
536 c->vc_cols = vga_video_num_columns; 545
537 c->vc_rows = vga_video_num_lines; 546 /* set dimensions manually if init != 0 since vc_resize() will fail */
547 if (init) {
548 c->vc_cols = vga_video_num_columns;
549 c->vc_rows = vga_video_num_lines;
550 } else
551 vc_resize(c, vga_video_num_columns, vga_video_num_lines);
552
538 c->vc_scan_lines = vga_scan_lines; 553 c->vc_scan_lines = vga_scan_lines;
539 c->vc_font.height = vga_video_font_height; 554 c->vc_font.height = vga_video_font_height;
540 c->vc_complement_mask = 0x7700; 555 c->vc_complement_mask = 0x7700;
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 655301a8671c..8cc6c0e2d27a 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -31,13 +31,11 @@
31 * more details. 31 * more details.
32 */ 32 */
33 33
34#include <linux/config.h>
35#include <linux/module.h> 34#include <linux/module.h>
36#include <linux/kernel.h> 35#include <linux/kernel.h>
37#include <linux/errno.h> 36#include <linux/errno.h>
38#include <linux/string.h> 37#include <linux/string.h>
39#include <linux/mm.h> 38#include <linux/mm.h>
40#include <linux/tty.h>
41#include <linux/slab.h> 39#include <linux/slab.h>
42#include <linux/vmalloc.h> 40#include <linux/vmalloc.h>
43#include <linux/delay.h> 41#include <linux/delay.h>
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 55a3514157ed..aae6d9c26e88 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -36,13 +36,11 @@
36 * (which, incidentally, is about the same saving as a 2.5in hard disk 36 * (which, incidentally, is about the same saving as a 2.5in hard disk
37 * entering standby mode.) 37 * entering standby mode.)
38 */ 38 */
39#include <linux/config.h>
40#include <linux/module.h> 39#include <linux/module.h>
41#include <linux/kernel.h> 40#include <linux/kernel.h>
42#include <linux/errno.h> 41#include <linux/errno.h>
43#include <linux/string.h> 42#include <linux/string.h>
44#include <linux/mm.h> 43#include <linux/mm.h>
45#include <linux/tty.h>
46#include <linux/slab.h> 44#include <linux/slab.h>
47#include <linux/delay.h> 45#include <linux/delay.h>
48#include <linux/fb.h> 46#include <linux/fb.h>
diff --git a/drivers/video/cyber2000fb.h b/drivers/video/cyber2000fb.h
index bd7e1c040781..de4fc43e51c1 100644
--- a/drivers/video/cyber2000fb.h
+++ b/drivers/video/cyber2000fb.h
@@ -9,7 +9,6 @@
9 * 9 *
10 * Integraphics Cyber2000 frame buffer device 10 * Integraphics Cyber2000 frame buffer device
11 */ 11 */
12#include <linux/config.h>
13 12
14/* 13/*
15 * Internal CyberPro sizes and offsets. 14 * Internal CyberPro sizes and offsets.
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index a3e189f90a7d..c40e72dafb0e 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -81,7 +81,6 @@
81#include <linux/errno.h> 81#include <linux/errno.h>
82#include <linux/string.h> 82#include <linux/string.h>
83#include <linux/mm.h> 83#include <linux/mm.h>
84#include <linux/tty.h>
85#include <linux/slab.h> 84#include <linux/slab.h>
86#include <linux/delay.h> 85#include <linux/delay.h>
87#include <linux/zorro.h> 86#include <linux/zorro.h>
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index 0ae0a97b0fed..94a66c2d2cf5 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -14,7 +14,6 @@
14 14
15#define CYBLAFB_PIXMAPSIZE 8192 15#define CYBLAFB_PIXMAPSIZE 8192
16 16
17#include <linux/config.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/string.h> 18#include <linux/string.h>
20#include <linux/fb.h> 19#include <linux/fb.h>
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 5abd3cb00671..b083ea7e9c69 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -2,7 +2,6 @@
2#include <linux/errno.h> 2#include <linux/errno.h>
3#include <linux/string.h> 3#include <linux/string.h>
4#include <linux/mm.h> 4#include <linux/mm.h>
5#include <linux/tty.h>
6#include <linux/slab.h> 5#include <linux/slab.h>
7#include <linux/delay.h> 6#include <linux/delay.h>
8#include <linux/interrupt.h> 7#include <linux/interrupt.h>
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 082759447bf6..737257d278f0 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -48,7 +48,6 @@
48#include <linux/errno.h> 48#include <linux/errno.h>
49#include <linux/string.h> 49#include <linux/string.h>
50#include <linux/mm.h> 50#include <linux/mm.h>
51#include <linux/tty.h>
52#include <linux/slab.h> 51#include <linux/slab.h>
53#include <linux/delay.h> 52#include <linux/delay.h>
54#include <linux/fb.h> 53#include <linux/fb.h>
@@ -605,11 +604,6 @@ static void clearfb16(struct fb_info *info)
605 fb_writeb(0, dst); 604 fb_writeb(0, dst);
606} 605}
607 606
608static void epson1355fb_platform_release(struct device *device)
609{
610 dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
611}
612
613static int epson1355fb_remove(struct platform_device *dev) 607static int epson1355fb_remove(struct platform_device *dev)
614{ 608{
615 struct fb_info *info = platform_get_drvdata(dev); 609 struct fb_info *info = platform_get_drvdata(dev);
@@ -733,13 +727,7 @@ static struct platform_driver epson1355fb_driver = {
733 }, 727 },
734}; 728};
735 729
736static struct platform_device epson1355fb_device = { 730static struct platform_device *epson1355fb_device;
737 .name = "epson1355fb",
738 .id = 0,
739 .dev = {
740 .release = epson1355fb_platform_release,
741 }
742};
743 731
744int __init epson1355fb_init(void) 732int __init epson1355fb_init(void)
745{ 733{
@@ -749,11 +737,21 @@ int __init epson1355fb_init(void)
749 return -ENODEV; 737 return -ENODEV;
750 738
751 ret = platform_driver_register(&epson1355fb_driver); 739 ret = platform_driver_register(&epson1355fb_driver);
740
752 if (!ret) { 741 if (!ret) {
753 ret = platform_device_register(&epson1355fb_device); 742 epson1355fb_device = platform_device_alloc("epson1355fb", 0);
754 if (ret) 743
744 if (epson1355fb_device)
745 ret = platform_device_add(epson1355fb_device);
746 else
747 ret = -ENOMEM;
748
749 if (ret) {
750 platform_device_put(epson1355fb_device);
755 platform_driver_unregister(&epson1355fb_driver); 751 platform_driver_unregister(&epson1355fb_driver);
752 }
756 } 753 }
754
757 return ret; 755 return ret;
758} 756}
759 757
@@ -762,7 +760,7 @@ module_init(epson1355fb_init);
762#ifdef MODULE 760#ifdef MODULE
763static void __exit epson1355fb_exit(void) 761static void __exit epson1355fb_exit(void)
764{ 762{
765 platform_device_unregister(&epson1355fb_device); 763 platform_device_unregister(epson1355fb_device);
766 platform_driver_unregister(&epson1355fb_driver); 764 platform_driver_unregister(&epson1355fb_driver);
767} 765}
768 766
diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
new file mode 100644
index 000000000000..8c020389e4fa
--- /dev/null
+++ b/drivers/video/fb_notify.c
@@ -0,0 +1,46 @@
1/*
2 * linux/drivers/video/fb_notify.c
3 *
4 * Copyright (C) 2006 Antonino Daplas <adaplas@pol.net>
5 *
6 * 2001 - Documented with DocBook
7 * - Brad Douglas <brad@neruo.com>
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive
11 * for more details.
12 */
13#include <linux/fb.h>
14#include <linux/notifier.h>
15
16static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
17
18/**
19 * fb_register_client - register a client notifier
20 * @nb: notifier block to callback on events
21 */
22int fb_register_client(struct notifier_block *nb)
23{
24 return blocking_notifier_chain_register(&fb_notifier_list, nb);
25}
26EXPORT_SYMBOL(fb_register_client);
27
28/**
29 * fb_unregister_client - unregister a client notifier
30 * @nb: notifier block to callback on events
31 */
32int fb_unregister_client(struct notifier_block *nb)
33{
34 return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
35}
36EXPORT_SYMBOL(fb_unregister_client);
37
38/**
39 * fb_notifier_call_chain - notify clients of fb_events
40 *
41 */
42int fb_notifier_call_chain(unsigned long val, void *v)
43{
44 return blocking_notifier_call_chain(&fb_notifier_list, val, v);
45}
46EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 1f98392a43b3..e8b135f3d80d 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/tty.h>
17#include <linux/fb.h> 16#include <linux/fb.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
19 18
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c
index ac90883dc3aa..b5498999c4ec 100644
--- a/drivers/video/fbcvt.c
+++ b/drivers/video/fbcvt.c
@@ -376,4 +376,3 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
376 376
377 return 0; 377 return 0;
378} 378}
379EXPORT_SYMBOL(fb_find_mode_cvt);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 372aa1776827..17961e3ecaa0 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -11,7 +11,6 @@
11 * for more details. 11 * for more details.
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/module.h> 14#include <linux/module.h>
16 15
17#include <linux/compat.h> 16#include <linux/compat.h>
@@ -24,7 +23,7 @@
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <linux/mm.h> 24#include <linux/mm.h>
26#include <linux/mman.h> 25#include <linux/mman.h>
27#include <linux/tty.h> 26#include <linux/vt.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/linux_logo.h> 28#include <linux/linux_logo.h>
30#include <linux/proc_fs.h> 29#include <linux/proc_fs.h>
@@ -32,9 +31,7 @@
32#ifdef CONFIG_KMOD 31#ifdef CONFIG_KMOD
33#include <linux/kmod.h> 32#include <linux/kmod.h>
34#endif 33#endif
35#include <linux/devfs_fs_kernel.h>
36#include <linux/err.h> 34#include <linux/err.h>
37#include <linux/kernel.h>
38#include <linux/device.h> 35#include <linux/device.h>
39#include <linux/efi.h> 36#include <linux/efi.h>
40 37
@@ -55,7 +52,6 @@
55 52
56#define FBPIXMAPSIZE (1024 * 8) 53#define FBPIXMAPSIZE (1024 * 8)
57 54
58static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
59struct fb_info *registered_fb[FB_MAX]; 55struct fb_info *registered_fb[FB_MAX];
60int num_registered_fb; 56int num_registered_fb;
61 57
@@ -162,7 +158,6 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size
162} 158}
163 159
164#ifdef CONFIG_LOGO 160#ifdef CONFIG_LOGO
165#include <linux/linux_logo.h>
166 161
167static inline unsigned safe_shift(unsigned d, int n) 162static inline unsigned safe_shift(unsigned d, int n)
168{ 163{
@@ -336,11 +331,11 @@ static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
336 331
337static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height) 332static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
338{ 333{
339 int i, j, w = width - 1; 334 int i, j, h = height - 1;
340 335
341 for (i = 0; i < height; i++) 336 for (i = 0; i < height; i++)
342 for (j = 0; j < width; j++) 337 for (j = 0; j < width; j++)
343 out[height * j + w - i] = *in++; 338 out[height * j + h - i] = *in++;
344} 339}
345 340
346static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height) 341static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
@@ -358,24 +353,24 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst,
358 u32 tmp; 353 u32 tmp;
359 354
360 if (rotate == FB_ROTATE_UD) { 355 if (rotate == FB_ROTATE_UD) {
361 image->dx = info->var.xres - image->width;
362 image->dy = info->var.yres - image->height;
363 fb_rotate_logo_ud(image->data, dst, image->width, 356 fb_rotate_logo_ud(image->data, dst, image->width,
364 image->height); 357 image->height);
358 image->dx = info->var.xres - image->width;
359 image->dy = info->var.yres - image->height;
365 } else if (rotate == FB_ROTATE_CW) { 360 } else if (rotate == FB_ROTATE_CW) {
366 tmp = image->width;
367 image->width = image->height;
368 image->height = tmp;
369 image->dx = info->var.xres - image->height;
370 fb_rotate_logo_cw(image->data, dst, image->width, 361 fb_rotate_logo_cw(image->data, dst, image->width,
371 image->height); 362 image->height);
372 } else if (rotate == FB_ROTATE_CCW) {
373 tmp = image->width; 363 tmp = image->width;
374 image->width = image->height; 364 image->width = image->height;
375 image->height = tmp; 365 image->height = tmp;
376 image->dy = info->var.yres - image->width; 366 image->dx = info->var.xres - image->width;
367 } else if (rotate == FB_ROTATE_CCW) {
377 fb_rotate_logo_ccw(image->data, dst, image->width, 368 fb_rotate_logo_ccw(image->data, dst, image->width,
378 image->height); 369 image->height);
370 tmp = image->width;
371 image->width = image->height;
372 image->height = tmp;
373 image->dy = info->var.yres - image->height;
379 } 374 }
380 375
381 image->data = dst; 376 image->data = dst;
@@ -435,7 +430,7 @@ int fb_prepare_logo(struct fb_info *info, int rotate)
435 depth = info->var.green.length; 430 depth = info->var.green.length;
436 } 431 }
437 432
438 if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { 433 if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) {
439 /* assume console colormap */ 434 /* assume console colormap */
440 depth = 4; 435 depth = 4;
441 } 436 }
@@ -795,8 +790,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
795 790
796 event.info = info; 791 event.info = info;
797 event.data = &mode1; 792 event.data = &mode1;
798 ret = blocking_notifier_call_chain(&fb_notifier_list, 793 ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event);
799 FB_EVENT_MODE_DELETE, &event);
800 } 794 }
801 795
802 if (!ret) 796 if (!ret)
@@ -841,8 +835,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
841 835
842 info->flags &= ~FBINFO_MISC_USEREVENT; 836 info->flags &= ~FBINFO_MISC_USEREVENT;
843 event.info = info; 837 event.info = info;
844 blocking_notifier_call_chain(&fb_notifier_list, 838 fb_notifier_call_chain(evnt, &event);
845 evnt, &event);
846 } 839 }
847 } 840 }
848 } 841 }
@@ -865,8 +858,7 @@ fb_blank(struct fb_info *info, int blank)
865 858
866 event.info = info; 859 event.info = info;
867 event.data = &blank; 860 event.data = &blank;
868 blocking_notifier_call_chain(&fb_notifier_list, 861 fb_notifier_call_chain(FB_EVENT_BLANK, &event);
869 FB_EVENT_BLANK, &event);
870 } 862 }
871 863
872 return ret; 864 return ret;
@@ -937,8 +929,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
937 con2fb.framebuffer = -1; 929 con2fb.framebuffer = -1;
938 event.info = info; 930 event.info = info;
939 event.data = &con2fb; 931 event.data = &con2fb;
940 blocking_notifier_call_chain(&fb_notifier_list, 932 fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
941 FB_EVENT_GET_CONSOLE_MAP, &event);
942 return copy_to_user(argp, &con2fb, 933 return copy_to_user(argp, &con2fb,
943 sizeof(con2fb)) ? -EFAULT : 0; 934 sizeof(con2fb)) ? -EFAULT : 0;
944 case FBIOPUT_CON2FBMAP: 935 case FBIOPUT_CON2FBMAP:
@@ -956,9 +947,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
956 return -EINVAL; 947 return -EINVAL;
957 event.info = info; 948 event.info = info;
958 event.data = &con2fb; 949 event.data = &con2fb;
959 return blocking_notifier_call_chain(&fb_notifier_list, 950 return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
960 FB_EVENT_SET_CONSOLE_MAP, 951 &event);
961 &event);
962 case FBIOBLANK: 952 case FBIOBLANK:
963 acquire_console_sem(); 953 acquire_console_sem();
964 info->flags |= FBINFO_MISC_USEREVENT; 954 info->flags |= FBINFO_MISC_USEREVENT;
@@ -1278,8 +1268,8 @@ static struct file_operations fb_fops = {
1278#endif 1268#endif
1279}; 1269};
1280 1270
1281static struct class *fb_class; 1271struct class *fb_class;
1282 1272EXPORT_SYMBOL(fb_class);
1283/** 1273/**
1284 * register_framebuffer - registers a frame buffer device 1274 * register_framebuffer - registers a frame buffer device
1285 * @fb_info: frame buffer info structure 1275 * @fb_info: frame buffer info structure
@@ -1333,11 +1323,8 @@ register_framebuffer(struct fb_info *fb_info)
1333 fb_add_videomode(&mode, &fb_info->modelist); 1323 fb_add_videomode(&mode, &fb_info->modelist);
1334 registered_fb[i] = fb_info; 1324 registered_fb[i] = fb_info;
1335 1325
1336 devfs_mk_cdev(MKDEV(FB_MAJOR, i),
1337 S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i);
1338 event.info = fb_info; 1326 event.info = fb_info;
1339 blocking_notifier_call_chain(&fb_notifier_list, 1327 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
1340 FB_EVENT_FB_REGISTERED, &event);
1341 return 0; 1328 return 0;
1342} 1329}
1343 1330
@@ -1355,42 +1342,27 @@ register_framebuffer(struct fb_info *fb_info)
1355int 1342int
1356unregister_framebuffer(struct fb_info *fb_info) 1343unregister_framebuffer(struct fb_info *fb_info)
1357{ 1344{
1345 struct fb_event event;
1358 int i; 1346 int i;
1359 1347
1360 i = fb_info->node; 1348 i = fb_info->node;
1361 if (!registered_fb[i]) 1349 if (!registered_fb[i])
1362 return -EINVAL; 1350 return -EINVAL;
1363 devfs_remove("fb/%d", i);
1364 1351
1365 if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) 1352 if (fb_info->pixmap.addr &&
1353 (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
1366 kfree(fb_info->pixmap.addr); 1354 kfree(fb_info->pixmap.addr);
1367 fb_destroy_modelist(&fb_info->modelist); 1355 fb_destroy_modelist(&fb_info->modelist);
1368 registered_fb[i]=NULL; 1356 registered_fb[i]=NULL;
1369 num_registered_fb--; 1357 num_registered_fb--;
1370 fb_cleanup_class_device(fb_info); 1358 fb_cleanup_class_device(fb_info);
1371 class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); 1359 class_device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1360 event.info = fb_info;
1361 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1372 return 0; 1362 return 0;
1373} 1363}
1374 1364
1375/** 1365/**
1376 * fb_register_client - register a client notifier
1377 * @nb: notifier block to callback on events
1378 */
1379int fb_register_client(struct notifier_block *nb)
1380{
1381 return blocking_notifier_chain_register(&fb_notifier_list, nb);
1382}
1383
1384/**
1385 * fb_unregister_client - unregister a client notifier
1386 * @nb: notifier block to callback on events
1387 */
1388int fb_unregister_client(struct notifier_block *nb)
1389{
1390 return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
1391}
1392
1393/**
1394 * fb_set_suspend - low level driver signals suspend 1366 * fb_set_suspend - low level driver signals suspend
1395 * @info: framebuffer affected 1367 * @info: framebuffer affected
1396 * @state: 0 = resuming, !=0 = suspending 1368 * @state: 0 = resuming, !=0 = suspending
@@ -1405,13 +1377,11 @@ void fb_set_suspend(struct fb_info *info, int state)
1405 1377
1406 event.info = info; 1378 event.info = info;
1407 if (state) { 1379 if (state) {
1408 blocking_notifier_call_chain(&fb_notifier_list, 1380 fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);
1409 FB_EVENT_SUSPEND, &event);
1410 info->state = FBINFO_STATE_SUSPENDED; 1381 info->state = FBINFO_STATE_SUSPENDED;
1411 } else { 1382 } else {
1412 info->state = FBINFO_STATE_RUNNING; 1383 info->state = FBINFO_STATE_RUNNING;
1413 blocking_notifier_call_chain(&fb_notifier_list, 1384 fb_notifier_call_chain(FB_EVENT_RESUME, &event);
1414 FB_EVENT_RESUME, &event);
1415 } 1385 }
1416} 1386}
1417 1387
@@ -1429,7 +1399,6 @@ fbmem_init(void)
1429{ 1399{
1430 create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL); 1400 create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);
1431 1401
1432 devfs_mk_dir("fb");
1433 if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) 1402 if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
1434 printk("unable to get major %d for fb devs\n", FB_MAJOR); 1403 printk("unable to get major %d for fb devs\n", FB_MAJOR);
1435 1404
@@ -1483,36 +1452,12 @@ int fb_new_modelist(struct fb_info *info)
1483 1452
1484 if (!list_empty(&info->modelist)) { 1453 if (!list_empty(&info->modelist)) {
1485 event.info = info; 1454 event.info = info;
1486 err = blocking_notifier_call_chain(&fb_notifier_list, 1455 err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
1487 FB_EVENT_NEW_MODELIST,
1488 &event);
1489 } 1456 }
1490 1457
1491 return err; 1458 return err;
1492} 1459}
1493 1460
1494/**
1495 * fb_con_duit - user<->fbcon passthrough
1496 * @info: struct fb_info
1497 * @event: notification event to be passed to fbcon
1498 * @data: private data
1499 *
1500 * DESCRIPTION
1501 * This function is an fbcon-user event passing channel
1502 * which bypasses fbdev. This is hopefully temporary
1503 * until a user interface for fbcon is created
1504 */
1505int fb_con_duit(struct fb_info *info, int event, void *data)
1506{
1507 struct fb_event evnt;
1508
1509 evnt.info = info;
1510 evnt.data = data;
1511
1512 return blocking_notifier_call_chain(&fb_notifier_list, event, &evnt);
1513}
1514EXPORT_SYMBOL(fb_con_duit);
1515
1516static char *video_options[FB_MAX]; 1461static char *video_options[FB_MAX];
1517static int ofonly; 1462static int ofonly;
1518 1463
@@ -1619,9 +1564,6 @@ EXPORT_SYMBOL(fb_blank);
1619EXPORT_SYMBOL(fb_pan_display); 1564EXPORT_SYMBOL(fb_pan_display);
1620EXPORT_SYMBOL(fb_get_buffer_offset); 1565EXPORT_SYMBOL(fb_get_buffer_offset);
1621EXPORT_SYMBOL(fb_set_suspend); 1566EXPORT_SYMBOL(fb_set_suspend);
1622EXPORT_SYMBOL(fb_register_client);
1623EXPORT_SYMBOL(fb_unregister_client);
1624EXPORT_SYMBOL(fb_get_options); 1567EXPORT_SYMBOL(fb_get_options);
1625EXPORT_SYMBOL(fb_new_modelist);
1626 1568
1627MODULE_LICENSE("GPL"); 1569MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 53beeb4a9998..de93139ccbb5 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -26,12 +26,11 @@
26 * for more details. 26 * for more details.
27 * 27 *
28 */ 28 */
29#include <linux/tty.h>
30#include <linux/fb.h> 29#include <linux/fb.h>
31#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/pci.h>
32#include <video/edid.h> 32#include <video/edid.h>
33#ifdef CONFIG_PPC_OF 33#ifdef CONFIG_PPC_OF
34#include <linux/pci.h>
35#include <asm/prom.h> 34#include <asm/prom.h>
36#include <asm/pci-bridge.h> 35#include <asm/pci-bridge.h>
37#endif 36#endif
@@ -605,6 +604,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
605 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 604 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
606 605
607 DPRINTK(" Monitor Operating Limits: "); 606 DPRINTK(" Monitor Operating Limits: ");
607
608 for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { 608 for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
609 if (edid_is_limits_block(block)) { 609 if (edid_is_limits_block(block)) {
610 specs->hfmin = H_MIN_RATE * 1000; 610 specs->hfmin = H_MIN_RATE * 1000;
@@ -618,11 +618,12 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
618 break; 618 break;
619 } 619 }
620 } 620 }
621 621
622 /* estimate monitor limits based on modes supported */ 622 /* estimate monitor limits based on modes supported */
623 if (retval) { 623 if (retval) {
624 struct fb_videomode *modes; 624 struct fb_videomode *modes, *mode;
625 int num_modes, i, hz, hscan, pixclock; 625 int num_modes, i, hz, hscan, pixclock;
626 int vtotal, htotal;
626 627
627 modes = fb_create_modedb(edid, &num_modes); 628 modes = fb_create_modedb(edid, &num_modes);
628 if (!modes) { 629 if (!modes) {
@@ -632,20 +633,38 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
632 633
633 retval = 0; 634 retval = 0;
634 for (i = 0; i < num_modes; i++) { 635 for (i = 0; i < num_modes; i++) {
635 hz = modes[i].refresh; 636 mode = &modes[i];
636 pixclock = PICOS2KHZ(modes[i].pixclock) * 1000; 637 pixclock = PICOS2KHZ(modes[i].pixclock) * 1000;
637 hscan = (modes[i].yres * 105 * hz + 5000)/100; 638 htotal = mode->xres + mode->right_margin + mode->hsync_len
639 + mode->left_margin;
640 vtotal = mode->yres + mode->lower_margin + mode->vsync_len
641 + mode->upper_margin;
642
643 if (mode->vmode & FB_VMODE_INTERLACED)
644 vtotal /= 2;
645
646 if (mode->vmode & FB_VMODE_DOUBLE)
647 vtotal *= 2;
648
649 hscan = (pixclock + htotal / 2) / htotal;
650 hscan = (hscan + 500) / 1000 * 1000;
651 hz = (hscan + vtotal / 2) / vtotal;
638 652
639 if (specs->dclkmax == 0 || specs->dclkmax < pixclock) 653 if (specs->dclkmax == 0 || specs->dclkmax < pixclock)
640 specs->dclkmax = pixclock; 654 specs->dclkmax = pixclock;
655
641 if (specs->dclkmin == 0 || specs->dclkmin > pixclock) 656 if (specs->dclkmin == 0 || specs->dclkmin > pixclock)
642 specs->dclkmin = pixclock; 657 specs->dclkmin = pixclock;
658
643 if (specs->hfmax == 0 || specs->hfmax < hscan) 659 if (specs->hfmax == 0 || specs->hfmax < hscan)
644 specs->hfmax = hscan; 660 specs->hfmax = hscan;
661
645 if (specs->hfmin == 0 || specs->hfmin > hscan) 662 if (specs->hfmin == 0 || specs->hfmin > hscan)
646 specs->hfmin = hscan; 663 specs->hfmin = hscan;
664
647 if (specs->vfmax == 0 || specs->vfmax < hz) 665 if (specs->vfmax == 0 || specs->vfmax < hz)
648 specs->vfmax = hz; 666 specs->vfmax = hz;
667
649 if (specs->vfmin == 0 || specs->vfmin > hz) 668 if (specs->vfmin == 0 || specs->vfmin > hz)
650 specs->vfmin = hz; 669 specs->vfmin = hz;
651 } 670 }
@@ -1281,8 +1300,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
1281 -EINVAL : 0; 1300 -EINVAL : 0;
1282} 1301}
1283 1302
1284#if defined(CONFIG_FB_FIRMWARE_EDID) && defined(__i386__) 1303#if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86)
1285#include <linux/pci.h>
1286 1304
1287/* 1305/*
1288 * We need to ensure that the EDID block is only returned for 1306 * We need to ensure that the EDID block is only returned for
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 34e07399756b..c151dcf68786 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -18,6 +18,7 @@
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/console.h> 20#include <linux/console.h>
21#include <linux/module.h>
21 22
22/** 23/**
23 * framebuffer_alloc - creates a new frame buffer info structure 24 * framebuffer_alloc - creates a new frame buffer info structure
@@ -55,6 +56,10 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
55 56
56 info->device = dev; 57 info->device = dev;
57 58
59#ifdef CONFIG_FB_BACKLIGHT
60 mutex_init(&info->bl_mutex);
61#endif
62
58 return info; 63 return info;
59#undef PADDING 64#undef PADDING
60#undef BYTES_PER_LONG 65#undef BYTES_PER_LONG
@@ -95,13 +100,22 @@ static int mode_string(char *buf, unsigned int offset,
95 const struct fb_videomode *mode) 100 const struct fb_videomode *mode)
96{ 101{
97 char m = 'U'; 102 char m = 'U';
103 char v = 'p';
104
98 if (mode->flag & FB_MODE_IS_DETAILED) 105 if (mode->flag & FB_MODE_IS_DETAILED)
99 m = 'D'; 106 m = 'D';
100 if (mode->flag & FB_MODE_IS_VESA) 107 if (mode->flag & FB_MODE_IS_VESA)
101 m = 'V'; 108 m = 'V';
102 if (mode->flag & FB_MODE_IS_STANDARD) 109 if (mode->flag & FB_MODE_IS_STANDARD)
103 m = 'S'; 110 m = 'S';
104 return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d-%d\n", m, mode->xres, mode->yres, mode->refresh); 111
112 if (mode->vmode & FB_VMODE_INTERLACED)
113 v = 'i';
114 if (mode->vmode & FB_VMODE_DOUBLE)
115 v = 'd';
116
117 return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d%c-%d\n",
118 m, mode->xres, mode->yres, v, mode->refresh);
105} 119}
106 120
107static ssize_t store_mode(struct class_device *class_device, const char * buf, 121static ssize_t store_mode(struct class_device *class_device, const char * buf,
@@ -233,45 +247,6 @@ static ssize_t show_rotate(struct class_device *class_device, char *buf)
233 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); 247 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
234} 248}
235 249
236static ssize_t store_con_rotate(struct class_device *class_device,
237 const char *buf, size_t count)
238{
239 struct fb_info *fb_info = class_get_devdata(class_device);
240 int rotate;
241 char **last = NULL;
242
243 acquire_console_sem();
244 rotate = simple_strtoul(buf, last, 0);
245 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate);
246 release_console_sem();
247 return count;
248}
249
250static ssize_t store_con_rotate_all(struct class_device *class_device,
251 const char *buf, size_t count)
252{
253 struct fb_info *fb_info = class_get_devdata(class_device);
254 int rotate;
255 char **last = NULL;
256
257 acquire_console_sem();
258 rotate = simple_strtoul(buf, last, 0);
259 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate);
260 release_console_sem();
261 return count;
262}
263
264static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
265{
266 struct fb_info *fb_info = class_get_devdata(class_device);
267 int rotate;
268
269 acquire_console_sem();
270 rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL);
271 release_console_sem();
272 return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
273}
274
275static ssize_t store_virtual(struct class_device *class_device, 250static ssize_t store_virtual(struct class_device *class_device,
276 const char * buf, size_t count) 251 const char * buf, size_t count)
277{ 252{
@@ -414,6 +389,77 @@ static ssize_t show_fbstate(struct class_device *class_device, char *buf)
414 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); 389 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state);
415} 390}
416 391
392#ifdef CONFIG_FB_BACKLIGHT
393static ssize_t store_bl_curve(struct class_device *class_device,
394 const char *buf, size_t count)
395{
396 struct fb_info *fb_info = class_get_devdata(class_device);
397 u8 tmp_curve[FB_BACKLIGHT_LEVELS];
398 unsigned int i;
399
400 /* Some drivers don't use framebuffer_alloc(), but those also
401 * don't have backlights.
402 */
403 if (!fb_info || !fb_info->bl_dev)
404 return -ENODEV;
405
406 if (count != (FB_BACKLIGHT_LEVELS / 8 * 24))
407 return -EINVAL;
408
409 for (i = 0; i < (FB_BACKLIGHT_LEVELS / 8); ++i)
410 if (sscanf(&buf[i * 24],
411 "%2hhx %2hhx %2hhx %2hhx %2hhx %2hhx %2hhx %2hhx\n",
412 &tmp_curve[i * 8 + 0],
413 &tmp_curve[i * 8 + 1],
414 &tmp_curve[i * 8 + 2],
415 &tmp_curve[i * 8 + 3],
416 &tmp_curve[i * 8 + 4],
417 &tmp_curve[i * 8 + 5],
418 &tmp_curve[i * 8 + 6],
419 &tmp_curve[i * 8 + 7]) != 8)
420 return -EINVAL;
421
422 /* If there has been an error in the input data, we won't
423 * reach this loop.
424 */
425 mutex_lock(&fb_info->bl_mutex);
426 for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i)
427 fb_info->bl_curve[i] = tmp_curve[i];
428 mutex_unlock(&fb_info->bl_mutex);
429
430 return count;
431}
432
433static ssize_t show_bl_curve(struct class_device *class_device, char *buf)
434{
435 struct fb_info *fb_info = class_get_devdata(class_device);
436 ssize_t len = 0;
437 unsigned int i;
438
439 /* Some drivers don't use framebuffer_alloc(), but those also
440 * don't have backlights.
441 */
442 if (!fb_info || !fb_info->bl_dev)
443 return -ENODEV;
444
445 mutex_lock(&fb_info->bl_mutex);
446 for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
447 len += snprintf(&buf[len], PAGE_SIZE,
448 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
449 fb_info->bl_curve[i + 0],
450 fb_info->bl_curve[i + 1],
451 fb_info->bl_curve[i + 2],
452 fb_info->bl_curve[i + 3],
453 fb_info->bl_curve[i + 4],
454 fb_info->bl_curve[i + 5],
455 fb_info->bl_curve[i + 6],
456 fb_info->bl_curve[i + 7]);
457 mutex_unlock(&fb_info->bl_mutex);
458
459 return len;
460}
461#endif
462
417/* When cmap is added back in it should be a binary attribute 463/* When cmap is added back in it should be a binary attribute
418 * not a text one. Consideration should also be given to converting 464 * not a text one. Consideration should also be given to converting
419 * fbdev to use configfs instead of sysfs */ 465 * fbdev to use configfs instead of sysfs */
@@ -429,9 +475,10 @@ static struct class_device_attribute class_device_attrs[] = {
429 __ATTR(name, S_IRUGO, show_name, NULL), 475 __ATTR(name, S_IRUGO, show_name, NULL),
430 __ATTR(stride, S_IRUGO, show_stride, NULL), 476 __ATTR(stride, S_IRUGO, show_stride, NULL),
431 __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), 477 __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
432 __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
433 __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
434 __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate), 478 __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate),
479#ifdef CONFIG_FB_BACKLIGHT
480 __ATTR(bl_curve, S_IRUGO|S_IWUSR, show_bl_curve, store_bl_curve),
481#endif
435}; 482};
436 483
437int fb_init_class_device(struct fb_info *fb_info) 484int fb_init_class_device(struct fb_info *fb_info)
@@ -454,4 +501,25 @@ void fb_cleanup_class_device(struct fb_info *fb_info)
454 &class_device_attrs[i]); 501 &class_device_attrs[i]);
455} 502}
456 503
504#ifdef CONFIG_FB_BACKLIGHT
505/* This function generates a linear backlight curve
506 *
507 * 0: off
508 * 1-7: min
509 * 8-127: linear from min to max
510 */
511void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max)
512{
513 unsigned int i, flat, count, range = (max - min);
457 514
515 fb_info->bl_curve[0] = off;
516
517 for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
518 fb_info->bl_curve[flat] = min;
519
520 count = FB_BACKLIGHT_LEVELS * 15 / 16;
521 for (i = 0; i < count; ++i)
522 fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count);
523}
524EXPORT_SYMBOL_GPL(fb_bl_default_curve);
525#endif
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 7633e41adda1..2a0e8210d398 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -1,6 +1,6 @@
1/* ffb.c: Creator/Elite3D frame buffer driver 1/* ffb.c: Creator/Elite3D frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
5 * 5 *
6 * Driver layout based loosely on tgafb.c, see that file for credits. 6 * Driver layout based loosely on tgafb.c, see that file for credits.
@@ -19,7 +19,8 @@
19 19
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/upa.h> 21#include <asm/upa.h>
22#include <asm/oplib.h> 22#include <asm/prom.h>
23#include <asm/of_device.h>
23#include <asm/fbio.h> 24#include <asm/fbio.h>
24 25
25#include "sbuslib.h" 26#include "sbuslib.h"
@@ -184,161 +185,161 @@ static struct fb_ops ffb_ops = {
184 185
185struct ffb_fbc { 186struct ffb_fbc {
186 /* Next vertex registers */ 187 /* Next vertex registers */
187 u32 xxx1[3]; 188 u32 xxx1[3];
188 volatile u32 alpha; 189 u32 alpha;
189 volatile u32 red; 190 u32 red;
190 volatile u32 green; 191 u32 green;
191 volatile u32 blue; 192 u32 blue;
192 volatile u32 depth; 193 u32 depth;
193 volatile u32 y; 194 u32 y;
194 volatile u32 x; 195 u32 x;
195 u32 xxx2[2]; 196 u32 xxx2[2];
196 volatile u32 ryf; 197 u32 ryf;
197 volatile u32 rxf; 198 u32 rxf;
198 u32 xxx3[2]; 199 u32 xxx3[2];
199 200
200 volatile u32 dmyf; 201 u32 dmyf;
201 volatile u32 dmxf; 202 u32 dmxf;
202 u32 xxx4[2]; 203 u32 xxx4[2];
203 volatile u32 ebyi; 204 u32 ebyi;
204 volatile u32 ebxi; 205 u32 ebxi;
205 u32 xxx5[2]; 206 u32 xxx5[2];
206 volatile u32 by; 207 u32 by;
207 volatile u32 bx; 208 u32 bx;
208 u32 dy; 209 u32 dy;
209 u32 dx; 210 u32 dx;
210 volatile u32 bh; 211 u32 bh;
211 volatile u32 bw; 212 u32 bw;
212 u32 xxx6[2]; 213 u32 xxx6[2];
213 214
214 u32 xxx7[32]; 215 u32 xxx7[32];
215 216
216 /* Setup unit vertex state register */ 217 /* Setup unit vertex state register */
217 volatile u32 suvtx; 218 u32 suvtx;
218 u32 xxx8[63]; 219 u32 xxx8[63];
219 220
220 /* Control registers */ 221 /* Control registers */
221 volatile u32 ppc; 222 u32 ppc;
222 volatile u32 wid; 223 u32 wid;
223 volatile u32 fg; 224 u32 fg;
224 volatile u32 bg; 225 u32 bg;
225 volatile u32 consty; 226 u32 consty;
226 volatile u32 constz; 227 u32 constz;
227 volatile u32 xclip; 228 u32 xclip;
228 volatile u32 dcss; 229 u32 dcss;
229 volatile u32 vclipmin; 230 u32 vclipmin;
230 volatile u32 vclipmax; 231 u32 vclipmax;
231 volatile u32 vclipzmin; 232 u32 vclipzmin;
232 volatile u32 vclipzmax; 233 u32 vclipzmax;
233 volatile u32 dcsf; 234 u32 dcsf;
234 volatile u32 dcsb; 235 u32 dcsb;
235 volatile u32 dczf; 236 u32 dczf;
236 volatile u32 dczb; 237 u32 dczb;
237 238
238 u32 xxx9; 239 u32 xxx9;
239 volatile u32 blendc; 240 u32 blendc;
240 volatile u32 blendc1; 241 u32 blendc1;
241 volatile u32 blendc2; 242 u32 blendc2;
242 volatile u32 fbramitc; 243 u32 fbramitc;
243 volatile u32 fbc; 244 u32 fbc;
244 volatile u32 rop; 245 u32 rop;
245 volatile u32 cmp; 246 u32 cmp;
246 volatile u32 matchab; 247 u32 matchab;
247 volatile u32 matchc; 248 u32 matchc;
248 volatile u32 magnab; 249 u32 magnab;
249 volatile u32 magnc; 250 u32 magnc;
250 volatile u32 fbcfg0; 251 u32 fbcfg0;
251 volatile u32 fbcfg1; 252 u32 fbcfg1;
252 volatile u32 fbcfg2; 253 u32 fbcfg2;
253 volatile u32 fbcfg3; 254 u32 fbcfg3;
254 255
255 u32 ppcfg; 256 u32 ppcfg;
256 volatile u32 pick; 257 u32 pick;
257 volatile u32 fillmode; 258 u32 fillmode;
258 volatile u32 fbramwac; 259 u32 fbramwac;
259 volatile u32 pmask; 260 u32 pmask;
260 volatile u32 xpmask; 261 u32 xpmask;
261 volatile u32 ypmask; 262 u32 ypmask;
262 volatile u32 zpmask; 263 u32 zpmask;
263 volatile u32 clip0min; 264 u32 clip0min;
264 volatile u32 clip0max; 265 u32 clip0max;
265 volatile u32 clip1min; 266 u32 clip1min;
266 volatile u32 clip1max; 267 u32 clip1max;
267 volatile u32 clip2min; 268 u32 clip2min;
268 volatile u32 clip2max; 269 u32 clip2max;
269 volatile u32 clip3min; 270 u32 clip3min;
270 volatile u32 clip3max; 271 u32 clip3max;
271 272
272 /* New 3dRAM III support regs */ 273 /* New 3dRAM III support regs */
273 volatile u32 rawblend2; 274 u32 rawblend2;
274 volatile u32 rawpreblend; 275 u32 rawpreblend;
275 volatile u32 rawstencil; 276 u32 rawstencil;
276 volatile u32 rawstencilctl; 277 u32 rawstencilctl;
277 volatile u32 threedram1; 278 u32 threedram1;
278 volatile u32 threedram2; 279 u32 threedram2;
279 volatile u32 passin; 280 u32 passin;
280 volatile u32 rawclrdepth; 281 u32 rawclrdepth;
281 volatile u32 rawpmask; 282 u32 rawpmask;
282 volatile u32 rawcsrc; 283 u32 rawcsrc;
283 volatile u32 rawmatch; 284 u32 rawmatch;
284 volatile u32 rawmagn; 285 u32 rawmagn;
285 volatile u32 rawropblend; 286 u32 rawropblend;
286 volatile u32 rawcmp; 287 u32 rawcmp;
287 volatile u32 rawwac; 288 u32 rawwac;
288 volatile u32 fbramid; 289 u32 fbramid;
289 290
290 volatile u32 drawop; 291 u32 drawop;
291 u32 xxx10[2]; 292 u32 xxx10[2];
292 volatile u32 fontlpat; 293 u32 fontlpat;
293 u32 xxx11; 294 u32 xxx11;
294 volatile u32 fontxy; 295 u32 fontxy;
295 volatile u32 fontw; 296 u32 fontw;
296 volatile u32 fontinc; 297 u32 fontinc;
297 volatile u32 font; 298 u32 font;
298 u32 xxx12[3]; 299 u32 xxx12[3];
299 volatile u32 blend2; 300 u32 blend2;
300 volatile u32 preblend; 301 u32 preblend;
301 volatile u32 stencil; 302 u32 stencil;
302 volatile u32 stencilctl; 303 u32 stencilctl;
303 304
304 u32 xxx13[4]; 305 u32 xxx13[4];
305 volatile u32 dcss1; 306 u32 dcss1;
306 volatile u32 dcss2; 307 u32 dcss2;
307 volatile u32 dcss3; 308 u32 dcss3;
308 volatile u32 widpmask; 309 u32 widpmask;
309 volatile u32 dcs2; 310 u32 dcs2;
310 volatile u32 dcs3; 311 u32 dcs3;
311 volatile u32 dcs4; 312 u32 dcs4;
312 u32 xxx14; 313 u32 xxx14;
313 volatile u32 dcd2; 314 u32 dcd2;
314 volatile u32 dcd3; 315 u32 dcd3;
315 volatile u32 dcd4; 316 u32 dcd4;
316 u32 xxx15; 317 u32 xxx15;
317 318
318 volatile u32 pattern[32]; 319 u32 pattern[32];
319 320
320 u32 xxx16[256]; 321 u32 xxx16[256];
321 322
322 volatile u32 devid; 323 u32 devid;
323 u32 xxx17[63]; 324 u32 xxx17[63];
324 325
325 volatile u32 ucsr; 326 u32 ucsr;
326 u32 xxx18[31]; 327 u32 xxx18[31];
327 328
328 volatile u32 mer; 329 u32 mer;
329}; 330};
330 331
331struct ffb_dac { 332struct ffb_dac {
332 volatile u32 type; 333 u32 type;
333 volatile u32 value; 334 u32 value;
334 volatile u32 type2; 335 u32 type2;
335 volatile u32 value2; 336 u32 value2;
336}; 337};
337 338
338struct ffb_par { 339struct ffb_par {
339 spinlock_t lock; 340 spinlock_t lock;
340 struct ffb_fbc *fbc; 341 struct ffb_fbc __iomem *fbc;
341 struct ffb_dac *dac; 342 struct ffb_dac __iomem *dac;
342 343
343 u32 flags; 344 u32 flags;
344#define FFB_FLAG_AFB 0x00000001 345#define FFB_FLAG_AFB 0x00000001
@@ -353,16 +354,13 @@ struct ffb_par {
353 unsigned long physbase; 354 unsigned long physbase;
354 unsigned long fbsize; 355 unsigned long fbsize;
355 356
356 char name[64];
357 int prom_node;
358 int prom_parent_node;
359 int dac_rev; 357 int dac_rev;
360 int board_type; 358 int board_type;
361}; 359};
362 360
363static void FFBFifo(struct ffb_par *par, int n) 361static void FFBFifo(struct ffb_par *par, int n)
364{ 362{
365 struct ffb_fbc *fbc; 363 struct ffb_fbc __iomem *fbc;
366 int cache = par->fifo_cache; 364 int cache = par->fifo_cache;
367 365
368 if (cache - n < 0) { 366 if (cache - n < 0) {
@@ -375,7 +373,7 @@ static void FFBFifo(struct ffb_par *par, int n)
375 373
376static void FFBWait(struct ffb_par *par) 374static void FFBWait(struct ffb_par *par)
377{ 375{
378 struct ffb_fbc *fbc; 376 struct ffb_fbc __iomem *fbc;
379 int limit = 10000; 377 int limit = 10000;
380 378
381 fbc = par->fbc; 379 fbc = par->fbc;
@@ -408,8 +406,8 @@ static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
408 406
409static void ffb_switch_from_graph(struct ffb_par *par) 407static void ffb_switch_from_graph(struct ffb_par *par)
410{ 408{
411 struct ffb_fbc *fbc = par->fbc; 409 struct ffb_fbc __iomem *fbc = par->fbc;
412 struct ffb_dac *dac = par->dac; 410 struct ffb_dac __iomem *dac = par->dac;
413 unsigned long flags; 411 unsigned long flags;
414 412
415 spin_lock_irqsave(&par->lock, flags); 413 spin_lock_irqsave(&par->lock, flags);
@@ -462,7 +460,7 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
462static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 460static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
463{ 461{
464 struct ffb_par *par = (struct ffb_par *) info->par; 462 struct ffb_par *par = (struct ffb_par *) info->par;
465 struct ffb_fbc *fbc = par->fbc; 463 struct ffb_fbc __iomem *fbc = par->fbc;
466 unsigned long flags; 464 unsigned long flags;
467 u32 fg; 465 u32 fg;
468 466
@@ -505,7 +503,7 @@ static void
505ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 503ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
506{ 504{
507 struct ffb_par *par = (struct ffb_par *) info->par; 505 struct ffb_par *par = (struct ffb_par *) info->par;
508 struct ffb_fbc *fbc = par->fbc; 506 struct ffb_fbc __iomem *fbc = par->fbc;
509 unsigned long flags; 507 unsigned long flags;
510 508
511 if (area->dx != area->sx || 509 if (area->dx != area->sx ||
@@ -541,7 +539,7 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
541static void ffb_imageblit(struct fb_info *info, const struct fb_image *image) 539static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
542{ 540{
543 struct ffb_par *par = (struct ffb_par *) info->par; 541 struct ffb_par *par = (struct ffb_par *) info->par;
544 struct ffb_fbc *fbc = par->fbc; 542 struct ffb_fbc __iomem *fbc = par->fbc;
545 const u8 *data = image->data; 543 const u8 *data = image->data;
546 unsigned long flags; 544 unsigned long flags;
547 u32 fg, bg, xy; 545 u32 fg, bg, xy;
@@ -664,7 +662,7 @@ static int
664ffb_blank(int blank, struct fb_info *info) 662ffb_blank(int blank, struct fb_info *info)
665{ 663{
666 struct ffb_par *par = (struct ffb_par *) info->par; 664 struct ffb_par *par = (struct ffb_par *) info->par;
667 struct ffb_dac *dac = par->dac; 665 struct ffb_dac __iomem *dac = par->dac;
668 unsigned long flags; 666 unsigned long flags;
669 u32 tmp; 667 u32 tmp;
670 668
@@ -883,78 +881,42 @@ ffb_init_fix(struct fb_info *info)
883 info->fix.accel = FB_ACCEL_SUN_CREATOR; 881 info->fix.accel = FB_ACCEL_SUN_CREATOR;
884} 882}
885 883
886static int ffb_apply_upa_parent_ranges(int parent,
887 struct linux_prom64_registers *regs)
888{
889 struct linux_prom64_ranges ranges[PROMREG_MAX];
890 char name[128];
891 int len, i;
892
893 prom_getproperty(parent, "name", name, sizeof(name));
894 if (strcmp(name, "upa") != 0)
895 return 0;
896
897 len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
898 if (len <= 0)
899 return 1;
900
901 len /= sizeof(struct linux_prom64_ranges);
902 for (i = 0; i < len; i++) {
903 struct linux_prom64_ranges *rng = &ranges[i];
904 u64 phys_addr = regs->phys_addr;
905
906 if (phys_addr >= rng->ot_child_base &&
907 phys_addr < (rng->ot_child_base + rng->or_size)) {
908 regs->phys_addr -= rng->ot_child_base;
909 regs->phys_addr += rng->ot_parent_base;
910 return 0;
911 }
912 }
913
914 return 1;
915}
916
917struct all_info { 884struct all_info {
918 struct fb_info info; 885 struct fb_info info;
919 struct ffb_par par; 886 struct ffb_par par;
920 u32 pseudo_palette[256]; 887 u32 pseudo_palette[256];
921 struct list_head list;
922}; 888};
923static LIST_HEAD(ffb_list);
924 889
925static void ffb_init_one(int node, int parent) 890static int ffb_init_one(struct of_device *op)
926{ 891{
927 struct linux_prom64_registers regs[2*PROMREG_MAX]; 892 struct device_node *dp = op->node;
928 struct ffb_fbc *fbc; 893 struct ffb_fbc __iomem *fbc;
929 struct ffb_dac *dac; 894 struct ffb_dac __iomem *dac;
930 struct all_info *all; 895 struct all_info *all;
896 int err;
931 897
932 if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) { 898 all = kzalloc(sizeof(*all), GFP_KERNEL);
933 printk("ffb: Cannot get reg device node property.\n"); 899 if (!all)
934 return; 900 return -ENOMEM;
935 }
936 901
937 if (ffb_apply_upa_parent_ranges(parent, &regs[0])) { 902 spin_lock_init(&all->par.lock);
938 printk("ffb: Cannot apply parent ranges to regs.\n"); 903 all->par.fbc = of_ioremap(&op->resource[2], 0,
939 return; 904 sizeof(struct ffb_fbc), "ffb fbc");
905 if (!all->par.fbc) {
906 kfree(all);
907 return -ENOMEM;
940 } 908 }
941 909
942 all = kmalloc(sizeof(*all), GFP_KERNEL); 910 all->par.dac = of_ioremap(&op->resource[1], 0,
943 if (!all) { 911 sizeof(struct ffb_dac), "ffb dac");
944 printk(KERN_ERR "ffb: Cannot allocate memory.\n"); 912 if (!all->par.dac) {
945 return; 913 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
914 kfree(all);
915 return -ENOMEM;
946 } 916 }
947 memset(all, 0, sizeof(*all));
948
949 INIT_LIST_HEAD(&all->list);
950 917
951 spin_lock_init(&all->par.lock);
952 all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
953 all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
954 all->par.rop_cache = FFB_ROP_NEW; 918 all->par.rop_cache = FFB_ROP_NEW;
955 all->par.physbase = regs[0].phys_addr; 919 all->par.physbase = op->resource[0].start;
956 all->par.prom_node = node;
957 all->par.prom_parent_node = parent;
958 920
959 /* Don't mention copyarea, so SCROLL_REDRAW is always 921 /* Don't mention copyarea, so SCROLL_REDRAW is always
960 * used. It is the fastest on this chip. 922 * used. It is the fastest on this chip.
@@ -968,7 +930,7 @@ static void ffb_init_one(int node, int parent)
968 all->info.par = &all->par; 930 all->info.par = &all->par;
969 all->info.pseudo_palette = all->pseudo_palette; 931 all->info.pseudo_palette = all->pseudo_palette;
970 932
971 sbusfb_fill_var(&all->info.var, all->par.prom_node, 32); 933 sbusfb_fill_var(&all->info.var, dp->node, 32);
972 all->par.fbsize = PAGE_ALIGN(all->info.var.xres * 934 all->par.fbsize = PAGE_ALIGN(all->info.var.xres *
973 all->info.var.yres * 935 all->info.var.yres *
974 4); 936 4);
@@ -976,14 +938,13 @@ static void ffb_init_one(int node, int parent)
976 938
977 all->info.var.accel_flags = FB_ACCELF_TEXT; 939 all->info.var.accel_flags = FB_ACCELF_TEXT;
978 940
979 prom_getstring(node, "name", all->par.name, sizeof(all->par.name)); 941 if (!strcmp(dp->name, "SUNW,afb"))
980 if (!strcmp(all->par.name, "SUNW,afb"))
981 all->par.flags |= FFB_FLAG_AFB; 942 all->par.flags |= FFB_FLAG_AFB;
982 943
983 all->par.board_type = prom_getintdefault(node, "board_type", 0); 944 all->par.board_type = of_getintprop_default(dp, "board_type", 0);
984 945
985 fbc = all->par.fbc; 946 fbc = all->par.fbc;
986 if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) 947 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
987 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); 948 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
988 949
989 ffb_switch_from_graph(&all->par); 950 ffb_switch_from_graph(&all->par);
@@ -1008,81 +969,88 @@ static void ffb_init_one(int node, int parent)
1008 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 969 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
1009 printk(KERN_ERR "ffb: Could not allocate color map.\n"); 970 printk(KERN_ERR "ffb: Could not allocate color map.\n");
1010 kfree(all); 971 kfree(all);
1011 return; 972 return -ENOMEM;
1012 } 973 }
1013 974
1014 ffb_init_fix(&all->info); 975 ffb_init_fix(&all->info);
1015 976
1016 if (register_framebuffer(&all->info) < 0) { 977 err = register_framebuffer(&all->info);
978 if (err < 0) {
1017 printk(KERN_ERR "ffb: Could not register framebuffer.\n"); 979 printk(KERN_ERR "ffb: Could not register framebuffer.\n");
1018 fb_dealloc_cmap(&all->info.cmap); 980 fb_dealloc_cmap(&all->info.cmap);
1019 kfree(all); 981 kfree(all);
1020 return; 982 return err;
1021 } 983 }
1022 984
1023 list_add(&all->list, &ffb_list); 985 dev_set_drvdata(&op->dev, all);
1024 986
1025 printk("ffb: %s at %016lx type %d DAC %d\n", 987 printk("%s: %s at %016lx, type %d, DAC revision %d\n",
988 dp->full_name,
1026 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), 989 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
1027 regs[0].phys_addr, all->par.board_type, all->par.dac_rev); 990 all->par.physbase, all->par.board_type, all->par.dac_rev);
991
992 return 0;
1028} 993}
1029 994
1030static void ffb_scan_siblings(int root) 995static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match)
1031{ 996{
1032 int node, child; 997 struct of_device *op = to_of_device(&dev->dev);
1033 998
1034 child = prom_getchild(root); 999 return ffb_init_one(op);
1035 for (node = prom_searchsiblings(child, "SUNW,ffb"); node;
1036 node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb"))
1037 ffb_init_one(node, root);
1038 for (node = prom_searchsiblings(child, "SUNW,afb"); node;
1039 node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb"))
1040 ffb_init_one(node, root);
1041} 1000}
1042 1001
1043int __init ffb_init(void) 1002static int __devexit ffb_remove(struct of_device *dev)
1044{ 1003{
1045 int root; 1004 struct all_info *all = dev_get_drvdata(&dev->dev);
1046 1005
1047 if (fb_get_options("ffb", NULL)) 1006 unregister_framebuffer(&all->info);
1048 return -ENODEV; 1007 fb_dealloc_cmap(&all->info.cmap);
1049 1008
1050 ffb_scan_siblings(prom_root_node); 1009 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
1010 of_iounmap(all->par.dac, sizeof(struct ffb_dac));
1051 1011
1052 root = prom_getchild(prom_root_node); 1012 kfree(all);
1053 for (root = prom_searchsiblings(root, "upa"); root; 1013
1054 root = prom_searchsiblings(prom_getsibling(root), "upa")) 1014 dev_set_drvdata(&dev->dev, NULL);
1055 ffb_scan_siblings(root);
1056 1015
1057 return 0; 1016 return 0;
1058} 1017}
1059 1018
1060void __exit ffb_exit(void) 1019static struct of_device_id ffb_match[] = {
1061{ 1020 {
1062 struct list_head *pos, *tmp; 1021 .name = "SUNW,ffb",
1022 },
1023 {
1024 .name = "SUNW,afb",
1025 },
1026 {},
1027};
1028MODULE_DEVICE_TABLE(of, ffb_match);
1029
1030static struct of_platform_driver ffb_driver = {
1031 .name = "ffb",
1032 .match_table = ffb_match,
1033 .probe = ffb_probe,
1034 .remove = __devexit_p(ffb_remove),
1035};
1063 1036
1064 list_for_each_safe(pos, tmp, &ffb_list) { 1037int __init ffb_init(void)
1065 struct all_info *all = list_entry(pos, typeof(*all), list); 1038{
1039 if (fb_get_options("ffb", NULL))
1040 return -ENODEV;
1066 1041
1067 unregister_framebuffer(&all->info); 1042 return of_register_driver(&ffb_driver, &of_bus_type);
1068 fb_dealloc_cmap(&all->info.cmap);
1069 kfree(all);
1070 }
1071} 1043}
1072 1044
1073int __init 1045void __exit ffb_exit(void)
1074ffb_setup(char *arg)
1075{ 1046{
1076 /* No cmdline options yet... */ 1047 of_unregister_driver(&ffb_driver);
1077 return 0;
1078} 1048}
1079 1049
1080module_init(ffb_init); 1050module_init(ffb_init);
1081
1082#ifdef MODULE
1083module_exit(ffb_exit); 1051module_exit(ffb_exit);
1084#endif
1085 1052
1086MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets"); 1053MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets");
1087MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 1054MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
1055MODULE_VERSION("2.0");
1088MODULE_LICENSE("GPL"); 1056MODULE_LICENSE("GPL");
diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c
index 605d1a132020..1b981b635675 100644
--- a/drivers/video/g364fb.c
+++ b/drivers/video/g364fb.c
@@ -21,7 +21,6 @@
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/string.h> 22#include <linux/string.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/tty.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 5e25b9860196..bf0e60b5a3b6 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -9,7 +9,6 @@
9 * more details. 9 * more details.
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/delay.h> 12#include <linux/delay.h>
14#include <linux/platform_device.h> 13#include <linux/platform_device.h>
15#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 20e69156d728..bcf9cea54d8b 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -15,7 +15,6 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/tty.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/delay.h> 19#include <linux/delay.h>
21#include <linux/fb.h> 20#include <linux/fb.h>
@@ -376,8 +375,6 @@ static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *
376 release_mem_region(gx1_gx_base() + 0x8300, 0x100); 375 release_mem_region(gx1_gx_base() + 0x8300, 0x100);
377 } 376 }
378 377
379 pci_disable_device(pdev);
380
381 if (info) 378 if (info)
382 framebuffer_release(info); 379 framebuffer_release(info);
383 return ret; 380 return ret;
@@ -399,7 +396,6 @@ static void gx1fb_remove(struct pci_dev *pdev)
399 iounmap(par->dc_regs); 396 iounmap(par->dc_regs);
400 release_mem_region(gx1_gx_base() + 0x8300, 0x100); 397 release_mem_region(gx1_gx_base() + 0x8300, 0x100);
401 398
402 pci_disable_device(pdev);
403 pci_set_drvdata(pdev, NULL); 399 pci_set_drvdata(pdev, NULL);
404 400
405 framebuffer_release(info); 401 framebuffer_release(info);
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 89c34b15f5d4..0d3643fc6293 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -25,7 +25,6 @@
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/tty.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31#include <linux/fb.h> 30#include <linux/fb.h>
@@ -354,8 +353,6 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
354 pci_release_region(pdev, 2); 353 pci_release_region(pdev, 2);
355 } 354 }
356 355
357 pci_disable_device(pdev);
358
359 if (info) 356 if (info)
360 framebuffer_release(info); 357 framebuffer_release(info);
361 return ret; 358 return ret;
@@ -377,7 +374,6 @@ static void gxfb_remove(struct pci_dev *pdev)
377 iounmap(par->dc_regs); 374 iounmap(par->dc_regs);
378 pci_release_region(pdev, 2); 375 pci_release_region(pdev, 2);
379 376
380 pci_disable_device(pdev);
381 pci_set_drvdata(pdev, NULL); 377 pci_set_drvdata(pdev, NULL);
382 378
383 framebuffer_release(info); 379 framebuffer_release(info);
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c
index 4e39035cf335..fb9e67228543 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/hgafb.c
@@ -36,7 +36,6 @@
36#include <linux/spinlock.h> 36#include <linux/spinlock.h>
37#include <linux/string.h> 37#include <linux/string.h>
38#include <linux/mm.h> 38#include <linux/mm.h>
39#include <linux/tty.h>
40#include <linux/slab.h> 39#include <linux/slab.h>
41#include <linux/delay.h> 40#include <linux/delay.h>
42#include <linux/fb.h> 41#include <linux/fb.h>
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index f04ca721f94c..3afb472763c0 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -4,36 +4,32 @@
4 * (C) 1999 Mihai Spatar 4 * (C) 1999 Mihai Spatar
5 * (C) 2000 YAEGASHI Takeshi 5 * (C) 2000 YAEGASHI Takeshi
6 * (C) 2003, 2004 Paul Mundt 6 * (C) 2003, 2004 Paul Mundt
7 * (C) 2003, 2004 Andriy Skulysh 7 * (C) 2003, 2004, 2006 Andriy Skulysh
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for 10 * License. See the file COPYING in the main directory of this archive for
11 * more details. 11 * more details.
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
18#include <linux/errno.h> 17#include <linux/errno.h>
19#include <linux/string.h> 18#include <linux/string.h>
20#include <linux/mm.h> 19#include <linux/mm.h>
21#include <linux/tty.h>
22#include <linux/slab.h> 20#include <linux/slab.h>
23#include <linux/delay.h> 21#include <linux/delay.h>
24#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/platform_device.h>
25#include <linux/fb.h> 24#include <linux/fb.h>
26 25
27#include <asm/machvec.h> 26#include <asm/machvec.h>
28#include <asm/uaccess.h> 27#include <asm/uaccess.h>
29#include <asm/pgtable.h> 28#include <asm/pgtable.h>
30#include <asm/io.h> 29#include <asm/io.h>
31#include <asm/hd64461/hd64461.h> 30#include <asm/hd64461.h>
32
33#ifdef MACH_HP600
34#include <asm/cpu/dac.h> 31#include <asm/cpu/dac.h>
35#include <asm/hp6xx/hp6xx.h> 32#include <asm/hp6xx/hp6xx.h>
36#endif
37 33
38#define WIDTH 640 34#define WIDTH 640
39 35
@@ -47,7 +43,6 @@ static struct fb_var_screeninfo hitfb_var __initdata = {
47static struct fb_fix_screeninfo hitfb_fix __initdata = { 43static struct fb_fix_screeninfo hitfb_fix __initdata = {
48 .id = "Hitachi HD64461", 44 .id = "Hitachi HD64461",
49 .type = FB_TYPE_PACKED_PIXELS, 45 .type = FB_TYPE_PACKED_PIXELS,
50 .ypanstep = 8,
51 .accel = FB_ACCEL_NONE, 46 .accel = FB_ACCEL_NONE,
52}; 47};
53 48
@@ -75,26 +70,14 @@ static inline void hitfb_accel_set_dest(int truecolor, u16 dx, u16 dy,
75 if (truecolor) 70 if (truecolor)
76 saddr <<= 1; 71 saddr <<= 1;
77 72
78 fb_writew(width, HD64461_BBTDWR); 73 fb_writew(width-1, HD64461_BBTDWR);
79 fb_writew(height, HD64461_BBTDHR); 74 fb_writew(height-1, HD64461_BBTDHR);
80 75
81 fb_writew(saddr & 0xffff, HD64461_BBTDSARL); 76 fb_writew(saddr & 0xffff, HD64461_BBTDSARL);
82 fb_writew(saddr >> 16, HD64461_BBTDSARH); 77 fb_writew(saddr >> 16, HD64461_BBTDSARH);
83 78
84} 79}
85 80
86static inline void hitfb_accel_solidfill(int truecolor, u16 dx, u16 dy,
87 u16 width, u16 height, u16 color)
88{
89 hitfb_accel_set_dest(truecolor, dx, dy, width, height);
90
91 fb_writew(0x00f0, HD64461_BBTROPR);
92 fb_writew(16, HD64461_BBTMDR);
93 fb_writew(color, HD64461_GRSCR);
94
95 hitfb_accel_start(truecolor);
96}
97
98static inline void hitfb_accel_bitblt(int truecolor, u16 sx, u16 sy, u16 dx, 81static inline void hitfb_accel_bitblt(int truecolor, u16 sx, u16 sy, u16 dx,
99 u16 dy, u16 width, u16 height, u16 rop, 82 u16 dy, u16 width, u16 height, u16 rop,
100 u32 mask_addr) 83 u32 mask_addr)
@@ -102,6 +85,8 @@ static inline void hitfb_accel_bitblt(int truecolor, u16 sx, u16 sy, u16 dx,
102 u32 saddr, daddr; 85 u32 saddr, daddr;
103 u32 maddr = 0; 86 u32 maddr = 0;
104 87
88 height--;
89 width--;
105 fb_writew(rop, HD64461_BBTROPR); 90 fb_writew(rop, HD64461_BBTROPR);
106 if ((sy < dy) || ((sy == dy) && (sx <= dx))) { 91 if ((sy < dy) || ((sy == dy) && (sx <= dx))) {
107 saddr = WIDTH * (sy + height) + sx + width; 92 saddr = WIDTH * (sy + height) + sx + width;
@@ -148,6 +133,7 @@ static void hitfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
148 if (rect->rop != ROP_COPY) 133 if (rect->rop != ROP_COPY)
149 cfb_fillrect(p, rect); 134 cfb_fillrect(p, rect);
150 else { 135 else {
136 hitfb_accel_wait();
151 fb_writew(0x00f0, HD64461_BBTROPR); 137 fb_writew(0x00f0, HD64461_BBTROPR);
152 fb_writew(16, HD64461_BBTMDR); 138 fb_writew(16, HD64461_BBTMDR);
153 139
@@ -163,16 +149,15 @@ static void hitfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
163 rect->height); 149 rect->height);
164 hitfb_accel_start(0); 150 hitfb_accel_start(0);
165 } 151 }
166 hitfb_accel_wait();
167 } 152 }
168} 153}
169 154
170static void hitfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) 155static void hitfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
171{ 156{
157 hitfb_accel_wait();
172 hitfb_accel_bitblt(p->var.bits_per_pixel == 16, area->sx, area->sy, 158 hitfb_accel_bitblt(p->var.bits_per_pixel == 16, area->sx, area->sy,
173 area->dx, area->dy, area->width, area->height, 159 area->dx, area->dy, area->width, area->height,
174 0x00cc, 0); 160 0x00cc, 0);
175 hitfb_accel_wait();
176} 161}
177 162
178static int hitfb_pan_display(struct fb_var_screeninfo *var, 163static int hitfb_pan_display(struct fb_var_screeninfo *var,
@@ -184,7 +169,7 @@ static int hitfb_pan_display(struct fb_var_screeninfo *var,
184 if (xoffset != 0) 169 if (xoffset != 0)
185 return -EINVAL; 170 return -EINVAL;
186 171
187 fb_writew(yoffset, HD64461_LCDCBAR); 172 fb_writew((yoffset*info->fix.line_length)>>10, HD64461_LCDCBAR);
188 173
189 return 0; 174 return 0;
190} 175}
@@ -194,12 +179,6 @@ int hitfb_blank(int blank_mode, struct fb_info *info)
194 unsigned short v; 179 unsigned short v;
195 180
196 if (blank_mode) { 181 if (blank_mode) {
197#ifdef MACH_HP600
198 sh_dac_disable(DAC_LCD_BRIGHTNESS);
199 v = fb_readw(HD64461_GPBDR);
200 v |= HD64461_GPBDR_LCDOFF;
201 fb_writew(v, HD64461_GPBDR);
202#endif
203 v = fb_readw(HD64461_LDR1); 182 v = fb_readw(HD64461_LDR1);
204 v &= ~HD64461_LDR1_DON; 183 v &= ~HD64461_LDR1_DON;
205 fb_writew(v, HD64461_LDR1); 184 fb_writew(v, HD64461_LDR1);
@@ -215,19 +194,18 @@ int hitfb_blank(int blank_mode, struct fb_info *info)
215 v = fb_readw(HD64461_STBCR); 194 v = fb_readw(HD64461_STBCR);
216 v &= ~HD64461_STBCR_SLCDST; 195 v &= ~HD64461_STBCR_SLCDST;
217 fb_writew(v, HD64461_STBCR); 196 fb_writew(v, HD64461_STBCR);
218#ifdef MACH_HP600
219 sh_dac_enable(DAC_LCD_BRIGHTNESS);
220 v = fb_readw(HD64461_GPBDR);
221 v &= ~HD64461_GPBDR_LCDOFF;
222 fb_writew(v, HD64461_GPBDR);
223#endif
224 v = fb_readw(HD64461_LDR1);
225 v |= HD64461_LDR1_DON;
226 fb_writew(v, HD64461_LDR1);
227 197
228 v = fb_readw(HD64461_LCDCCR); 198 v = fb_readw(HD64461_LCDCCR);
229 v &= ~HD64461_LCDCCR_MOFF; 199 v &= ~(HD64461_LCDCCR_MOFF | HD64461_LCDCCR_STREQ);
230 fb_writew(v, HD64461_LCDCCR); 200 fb_writew(v, HD64461_LCDCCR);
201
202 do {
203 v = fb_readw(HD64461_LCDCCR);
204 } while(v&HD64461_LCDCCR_STBACK);
205
206 v = fb_readw(HD64461_LDR1);
207 v |= HD64461_LDR1_DON;
208 fb_writew(v, HD64461_LDR1);
231 } 209 }
232 return 0; 210 return 0;
233} 211}
@@ -235,7 +213,7 @@ int hitfb_blank(int blank_mode, struct fb_info *info)
235static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green, 213static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green,
236 unsigned blue, unsigned transp, struct fb_info *info) 214 unsigned blue, unsigned transp, struct fb_info *info)
237{ 215{
238 if (regno >= info->cmap.len) 216 if (regno >= 256)
239 return 1; 217 return 1;
240 218
241 switch (info->var.bits_per_pixel) { 219 switch (info->var.bits_per_pixel) {
@@ -246,6 +224,8 @@ static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green,
246 fb_writew(blue >> 10, HD64461_CPTWDR); 224 fb_writew(blue >> 10, HD64461_CPTWDR);
247 break; 225 break;
248 case 16: 226 case 16:
227 if (regno >= 16)
228 return 1;
249 ((u32 *) (info->pseudo_palette))[regno] = 229 ((u32 *) (info->pseudo_palette))[regno] =
250 ((red & 0xf800)) | 230 ((red & 0xf800)) |
251 ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); 231 ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
@@ -254,26 +234,113 @@ static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green,
254 return 0; 234 return 0;
255} 235}
256 236
237static int hitfb_sync(struct fb_info *info)
238{
239 hitfb_accel_wait();
240
241 return 0;
242}
243
244static int hitfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
245{
246 int maxy;
247
248 var->xres = info->var.xres;
249 var->xres_virtual = info->var.xres;
250 var->yres = info->var.yres;
251
252 if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16))
253 var->bits_per_pixel = info->var.bits_per_pixel;
254
255 if (var->yres_virtual < var->yres)
256 var->yres_virtual = var->yres;
257
258 maxy = info->fix.smem_len / var->xres;
259
260 if (var->bits_per_pixel == 16)
261 maxy /= 2;
262
263 if (var->yres_virtual > maxy)
264 var->yres_virtual = maxy;
265
266 var->xoffset = 0;
267 var->yoffset = 0;
268
269 switch (var->bits_per_pixel) {
270 case 8:
271 var->red.offset = 0;
272 var->red.length = 8;
273 var->green.offset = 0;
274 var->green.length = 8;
275 var->blue.offset = 0;
276 var->blue.length = 8;
277 var->transp.offset = 0;
278 var->transp.length = 0;
279 break;
280 case 16: /* RGB 565 */
281 var->red.offset = 11;
282 var->red.length = 5;
283 var->green.offset = 5;
284 var->green.length = 6;
285 var->blue.offset = 0;
286 var->blue.length = 5;
287 var->transp.offset = 0;
288 var->transp.length = 0;
289 break;
290 }
291
292 return 0;
293}
294
295static int hitfb_set_par(struct fb_info *info)
296{
297 unsigned short ldr3;
298
299 switch (info->var.bits_per_pixel) {
300 case 8:
301 info->fix.line_length = info->var.xres;
302 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
303 info->fix.ypanstep = 16;
304 break;
305 case 16:
306 info->fix.line_length = info->var.xres*2;
307 info->fix.visual = FB_VISUAL_TRUECOLOR;
308 info->fix.ypanstep = 8;
309 break;
310 }
311
312 fb_writew(info->fix.line_length, HD64461_LCDCLOR);
313 ldr3 = fb_readw(HD64461_LDR3);
314 ldr3 &= ~15;
315 ldr3 |= (info->var.bits_per_pixel == 8) ? 4 : 8;
316 fb_writew(ldr3, HD64461_LDR3);
317 return 0;
318}
319
257static struct fb_ops hitfb_ops = { 320static struct fb_ops hitfb_ops = {
258 .owner = THIS_MODULE, 321 .owner = THIS_MODULE,
322 .fb_check_var = hitfb_check_var,
323 .fb_set_par = hitfb_set_par,
259 .fb_setcolreg = hitfb_setcolreg, 324 .fb_setcolreg = hitfb_setcolreg,
260 .fb_blank = hitfb_blank, 325 .fb_blank = hitfb_blank,
326 .fb_sync = hitfb_sync,
261 .fb_pan_display = hitfb_pan_display, 327 .fb_pan_display = hitfb_pan_display,
262 .fb_fillrect = hitfb_fillrect, 328 .fb_fillrect = hitfb_fillrect,
263 .fb_copyarea = hitfb_copyarea, 329 .fb_copyarea = hitfb_copyarea,
264 .fb_imageblit = cfb_imageblit, 330 .fb_imageblit = cfb_imageblit,
265}; 331};
266 332
267int __init hitfb_init(void) 333static int __init hitfb_probe(struct platform_device *dev)
268{ 334{
269 unsigned short lcdclor, ldr3, ldvndr; 335 unsigned short lcdclor, ldr3, ldvndr;
270 int size;
271 336
272 if (fb_get_options("hitfb", NULL)) 337 if (fb_get_options("hitfb", NULL))
273 return -ENODEV; 338 return -ENODEV;
274 339
340 hitfb_fix.mmio_start = CONFIG_HD64461_IOBASE+0x1000;
341 hitfb_fix.mmio_len = 0x1000;
275 hitfb_fix.smem_start = CONFIG_HD64461_IOBASE + 0x02000000; 342 hitfb_fix.smem_start = CONFIG_HD64461_IOBASE + 0x02000000;
276 hitfb_fix.smem_len = (MACH_HP690) ? 1024 * 1024 : 512 * 1024; 343 hitfb_fix.smem_len = 512 * 1024;
277 344
278 lcdclor = fb_readw(HD64461_LCDCLOR); 345 lcdclor = fb_readw(HD64461_LCDCLOR);
279 ldvndr = fb_readw(HD64461_LDVNDR); 346 ldvndr = fb_readw(HD64461_LDVNDR);
@@ -323,12 +390,12 @@ int __init hitfb_init(void)
323 fb_info.var = hitfb_var; 390 fb_info.var = hitfb_var;
324 fb_info.fix = hitfb_fix; 391 fb_info.fix = hitfb_fix;
325 fb_info.pseudo_palette = pseudo_palette; 392 fb_info.pseudo_palette = pseudo_palette;
326 fb_info.flags = FBINFO_DEFAULT; 393 fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
394 FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA;
327 395
328 fb_info.screen_base = (void *)hitfb_fix.smem_start; 396 fb_info.screen_base = (void *)hitfb_fix.smem_start;
329 397
330 size = (fb_info.var.bits_per_pixel == 8) ? 256 : 16; 398 fb_alloc_cmap(&fb_info.cmap, 256, 0);
331 fb_alloc_cmap(&fb_info.cmap, size, 0);
332 399
333 if (register_framebuffer(&fb_info) < 0) 400 if (register_framebuffer(&fb_info) < 0)
334 return -EINVAL; 401 return -EINVAL;
@@ -338,9 +405,75 @@ int __init hitfb_init(void)
338 return 0; 405 return 0;
339} 406}
340 407
408static int __devexit hitfb_remove(struct platform_device *dev)
409{
410 return unregister_framebuffer(&fb_info);
411}
412
413#ifdef CONFIG_PM
414static int hitfb_suspend(struct platform_device *dev, pm_message_t state)
415{
416 u16 v;
417
418 hitfb_blank(1,0);
419 v = fb_readw(HD64461_STBCR);
420 v |= HD64461_STBCR_SLCKE_IST;
421 fb_writew(v, HD64461_STBCR);
422
423 return 0;
424}
425
426static int hitfb_resume(struct platform_device *dev)
427{
428 u16 v;
429
430 v = fb_readw(HD64461_STBCR);
431 v &= ~HD64461_STBCR_SLCKE_OST;
432 msleep(100);
433 v = fb_readw(HD64461_STBCR);
434 v &= ~HD64461_STBCR_SLCKE_IST;
435 fb_writew(v, HD64461_STBCR);
436 hitfb_blank(0,0);
437
438 return 0;
439}
440#endif
441
442static struct platform_driver hitfb_driver = {
443 .probe = hitfb_probe,
444 .remove = __devexit_p(hitfb_remove),
445#ifdef CONFIG_PM
446 .suspend = hitfb_suspend,
447 .resume = hitfb_resume,
448#endif
449 .driver = {
450 .name = "hitfb",
451 },
452};
453
454static struct platform_device hitfb_device = {
455 .name = "hitfb",
456 .id = -1,
457};
458
459static int __init hitfb_init(void)
460{
461 int ret;
462
463 ret = platform_driver_register(&hitfb_driver);
464 if (!ret) {
465 ret = platform_device_register(&hitfb_device);
466 if (ret)
467 platform_driver_unregister(&hitfb_driver);
468 }
469 return ret;
470}
471
472
341static void __exit hitfb_exit(void) 473static void __exit hitfb_exit(void)
342{ 474{
343 unregister_framebuffer(&fb_info); 475 platform_device_unregister(&hitfb_device);
476 platform_driver_unregister(&hitfb_driver);
344} 477}
345 478
346module_init(hitfb_init); 479module_init(hitfb_init);
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index abd920a663a0..91cf3b577d15 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -11,7 +11,6 @@
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <linux/tty.h>
15#include <linux/slab.h> 14#include <linux/slab.h>
16#include <linux/delay.h> 15#include <linux/delay.h>
17#include <linux/init.h> 16#include <linux/init.h>
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 3fe3ae1aff12..7d06b38e80a0 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -8,7 +8,6 @@
8 * License. See the file COPYING in the main directory of this archive for 8 * License. See the file COPYING in the main directory of this archive for
9 * more details. 9 * more details.
10 */ 10 */
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
14#include <linux/sched.h> 13#include <linux/sched.h>
@@ -99,7 +98,6 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
99 chan->algo.getsda = i810i2c_getsda; 98 chan->algo.getsda = i810i2c_getsda;
100 chan->algo.getscl = i810i2c_getscl; 99 chan->algo.getscl = i810i2c_getscl;
101 chan->algo.udelay = 10; 100 chan->algo.udelay = 10;
102 chan->algo.mdelay = 10;
103 chan->algo.timeout = (HZ/2); 101 chan->algo.timeout = (HZ/2);
104 chan->algo.data = chan; 102 chan->algo.data = chan;
105 103
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 44aa2ffff973..d42edaccb84c 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -29,12 +29,10 @@
29 */ 29 */
30 30
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/config.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
34#include <linux/errno.h> 33#include <linux/errno.h>
35#include <linux/string.h> 34#include <linux/string.h>
36#include <linux/mm.h> 35#include <linux/mm.h>
37#include <linux/tty.h>
38#include <linux/slab.h> 36#include <linux/slab.h>
39#include <linux/fb.h> 37#include <linux/fb.h>
40#include <linux/init.h> 38#include <linux/init.h>
@@ -1556,15 +1554,17 @@ static struct fb_ops i810fb_ops __devinitdata = {
1556/*********************************************************************** 1554/***********************************************************************
1557 * Power Management * 1555 * Power Management *
1558 ***********************************************************************/ 1556 ***********************************************************************/
1559static int i810fb_suspend(struct pci_dev *dev, pm_message_t state) 1557static int i810fb_suspend(struct pci_dev *dev, pm_message_t mesg)
1560{ 1558{
1561 struct fb_info *info = pci_get_drvdata(dev); 1559 struct fb_info *info = pci_get_drvdata(dev);
1562 struct i810fb_par *par = info->par; 1560 struct i810fb_par *par = info->par;
1563 1561
1564 par->cur_state = state.event; 1562 par->cur_state = mesg.event;
1565 1563
1566 if (state.event == PM_EVENT_FREEZE) { 1564 switch (mesg.event) {
1567 dev->dev.power.power_state = state; 1565 case PM_EVENT_FREEZE:
1566 case PM_EVENT_PRETHAW:
1567 dev->dev.power.power_state = mesg;
1568 return 0; 1568 return 0;
1569 } 1569 }
1570 1570
@@ -1580,7 +1580,7 @@ static int i810fb_suspend(struct pci_dev *dev, pm_message_t state)
1580 1580
1581 pci_save_state(dev); 1581 pci_save_state(dev);
1582 pci_disable_device(dev); 1582 pci_disable_device(dev);
1583 pci_set_power_state(dev, pci_choose_state(dev, state)); 1583 pci_set_power_state(dev, pci_choose_state(dev, mesg));
1584 release_console_sem(); 1584 release_console_sem();
1585 1585
1586 return 0; 1586 return 0;
@@ -2110,9 +2110,6 @@ static void i810fb_release_resource(struct fb_info *info,
2110 if (par->res_flags & MMIO_REQ) 2110 if (par->res_flags & MMIO_REQ)
2111 release_mem_region(par->mmio_start_phys, MMIO_SIZE); 2111 release_mem_region(par->mmio_start_phys, MMIO_SIZE);
2112 2112
2113 if (par->res_flags & PCI_DEVICE_ENABLED)
2114 pci_disable_device(par->dev);
2115
2116 framebuffer_release(info); 2113 framebuffer_release(info);
2117 2114
2118} 2115}
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 6b88050d21bf..67f384f86758 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -33,7 +33,6 @@
33#include <linux/errno.h> 33#include <linux/errno.h>
34#include <linux/string.h> 34#include <linux/string.h>
35#include <linux/mm.h> 35#include <linux/mm.h>
36#include <linux/tty.h>
37#include <linux/slab.h> 36#include <linux/slab.h>
38#include <linux/vmalloc.h> 37#include <linux/vmalloc.h>
39#include <linux/delay.h> 38#include <linux/delay.h>
@@ -232,9 +231,6 @@ static int igafb_mmap(struct fb_info *info,
232 231
233 size = vma->vm_end - vma->vm_start; 232 size = vma->vm_end - vma->vm_start;
234 233
235 /* To stop the swapper from even considering these pages. */
236 vma->vm_flags |= (VM_SHM | VM_LOCKED);
237
238 /* Each page, see which map applies */ 234 /* Each page, see which map applies */
239 for (page = 0; page < size; ) { 235 for (page = 0; page < size; ) {
240 map_size = 0; 236 map_size = 0;
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c
new file mode 100644
index 000000000000..18ea4a549105
--- /dev/null
+++ b/drivers/video/imacfb.c
@@ -0,0 +1,380 @@
1/*
2 * framebuffer driver for Intel Based Mac's
3 *
4 * (c) 2006 Edgar Hucek <gimli@dark-green.com>
5 * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
6 *
7 */
8
9#include <linux/delay.h>
10#include <linux/errno.h>
11#include <linux/fb.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/mm.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/screen_info.h>
19#include <linux/slab.h>
20#include <linux/string.h>
21#include <linux/dmi.h>
22#include <linux/efi.h>
23
24#include <asm/io.h>
25
26#include <video/vga.h>
27
28typedef enum _MAC_TYPE {
29 M_I17,
30 M_I20,
31 M_MINI,
32 M_MACBOOK,
33 M_UNKNOWN
34} MAC_TYPE;
35
36/* --------------------------------------------------------------------- */
37
38static struct fb_var_screeninfo imacfb_defined __initdata = {
39 .activate = FB_ACTIVATE_NOW,
40 .height = -1,
41 .width = -1,
42 .right_margin = 32,
43 .upper_margin = 16,
44 .lower_margin = 4,
45 .vsync_len = 4,
46 .vmode = FB_VMODE_NONINTERLACED,
47};
48
49static struct fb_fix_screeninfo imacfb_fix __initdata = {
50 .id = "IMAC VGA",
51 .type = FB_TYPE_PACKED_PIXELS,
52 .accel = FB_ACCEL_NONE,
53 .visual = FB_VISUAL_TRUECOLOR,
54};
55
56static int inverse;
57static int model = M_UNKNOWN;
58static int manual_height;
59static int manual_width;
60
61static int set_system(struct dmi_system_id *id)
62{
63 printk(KERN_INFO "imacfb: %s detected - set system to %ld\n",
64 id->ident, (long)id->driver_data);
65
66 model = (long)id->driver_data;
67
68 return 0;
69}
70
71static struct dmi_system_id __initdata dmi_system_table[] = {
72 { set_system, "iMac4,1", {
73 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
74 DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17},
75 { set_system, "MacBookPro1,1", {
76 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
77 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17},
78 { set_system, "MacBook1,1", {
79 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
80 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK},
81 { set_system, "Macmini1,1", {
82 DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
83 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI},
84 {},
85};
86
87#define DEFAULT_FB_MEM 1024*1024*16
88
89/* --------------------------------------------------------------------- */
90
91static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green,
92 unsigned blue, unsigned transp,
93 struct fb_info *info)
94{
95 /*
96 * Set a single color register. The values supplied are
97 * already rounded down to the hardware's capabilities
98 * (according to the entries in the `var' structure). Return
99 * != 0 for invalid regno.
100 */
101
102 if (regno >= info->cmap.len)
103 return 1;
104
105 if (regno < 16) {
106 red >>= 8;
107 green >>= 8;
108 blue >>= 8;
109 ((u32 *)(info->pseudo_palette))[regno] =
110 (red << info->var.red.offset) |
111 (green << info->var.green.offset) |
112 (blue << info->var.blue.offset);
113 }
114 return 0;
115}
116
117static struct fb_ops imacfb_ops = {
118 .owner = THIS_MODULE,
119 .fb_setcolreg = imacfb_setcolreg,
120 .fb_fillrect = cfb_fillrect,
121 .fb_copyarea = cfb_copyarea,
122 .fb_imageblit = cfb_imageblit,
123};
124
125static int __init imacfb_setup(char *options)
126{
127 char *this_opt;
128
129 if (!options || !*options)
130 return 0;
131
132 while ((this_opt = strsep(&options, ",")) != NULL) {
133 if (!*this_opt) continue;
134
135 if (!strcmp(this_opt, "inverse"))
136 inverse = 1;
137 else if (!strcmp(this_opt, "i17"))
138 model = M_I17;
139 else if (!strcmp(this_opt, "i20"))
140 model = M_I20;
141 else if (!strcmp(this_opt, "mini"))
142 model = M_MINI;
143 else if (!strcmp(this_opt, "macbook"))
144 model = M_MACBOOK;
145 else if (!strncmp(this_opt, "height:", 7))
146 manual_height = simple_strtoul(this_opt+7, NULL, 0);
147 else if (!strncmp(this_opt, "width:", 6))
148 manual_width = simple_strtoul(this_opt+6, NULL, 0);
149 }
150 return 0;
151}
152
153static int __init imacfb_probe(struct platform_device *dev)
154{
155 struct fb_info *info;
156 int err;
157 unsigned int size_vmode;
158 unsigned int size_remap;
159 unsigned int size_total;
160
161 screen_info.lfb_depth = 32;
162 screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000;
163 screen_info.pages=1;
164 screen_info.blue_size = 8;
165 screen_info.blue_pos = 0;
166 screen_info.green_size = 8;
167 screen_info.green_pos = 8;
168 screen_info.red_size = 8;
169 screen_info.red_pos = 16;
170 screen_info.rsvd_size = 8;
171 screen_info.rsvd_pos = 24;
172
173 switch (model) {
174 case M_I17:
175 screen_info.lfb_width = 1440;
176 screen_info.lfb_height = 900;
177 screen_info.lfb_linelength = 1472 * 4;
178 screen_info.lfb_base = 0x80010000;
179 break;
180 case M_I20:
181 screen_info.lfb_width = 1680;
182 screen_info.lfb_height = 1050;
183 screen_info.lfb_linelength = 1728 * 4;
184 screen_info.lfb_base = 0x80010000;
185 break;
186 case M_MINI:
187 screen_info.lfb_width = 1024;
188 screen_info.lfb_height = 768;
189 screen_info.lfb_linelength = 2048 * 4;
190 screen_info.lfb_base = 0x80000000;
191 break;
192 case M_MACBOOK:
193 screen_info.lfb_width = 1280;
194 screen_info.lfb_height = 800;
195 screen_info.lfb_linelength = 2048 * 4;
196 screen_info.lfb_base = 0x80000000;
197 break;
198 }
199
200 /* if the user wants to manually specify height/width,
201 we will override the defaults */
202 /* TODO: eventually get auto-detection working */
203 if (manual_height > 0)
204 screen_info.lfb_height = manual_height;
205 if (manual_width > 0)
206 screen_info.lfb_width = manual_width;
207
208 imacfb_fix.smem_start = screen_info.lfb_base;
209 imacfb_defined.bits_per_pixel = screen_info.lfb_depth;
210 imacfb_defined.xres = screen_info.lfb_width;
211 imacfb_defined.yres = screen_info.lfb_height;
212 imacfb_fix.line_length = screen_info.lfb_linelength;
213
214 /* size_vmode -- that is the amount of memory needed for the
215 * used video mode, i.e. the minimum amount of
216 * memory we need. */
217 size_vmode = imacfb_defined.yres * imacfb_fix.line_length;
218
219 /* size_total -- all video memory we have. Used for
220 * entries, ressource allocation and bounds
221 * checking. */
222 size_total = screen_info.lfb_size * 65536;
223 if (size_total < size_vmode)
224 size_total = size_vmode;
225
226 /* size_remap -- the amount of video memory we are going to
227 * use for imacfb. With modern cards it is no
228 * option to simply use size_total as that
229 * wastes plenty of kernel address space. */
230 size_remap = size_vmode * 2;
231 if (size_remap < size_vmode)
232 size_remap = size_vmode;
233 if (size_remap > size_total)
234 size_remap = size_total;
235 imacfb_fix.smem_len = size_remap;
236
237#ifndef __i386__
238 screen_info.imacpm_seg = 0;
239#endif
240
241 if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) {
242 printk(KERN_WARNING
243 "imacfb: cannot reserve video memory at 0x%lx\n",
244 imacfb_fix.smem_start);
245 /* We cannot make this fatal. Sometimes this comes from magic
246 spaces our resource handlers simply don't know about */
247 }
248
249 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
250 if (!info) {
251 err = -ENOMEM;
252 goto err_release_mem;
253 }
254 info->pseudo_palette = info->par;
255 info->par = NULL;
256
257 info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len);
258 if (!info->screen_base) {
259 printk(KERN_ERR "imacfb: abort, cannot ioremap video memory "
260 "0x%x @ 0x%lx\n",
261 imacfb_fix.smem_len, imacfb_fix.smem_start);
262 err = -EIO;
263 goto err_unmap;
264 }
265
266 printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, "
267 "using %dk, total %dk\n",
268 imacfb_fix.smem_start, info->screen_base,
269 size_remap/1024, size_total/1024);
270 printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
271 imacfb_defined.xres, imacfb_defined.yres,
272 imacfb_defined.bits_per_pixel, imacfb_fix.line_length,
273 screen_info.pages);
274
275 imacfb_defined.xres_virtual = imacfb_defined.xres;
276 imacfb_defined.yres_virtual = imacfb_fix.smem_len /
277 imacfb_fix.line_length;
278 printk(KERN_INFO "imacfb: scrolling: redraw\n");
279 imacfb_defined.yres_virtual = imacfb_defined.yres;
280
281 /* some dummy values for timing to make fbset happy */
282 imacfb_defined.pixclock = 10000000 / imacfb_defined.xres *
283 1000 / imacfb_defined.yres;
284 imacfb_defined.left_margin = (imacfb_defined.xres / 8) & 0xf8;
285 imacfb_defined.hsync_len = (imacfb_defined.xres / 8) & 0xf8;
286
287 imacfb_defined.red.offset = screen_info.red_pos;
288 imacfb_defined.red.length = screen_info.red_size;
289 imacfb_defined.green.offset = screen_info.green_pos;
290 imacfb_defined.green.length = screen_info.green_size;
291 imacfb_defined.blue.offset = screen_info.blue_pos;
292 imacfb_defined.blue.length = screen_info.blue_size;
293 imacfb_defined.transp.offset = screen_info.rsvd_pos;
294 imacfb_defined.transp.length = screen_info.rsvd_size;
295
296 printk(KERN_INFO "imacfb: %s: "
297 "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
298 "Truecolor",
299 screen_info.rsvd_size,
300 screen_info.red_size,
301 screen_info.green_size,
302 screen_info.blue_size,
303 screen_info.rsvd_pos,
304 screen_info.red_pos,
305 screen_info.green_pos,
306 screen_info.blue_pos);
307
308 imacfb_fix.ypanstep = 0;
309 imacfb_fix.ywrapstep = 0;
310
311 /* request failure does not faze us, as vgacon probably has this
312 * region already (FIXME) */
313 request_region(0x3c0, 32, "imacfb");
314
315 info->fbops = &imacfb_ops;
316 info->var = imacfb_defined;
317 info->fix = imacfb_fix;
318 info->flags = FBINFO_FLAG_DEFAULT;
319
320 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
321 err = -ENOMEM;
322 goto err_unmap;
323 }
324 if (register_framebuffer(info)<0) {
325 err = -EINVAL;
326 goto err_fb_dealoc;
327 }
328 printk(KERN_INFO "fb%d: %s frame buffer device\n",
329 info->node, info->fix.id);
330 return 0;
331
332err_fb_dealoc:
333 fb_dealloc_cmap(&info->cmap);
334err_unmap:
335 iounmap(info->screen_base);
336 framebuffer_release(info);
337err_release_mem:
338 release_mem_region(imacfb_fix.smem_start, size_total);
339 return err;
340}
341
342static struct platform_driver imacfb_driver = {
343 .probe = imacfb_probe,
344 .driver = {
345 .name = "imacfb",
346 },
347};
348
349static struct platform_device imacfb_device = {
350 .name = "imacfb",
351};
352
353static int __init imacfb_init(void)
354{
355 int ret;
356 char *option = NULL;
357
358 if (!efi_enabled)
359 return -ENODEV;
360 if (!dmi_check_system(dmi_system_table))
361 return -ENODEV;
362 if (model == M_UNKNOWN)
363 return -ENODEV;
364
365 if (fb_get_options("imacfb", &option))
366 return -ENODEV;
367
368 imacfb_setup(option);
369 ret = platform_driver_register(&imacfb_driver);
370
371 if (!ret) {
372 ret = platform_device_register(&imacfb_device);
373 if (ret)
374 platform_driver_unregister(&imacfb_driver);
375 }
376 return ret;
377}
378module_init(imacfb_init);
379
380MODULE_LICENSE("GPL");
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index f73c642b50c2..5715b8ad0ddc 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -16,13 +16,11 @@
16 * more details. 16 * more details.
17 */ 17 */
18 18
19#include <linux/config.h>
20#include <linux/module.h> 19#include <linux/module.h>
21#include <linux/kernel.h> 20#include <linux/kernel.h>
22#include <linux/errno.h> 21#include <linux/errno.h>
23#include <linux/string.h> 22#include <linux/string.h>
24#include <linux/mm.h> 23#include <linux/mm.h>
25#include <linux/tty.h>
26#include <linux/slab.h> 24#include <linux/slab.h>
27#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
28#include <linux/delay.h> 26#include <linux/delay.h>
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 1718baaeed2a..0f9b2fdc28b1 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -18,7 +18,6 @@
18 18
19//#define DEBUG 1 19//#define DEBUG 1
20 20
21#include <linux/config.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/kernel.h> 22#include <linux/kernel.h>
24#include <linux/sched.h> 23#include <linux/sched.h>
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index f6e30b3d1081..6f9de04193d2 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -108,13 +108,11 @@
108 * 108 *
109 */ 109 */
110 110
111#include <linux/config.h>
112#include <linux/module.h> 111#include <linux/module.h>
113#include <linux/kernel.h> 112#include <linux/kernel.h>
114#include <linux/errno.h> 113#include <linux/errno.h>
115#include <linux/string.h> 114#include <linux/string.h>
116#include <linux/mm.h> 115#include <linux/mm.h>
117#include <linux/tty.h>
118#include <linux/slab.h> 116#include <linux/slab.h>
119#include <linux/delay.h> 117#include <linux/delay.h>
120#include <linux/fb.h> 118#include <linux/fb.h>
@@ -123,6 +121,7 @@
123#include <linux/pci.h> 121#include <linux/pci.h>
124#include <linux/vmalloc.h> 122#include <linux/vmalloc.h>
125#include <linux/pagemap.h> 123#include <linux/pagemap.h>
124#include <linux/screen_info.h>
126 125
127#include <asm/io.h> 126#include <asm/io.h>
128 127
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index bbd82fffc3f6..f887f1efd3fe 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -19,13 +19,11 @@
19 19
20/* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */ 20/* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */
21 21
22#include <linux/config.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/string.h> 25#include <linux/string.h>
27#include <linux/mm.h> 26#include <linux/mm.h>
28#include <linux/tty.h>
29#include <linux/slab.h> 27#include <linux/slab.h>
30#include <linux/delay.h> 28#include <linux/delay.h>
31#include <linux/fb.h> 29#include <linux/fb.h>
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index 477ad297de4e..f0d614a80f1f 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -9,7 +9,6 @@
9 * for more details. 9 * for more details.
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/module.h> 12#include <linux/module.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
@@ -17,7 +16,6 @@
17#include <linux/mm.h> 16#include <linux/mm.h>
18#include <linux/errno.h> 17#include <linux/errno.h>
19#include <linux/string.h> 18#include <linux/string.h>
20#include <linux/tty.h>
21#include <linux/delay.h> 19#include <linux/delay.h>
22#include <linux/fb.h> 20#include <linux/fb.h>
23#include <linux/ioctl.h> 21#include <linux/ioctl.h>
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index a23cfdb9d826..f3a24338d9ac 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -1,6 +1,6 @@
1/* leo.c: LEO frame buffer driver 1/* leo.c: LEO frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) 5 * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
6 * 6 *
@@ -18,8 +18,8 @@
18#include <linux/mm.h> 18#include <linux/mm.h>
19 19
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/sbus.h> 21#include <asm/prom.h>
22#include <asm/oplib.h> 22#include <asm/of_device.h>
23#include <asm/fbio.h> 23#include <asm/fbio.h>
24 24
25#include "sbuslib.h" 25#include "sbuslib.h"
@@ -80,10 +80,10 @@ static struct fb_ops leo_ops = {
80 80
81struct leo_cursor { 81struct leo_cursor {
82 u8 xxx0[16]; 82 u8 xxx0[16];
83 volatile u32 cur_type; 83 u32 cur_type;
84 volatile u32 cur_misc; 84 u32 cur_misc;
85 volatile u32 cur_cursxy; 85 u32 cur_cursxy;
86 volatile u32 cur_data; 86 u32 cur_data;
87}; 87};
88 88
89#define LEO_KRN_TYPE_CLUT0 0x00001000 89#define LEO_KRN_TYPE_CLUT0 0x00001000
@@ -99,27 +99,27 @@ struct leo_cursor {
99#define LEO_KRN_CSR_UNK2 0x00000001 99#define LEO_KRN_CSR_UNK2 0x00000001
100 100
101struct leo_lx_krn { 101struct leo_lx_krn {
102 volatile u32 krn_type; 102 u32 krn_type;
103 volatile u32 krn_csr; 103 u32 krn_csr;
104 volatile u32 krn_value; 104 u32 krn_value;
105}; 105};
106 106
107struct leo_lc_ss0_krn { 107struct leo_lc_ss0_krn {
108 volatile u32 misc; 108 u32 misc;
109 u8 xxx0[0x800-4]; 109 u8 xxx0[0x800-4];
110 volatile u32 rev; 110 u32 rev;
111}; 111};
112 112
113struct leo_lc_ss0_usr { 113struct leo_lc_ss0_usr {
114 volatile u32 csr; 114 u32 csr;
115 volatile u32 addrspace; 115 u32 addrspace;
116 volatile u32 fontmsk; 116 u32 fontmsk;
117 volatile u32 fontt; 117 u32 fontt;
118 volatile u32 extent; 118 u32 extent;
119 volatile u32 src; 119 u32 src;
120 u32 dst; 120 u32 dst;
121 volatile u32 copy; 121 u32 copy;
122 volatile u32 fill; 122 u32 fill;
123}; 123};
124 124
125struct leo_lc_ss1_krn { 125struct leo_lc_ss1_krn {
@@ -132,47 +132,47 @@ struct leo_lc_ss1_usr {
132 132
133struct leo_ld { 133struct leo_ld {
134 u8 xxx0[0xe00]; 134 u8 xxx0[0xe00];
135 volatile u32 csr; 135 u32 csr;
136 volatile u32 wid; 136 u32 wid;
137 volatile u32 wmask; 137 u32 wmask;
138 volatile u32 widclip; 138 u32 widclip;
139 volatile u32 vclipmin; 139 u32 vclipmin;
140 volatile u32 vclipmax; 140 u32 vclipmax;
141 volatile u32 pickmin; /* SS1 only */ 141 u32 pickmin; /* SS1 only */
142 volatile u32 pickmax; /* SS1 only */ 142 u32 pickmax; /* SS1 only */
143 volatile u32 fg; 143 u32 fg;
144 volatile u32 bg; 144 u32 bg;
145 volatile u32 src; /* Copy/Scroll (SS0 only) */ 145 u32 src; /* Copy/Scroll (SS0 only) */
146 volatile u32 dst; /* Copy/Scroll/Fill (SS0 only) */ 146 u32 dst; /* Copy/Scroll/Fill (SS0 only) */
147 volatile u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ 147 u32 extent; /* Copy/Scroll/Fill size (SS0 only) */
148 u32 xxx1[3]; 148 u32 xxx1[3];
149 volatile u32 setsem; /* SS1 only */ 149 u32 setsem; /* SS1 only */
150 volatile u32 clrsem; /* SS1 only */ 150 u32 clrsem; /* SS1 only */
151 volatile u32 clrpick; /* SS1 only */ 151 u32 clrpick; /* SS1 only */
152 volatile u32 clrdat; /* SS1 only */ 152 u32 clrdat; /* SS1 only */
153 volatile u32 alpha; /* SS1 only */ 153 u32 alpha; /* SS1 only */
154 u8 xxx2[0x2c]; 154 u8 xxx2[0x2c];
155 volatile u32 winbg; 155 u32 winbg;
156 volatile u32 planemask; 156 u32 planemask;
157 volatile u32 rop; 157 u32 rop;
158 volatile u32 z; 158 u32 z;
159 volatile u32 dczf; /* SS1 only */ 159 u32 dczf; /* SS1 only */
160 volatile u32 dczb; /* SS1 only */ 160 u32 dczb; /* SS1 only */
161 volatile u32 dcs; /* SS1 only */ 161 u32 dcs; /* SS1 only */
162 volatile u32 dczs; /* SS1 only */ 162 u32 dczs; /* SS1 only */
163 volatile u32 pickfb; /* SS1 only */ 163 u32 pickfb; /* SS1 only */
164 volatile u32 pickbb; /* SS1 only */ 164 u32 pickbb; /* SS1 only */
165 volatile u32 dcfc; /* SS1 only */ 165 u32 dcfc; /* SS1 only */
166 volatile u32 forcecol; /* SS1 only */ 166 u32 forcecol; /* SS1 only */
167 volatile u32 door[8]; /* SS1 only */ 167 u32 door[8]; /* SS1 only */
168 volatile u32 pick[5]; /* SS1 only */ 168 u32 pick[5]; /* SS1 only */
169}; 169};
170 170
171#define LEO_SS1_MISC_ENABLE 0x00000001 171#define LEO_SS1_MISC_ENABLE 0x00000001
172#define LEO_SS1_MISC_STEREO 0x00000002 172#define LEO_SS1_MISC_STEREO 0x00000002
173struct leo_ld_ss1 { 173struct leo_ld_ss1 {
174 u8 xxx0[0xef4]; 174 u8 xxx0[0xef4];
175 volatile u32 ss1_misc; 175 u32 ss1_misc;
176}; 176};
177 177
178struct leo_ld_gbl { 178struct leo_ld_gbl {
@@ -193,9 +193,8 @@ struct leo_par {
193#define LEO_FLAG_BLANKED 0x00000001 193#define LEO_FLAG_BLANKED 0x00000001
194 194
195 unsigned long physbase; 195 unsigned long physbase;
196 unsigned long which_io;
196 unsigned long fbsize; 197 unsigned long fbsize;
197
198 struct sbus_dev *sdev;
199}; 198};
200 199
201static void leo_wait(struct leo_lx_krn __iomem *lx_krn) 200static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
@@ -368,8 +367,7 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
368 367
369 return sbusfb_mmap_helper(leo_mmap_map, 368 return sbusfb_mmap_helper(leo_mmap_map,
370 par->physbase, par->fbsize, 369 par->physbase, par->fbsize,
371 par->sdev->reg_addrs[0].which_io, 370 par->which_io, vma);
372 vma);
373} 371}
374 372
375static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 373static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
@@ -385,11 +383,9 @@ static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
385 */ 383 */
386 384
387static void 385static void
388leo_init_fix(struct fb_info *info) 386leo_init_fix(struct fb_info *info, struct device_node *dp)
389{ 387{
390 struct leo_par *par = (struct leo_par *)info->par; 388 strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
391
392 strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
393 389
394 info->fix.type = FB_TYPE_PACKED_PIXELS; 390 info->fix.type = FB_TYPE_PACKED_PIXELS;
395 info->fix.visual = FB_VISUAL_TRUECOLOR; 391 info->fix.visual = FB_VISUAL_TRUECOLOR;
@@ -532,60 +528,74 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
532struct all_info { 528struct all_info {
533 struct fb_info info; 529 struct fb_info info;
534 struct leo_par par; 530 struct leo_par par;
535 struct list_head list;
536}; 531};
537static LIST_HEAD(leo_list);
538 532
539static void leo_init_one(struct sbus_dev *sdev) 533static void leo_unmap_regs(struct all_info *all)
540{ 534{
541 struct all_info *all; 535 if (all->par.lc_ss0_usr)
542 int linebytes; 536 of_iounmap(all->par.lc_ss0_usr, 0x1000);
537 if (all->par.ld_ss0)
538 of_iounmap(all->par.ld_ss0, 0x1000);
539 if (all->par.ld_ss1)
540 of_iounmap(all->par.ld_ss1, 0x1000);
541 if (all->par.lx_krn)
542 of_iounmap(all->par.lx_krn, 0x1000);
543 if (all->par.cursor)
544 of_iounmap(all->par.cursor, sizeof(struct leo_cursor));
545 if (all->info.screen_base)
546 of_iounmap(all->info.screen_base, 0x800000);
547}
543 548
544 all = kmalloc(sizeof(*all), GFP_KERNEL); 549static int __devinit leo_init_one(struct of_device *op)
545 if (!all) { 550{
546 printk(KERN_ERR "leo: Cannot allocate memory.\n"); 551 struct device_node *dp = op->node;
547 return; 552 struct all_info *all;
548 } 553 int linebytes, err;
549 memset(all, 0, sizeof(*all));
550 554
551 INIT_LIST_HEAD(&all->list); 555 all = kzalloc(sizeof(*all), GFP_KERNEL);
556 if (!all)
557 return -ENOMEM;
552 558
553 spin_lock_init(&all->par.lock); 559 spin_lock_init(&all->par.lock);
554 all->par.sdev = sdev;
555 560
556 all->par.physbase = sdev->reg_addrs[0].phys_addr; 561 all->par.physbase = op->resource[0].start;
562 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
557 563
558 sbusfb_fill_var(&all->info.var, sdev->prom_node, 32); 564 sbusfb_fill_var(&all->info.var, dp->node, 32);
559 leo_fixup_var_rgb(&all->info.var); 565 leo_fixup_var_rgb(&all->info.var);
560 566
561 linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 567 linebytes = of_getintprop_default(dp, "linebytes",
562 all->info.var.xres); 568 all->info.var.xres);
563 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 569 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
564 570
565#ifdef CONFIG_SPARC32
566 all->info.screen_base = (char __iomem *)
567 prom_getintdefault(sdev->prom_node, "address", 0);
568#endif
569 if (!all->info.screen_base)
570 all->info.screen_base =
571 sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0,
572 0x800000, "leo ram");
573
574 all->par.lc_ss0_usr = 571 all->par.lc_ss0_usr =
575 sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR, 572 of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR,
576 0x1000, "leolc ss0usr"); 573 0x1000, "leolc ss0usr");
577 all->par.ld_ss0 = 574 all->par.ld_ss0 =
578 sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0, 575 of_ioremap(&op->resource[0], LEO_OFF_LD_SS0,
579 0x1000, "leold ss0"); 576 0x1000, "leold ss0");
580 all->par.ld_ss1 = 577 all->par.ld_ss1 =
581 sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1, 578 of_ioremap(&op->resource[0], LEO_OFF_LD_SS1,
582 0x1000, "leold ss1"); 579 0x1000, "leold ss1");
583 all->par.lx_krn = 580 all->par.lx_krn =
584 sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN, 581 of_ioremap(&op->resource[0], LEO_OFF_LX_KRN,
585 0x1000, "leolx krn"); 582 0x1000, "leolx krn");
586 all->par.cursor = 583 all->par.cursor =
587 sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR, 584 of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR,
588 sizeof(struct leo_cursor), "leolx cursor"); 585 sizeof(struct leo_cursor), "leolx cursor");
586 all->info.screen_base =
587 of_ioremap(&op->resource[0], LEO_OFF_SS0,
588 0x800000, "leo ram");
589 if (!all->par.lc_ss0_usr ||
590 !all->par.ld_ss0 ||
591 !all->par.ld_ss1 ||
592 !all->par.lx_krn ||
593 !all->par.cursor ||
594 !all->info.screen_base) {
595 leo_unmap_regs(all);
596 kfree(all);
597 return -ENOMEM;
598 }
589 599
590 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 600 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
591 all->info.fbops = &leo_ops; 601 all->info.fbops = &leo_ops;
@@ -597,69 +607,85 @@ static void leo_init_one(struct sbus_dev *sdev)
597 leo_blank(0, &all->info); 607 leo_blank(0, &all->info);
598 608
599 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 609 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
600 printk(KERN_ERR "leo: Could not allocate color map.\n"); 610 leo_unmap_regs(all);
601 kfree(all); 611 kfree(all);
602 return; 612 return -ENOMEM;;
603 } 613 }
604 614
605 leo_init_fix(&all->info); 615 leo_init_fix(&all->info, dp);
606 616
607 if (register_framebuffer(&all->info) < 0) { 617 err = register_framebuffer(&all->info);
608 printk(KERN_ERR "leo: Could not register framebuffer.\n"); 618 if (err < 0) {
609 fb_dealloc_cmap(&all->info.cmap); 619 fb_dealloc_cmap(&all->info.cmap);
620 leo_unmap_regs(all);
610 kfree(all); 621 kfree(all);
611 return; 622 return err;
612 } 623 }
613 624
614 list_add(&all->list, &leo_list); 625 dev_set_drvdata(&op->dev, all);
626
627 printk("%s: leo at %lx:%lx\n",
628 dp->full_name,
629 all->par.which_io, all->par.physbase);
615 630
616 printk("leo: %s at %lx:%lx\n", 631 return 0;
617 sdev->prom_name,
618 (long) sdev->reg_addrs[0].which_io,
619 (long) sdev->reg_addrs[0].phys_addr);
620} 632}
621 633
622int __init leo_init(void) 634static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match)
623{ 635{
624 struct sbus_bus *sbus; 636 struct of_device *op = to_of_device(&dev->dev);
625 struct sbus_dev *sdev;
626 637
627 if (fb_get_options("leofb", NULL)) 638 return leo_init_one(op);
628 return -ENODEV; 639}
629 640
630 for_all_sbusdev(sdev, sbus) { 641static int __devexit leo_remove(struct of_device *dev)
631 if (!strcmp(sdev->prom_name, "leo")) 642{
632 leo_init_one(sdev); 643 struct all_info *all = dev_get_drvdata(&dev->dev);
633 } 644
645 unregister_framebuffer(&all->info);
646 fb_dealloc_cmap(&all->info.cmap);
647
648 leo_unmap_regs(all);
649
650 kfree(all);
651
652 dev_set_drvdata(&dev->dev, NULL);
634 653
635 return 0; 654 return 0;
636} 655}
637 656
638void __exit leo_exit(void) 657static struct of_device_id leo_match[] = {
639{ 658 {
640 struct list_head *pos, *tmp; 659 .name = "leo",
660 },
661 {},
662};
663MODULE_DEVICE_TABLE(of, leo_match);
664
665static struct of_platform_driver leo_driver = {
666 .name = "leo",
667 .match_table = leo_match,
668 .probe = leo_probe,
669 .remove = __devexit_p(leo_remove),
670};
641 671
642 list_for_each_safe(pos, tmp, &leo_list) { 672static int __init leo_init(void)
643 struct all_info *all = list_entry(pos, typeof(*all), list); 673{
674 if (fb_get_options("leofb", NULL))
675 return -ENODEV;
644 676
645 unregister_framebuffer(&all->info); 677 return of_register_driver(&leo_driver, &of_bus_type);
646 fb_dealloc_cmap(&all->info.cmap);
647 kfree(all);
648 }
649} 678}
650 679
651int __init 680static void __exit leo_exit(void)
652leo_setup(char *arg)
653{ 681{
654 /* No cmdline options yet... */ 682 of_unregister_driver(&leo_driver);
655 return 0;
656} 683}
657 684
658module_init(leo_init); 685module_init(leo_init);
659#ifdef MODULE
660module_exit(leo_exit); 686module_exit(leo_exit);
661#endif
662 687
663MODULE_DESCRIPTION("framebuffer driver for LEO chipsets"); 688MODULE_DESCRIPTION("framebuffer driver for LEO chipsets");
664MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 689MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
690MODULE_VERSION("2.0");
665MODULE_LICENSE("GPL"); 691MODULE_LICENSE("GPL");
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 788fa812c871..80c03618eb53 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -9,7 +9,6 @@
9 * Copyright (C) 2003 Geert Uytterhoeven <geert@linux-m68k.org> 9 * Copyright (C) 2003 Geert Uytterhoeven <geert@linux-m68k.org>
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/linux_logo.h> 12#include <linux/linux_logo.h>
14#include <linux/stddef.h> 13#include <linux/stddef.h>
15#include <linux/module.h> 14#include <linux/module.h>
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index e6cbd9de944a..80a043807161 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -24,7 +24,6 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/mm.h> 26#include <linux/mm.h>
27#include <linux/tty.h>
28#include <linux/slab.h> 27#include <linux/slab.h>
29#include <linux/delay.h> 28#include <linux/delay.h>
30#include <linux/nubus.h> 29#include <linux/nubus.h>
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index c0385c6f7db5..ab2149531a04 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -15,7 +15,6 @@
15 * more details. 15 * more details.
16 */ 16 */
17 17
18#include <linux/config.h>
19#include <linux/errno.h> 18#include <linux/errno.h>
20#include <linux/fb.h> 19#include <linux/fb.h>
21#include <linux/string.h> 20#include <linux/string.h>
@@ -327,7 +326,6 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
327 } 326 }
328 return -EINVAL; 327 return -EINVAL;
329} 328}
330EXPORT_SYMBOL(mac_var_to_vmode);
331 329
332/** 330/**
333 * mac_map_monitor_sense - Convert monitor sense to vmode 331 * mac_map_monitor_sense - Convert monitor sense to vmode
@@ -371,8 +369,9 @@ EXPORT_SYMBOL(mac_map_monitor_sense);
371 * 369 *
372 */ 370 */
373 371
374int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info, 372int __devinit mac_find_mode(struct fb_var_screeninfo *var,
375 const char *mode_option, unsigned int default_bpp) 373 struct fb_info *info, const char *mode_option,
374 unsigned int default_bpp)
376{ 375{
377 const struct fb_videomode *db = NULL; 376 const struct fb_videomode *db = NULL;
378 unsigned int dbsize = 0; 377 unsigned int dbsize = 0;
diff --git a/drivers/video/macmodes.h b/drivers/video/macmodes.h
index 232f5a09a499..babeb81f467d 100644
--- a/drivers/video/macmodes.h
+++ b/drivers/video/macmodes.h
@@ -55,9 +55,10 @@ extern int mac_vmode_to_var(int vmode, int cmode,
55extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, 55extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
56 int *cmode); 56 int *cmode);
57extern int mac_map_monitor_sense(int sense); 57extern int mac_map_monitor_sense(int sense);
58extern int __init mac_find_mode(struct fb_var_screeninfo *var, 58extern int __devinit mac_find_mode(struct fb_var_screeninfo *var,
59 struct fb_info *info, const char *mode_option, 59 struct fb_info *info,
60 unsigned int default_bpp); 60 const char *mode_option,
61 unsigned int default_bpp);
61 62
62 63
63 /* 64 /*
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c
index 440272ad10e7..7c76e079ca7d 100644
--- a/drivers/video/matrox/g450_pll.c
+++ b/drivers/video/matrox/g450_pll.c
@@ -331,7 +331,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
331 tmp |= M1064_XPIXCLKCTRL_PLL_UP; 331 tmp |= M1064_XPIXCLKCTRL_PLL_UP;
332 } 332 }
333 matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); 333 matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp);
334#ifdef __powerpc__
335 /* This is necessary to avoid jitter on PowerPC
336 * (OpenFirmware) systems, but apparently
337 * introduces jitter, at least on a x86-64
338 * using DVI.
339 * A simple workaround is disable for non-PPC.
340 */
334 matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0); 341 matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0);
342#endif /* __powerpc__ */
335 matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl); 343 matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl);
336 344
337 matroxfb_DAC_unlock_irqrestore(flags); 345 matroxfb_DAC_unlock_irqrestore(flags);
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index 57abbae5520f..795c1a99a680 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -95,12 +95,12 @@ static struct i2c_adapter matrox_i2c_adapter_template =
95 95
96static struct i2c_algo_bit_data matrox_i2c_algo_template = 96static struct i2c_algo_bit_data matrox_i2c_algo_template =
97{ 97{
98 NULL, 98 .setsda = matroxfb_gpio_setsda,
99 matroxfb_gpio_setsda, 99 .setscl = matroxfb_gpio_setscl,
100 matroxfb_gpio_setscl, 100 .getsda = matroxfb_gpio_getsda,
101 matroxfb_gpio_getsda, 101 .getscl = matroxfb_gpio_getscl,
102 matroxfb_gpio_getscl, 102 .udelay = 10,
103 10, 10, 100, 103 .timeout = 100,
104}; 104};
105 105
106static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, 106static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
index a456e67a5b00..c4b570b4a4df 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.c
+++ b/drivers/video/matrox/matroxfb_DAC1064.c
@@ -12,7 +12,6 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/config.h>
16 15
17#include "matroxfb_DAC1064.h" 16#include "matroxfb_DAC1064.h"
18#include "matroxfb_misc.h" 17#include "matroxfb_misc.h"
diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h
index 56513a5d220b..df39c3193735 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.h
+++ b/drivers/video/matrox/matroxfb_DAC1064.h
@@ -1,7 +1,6 @@
1#ifndef __MATROXFB_DAC1064_H__ 1#ifndef __MATROXFB_DAC1064_H__
2#define __MATROXFB_DAC1064_H__ 2#define __MATROXFB_DAC1064_H__
3 3
4#include <linux/config.h>
5 4
6#include "matroxfb_base.h" 5#include "matroxfb_base.h"
7 6
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c
index 23ebad0a12d8..a5690a5f29d5 100644
--- a/drivers/video/matrox/matroxfb_Ti3026.c
+++ b/drivers/video/matrox/matroxfb_Ti3026.c
@@ -78,7 +78,6 @@
78 * 78 *
79 */ 79 */
80 80
81#include <linux/config.h>
82 81
83#include "matroxfb_Ti3026.h" 82#include "matroxfb_Ti3026.h"
84#include "matroxfb_misc.h" 83#include "matroxfb_misc.h"
diff --git a/drivers/video/matrox/matroxfb_Ti3026.h b/drivers/video/matrox/matroxfb_Ti3026.h
index 536e5f69de9f..27872aaa0a17 100644
--- a/drivers/video/matrox/matroxfb_Ti3026.h
+++ b/drivers/video/matrox/matroxfb_Ti3026.h
@@ -1,7 +1,6 @@
1#ifndef __MATROXFB_TI3026_H__ 1#ifndef __MATROXFB_TI3026_H__
2#define __MATROXFB_TI3026_H__ 2#define __MATROXFB_TI3026_H__
3 3
4#include <linux/config.h>
5 4
6#include "matroxfb_base.h" 5#include "matroxfb_base.h"
7 6
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 23c1827b2d0b..4a57dabb77d4 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -99,9 +99,10 @@
99 * 99 *
100 */ 100 */
101 101
102#include <linux/config.h>
103#include <linux/version.h> 102#include <linux/version.h>
104 103
104#define __OLD_VIDIOC_
105
105#include "matroxfb_base.h" 106#include "matroxfb_base.h"
106#include "matroxfb_misc.h" 107#include "matroxfb_misc.h"
107#include "matroxfb_accel.h" 108#include "matroxfb_accel.h"
@@ -158,9 +159,9 @@ static void update_crtc2(WPMINFO unsigned int pos) {
158 159
159 /* Make sure that displays are compatible */ 160 /* Make sure that displays are compatible */
160 if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) 161 if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel)
161 && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) 162 && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual)
162 && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) 163 && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length)
163 ) { 164 ) {
164 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { 165 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {
165 case 16: 166 case 16:
166 case 32: 167 case 32:
@@ -224,7 +225,7 @@ static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp)
224 225
225int matroxfb_enable_irq(WPMINFO int reenable) { 226int matroxfb_enable_irq(WPMINFO int reenable) {
226 u_int32_t bm; 227 u_int32_t bm;
227 228
228 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) 229 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)
229 bm = 0x220; 230 bm = 0x220;
230 else 231 else
@@ -232,7 +233,7 @@ int matroxfb_enable_irq(WPMINFO int reenable) {
232 233
233 if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) { 234 if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) {
234 if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq, 235 if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq,
235 SA_SHIRQ, "matroxfb", MINFO)) { 236 IRQF_SHARED, "matroxfb", MINFO)) {
236 clear_bit(0, &ACCESS_FBINFO(irq_flags)); 237 clear_bit(0, &ACCESS_FBINFO(irq_flags));
237 return -EINVAL; 238 return -EINVAL;
238 } 239 }
@@ -241,7 +242,7 @@ int matroxfb_enable_irq(WPMINFO int reenable) {
241 mga_outl(M_IEN, mga_inl(M_IEN) | bm); 242 mga_outl(M_IEN, mga_inl(M_IEN) | bm);
242 } else if (reenable) { 243 } else if (reenable) {
243 u_int32_t ien; 244 u_int32_t ien;
244 245
245 ien = mga_inl(M_IEN); 246 ien = mga_inl(M_IEN);
246 if ((ien & bm) != bm) { 247 if ((ien & bm) != bm) {
247 printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien); 248 printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien);
@@ -347,7 +348,7 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
347 mga_setr(M_EXTVGA_INDEX, 0x00, p2); 348 mga_setr(M_EXTVGA_INDEX, 0x00, p2);
348 } 349 }
349 matroxfb_DAC_unlock_irqrestore(flags); 350 matroxfb_DAC_unlock_irqrestore(flags);
350 351
351 update_crtc2(PMINFO pos); 352 update_crtc2(PMINFO pos);
352 353
353 CRITEND 354 CRITEND
@@ -390,7 +391,7 @@ static void matroxfb_remove(WPMINFO int dummy) {
390static int matroxfb_open(struct fb_info *info, int user) 391static int matroxfb_open(struct fb_info *info, int user)
391{ 392{
392 MINFO_FROM_INFO(info); 393 MINFO_FROM_INFO(info);
393 394
394 DBG_LOOP(__FUNCTION__) 395 DBG_LOOP(__FUNCTION__)
395 396
396 if (ACCESS_FBINFO(dead)) { 397 if (ACCESS_FBINFO(dead)) {
@@ -406,7 +407,7 @@ static int matroxfb_open(struct fb_info *info, int user)
406static int matroxfb_release(struct fb_info *info, int user) 407static int matroxfb_release(struct fb_info *info, int user)
407{ 408{
408 MINFO_FROM_INFO(info); 409 MINFO_FROM_INFO(info);
409 410
410 DBG_LOOP(__FUNCTION__) 411 DBG_LOOP(__FUNCTION__)
411 412
412 if (user) { 413 if (user) {
@@ -854,7 +855,7 @@ static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank)
854 vblank->flags |= FB_VBLANK_VBLANKING; 855 vblank->flags |= FB_VBLANK_VBLANKING;
855 if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { 856 if (test_bit(0, &ACCESS_FBINFO(irq_flags))) {
856 vblank->flags |= FB_VBLANK_HAVE_COUNT; 857 vblank->flags |= FB_VBLANK_HAVE_COUNT;
857 /* Only one writer, aligned int value... 858 /* Only one writer, aligned int value...
858 it should work without lock and without atomic_t */ 859 it should work without lock and without atomic_t */
859 vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; 860 vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt;
860 } 861 }
@@ -870,7 +871,7 @@ static int matroxfb_ioctl(struct fb_info *info,
870{ 871{
871 void __user *argp = (void __user *)arg; 872 void __user *argp = (void __user *)arg;
872 MINFO_FROM_INFO(info); 873 MINFO_FROM_INFO(info);
873 874
874 DBG(__FUNCTION__) 875 DBG(__FUNCTION__)
875 876
876 if (ACCESS_FBINFO(dead)) { 877 if (ACCESS_FBINFO(dead)) {
@@ -1081,7 +1082,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1081 case VIDIOC_QUERYCAP: 1082 case VIDIOC_QUERYCAP:
1082 { 1083 {
1083 struct v4l2_capability r; 1084 struct v4l2_capability r;
1084 1085
1085 memset(&r, 0, sizeof(r)); 1086 memset(&r, 0, sizeof(r));
1086 strcpy(r.driver, "matroxfb"); 1087 strcpy(r.driver, "matroxfb");
1087 strcpy(r.card, "Matrox"); 1088 strcpy(r.card, "Matrox");
@@ -1091,7 +1092,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1091 if (copy_to_user(argp, &r, sizeof(r))) 1092 if (copy_to_user(argp, &r, sizeof(r)))
1092 return -EFAULT; 1093 return -EFAULT;
1093 return 0; 1094 return 0;
1094 1095
1095 } 1096 }
1096 case VIDIOC_QUERYCTRL: 1097 case VIDIOC_QUERYCTRL:
1097 { 1098 {
@@ -1690,8 +1691,8 @@ static int initMatrox2(WPMINFO struct board* b){
1690 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); 1691 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd);
1691 mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ 1692 mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */
1692 mga_option |= MX_OPTION_BSWAP; 1693 mga_option |= MX_OPTION_BSWAP;
1693 /* disable palette snooping */ 1694 /* disable palette snooping */
1694 cmd &= ~PCI_COMMAND_VGA_PALETTE; 1695 cmd &= ~PCI_COMMAND_VGA_PALETTE;
1695 if (pci_dev_present(intel_82437)) { 1696 if (pci_dev_present(intel_82437)) {
1696 if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { 1697 if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) {
1697 printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); 1698 printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n");
@@ -1809,12 +1810,12 @@ static int initMatrox2(WPMINFO struct board* b){
1809 1810
1810 if (fv) { 1811 if (fv) {
1811 tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres 1812 tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres
1812 + vesafb_defined.lower_margin + vesafb_defined.vsync_len); 1813 + vesafb_defined.lower_margin + vesafb_defined.vsync_len);
1813 if ((tmp < fh) || (fh == 0)) fh = tmp; 1814 if ((tmp < fh) || (fh == 0)) fh = tmp;
1814 } 1815 }
1815 if (fh) { 1816 if (fh) {
1816 tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres 1817 tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres
1817 + vesafb_defined.right_margin + vesafb_defined.hsync_len); 1818 + vesafb_defined.right_margin + vesafb_defined.hsync_len);
1818 if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp; 1819 if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
1819 } 1820 }
1820 tmp = (maxclk + 499) / 500; 1821 tmp = (maxclk + 499) / 500;
@@ -1890,14 +1891,14 @@ static int initMatrox2(WPMINFO struct board* b){
1890 1891
1891 /* there is no console on this fb... but we have to initialize hardware 1892 /* there is no console on this fb... but we have to initialize hardware
1892 * until someone tells me what is proper thing to do */ 1893 * until someone tells me what is proper thing to do */
1893 if (!ACCESS_FBINFO(initialized)) { 1894 if (!ACCESS_FBINFO(initialized)) {
1894 printk(KERN_INFO "fb%d: initializing hardware\n", 1895 printk(KERN_INFO "fb%d: initializing hardware\n",
1895 ACCESS_FBINFO(fbcon.node)); 1896 ACCESS_FBINFO(fbcon.node));
1896 /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var 1897 /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var
1897 * already before, so register_framebuffer works correctly. */ 1898 * already before, so register_framebuffer works correctly. */
1898 vesafb_defined.activate |= FB_ACTIVATE_FORCE; 1899 vesafb_defined.activate |= FB_ACTIVATE_FORCE;
1899 fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); 1900 fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined);
1900 } 1901 }
1901 1902
1902 return 0; 1903 return 0;
1903failVideoIO:; 1904failVideoIO:;
@@ -2356,7 +2357,7 @@ static int __init matroxfb_setup(char *options) {
2356 else if (!strncmp(this_opt, "dfp:", 4)) { 2357 else if (!strncmp(this_opt, "dfp:", 4)) {
2357 dfp_type = simple_strtoul(this_opt+4, NULL, 0); 2358 dfp_type = simple_strtoul(this_opt+4, NULL, 0);
2358 dfp = 1; 2359 dfp = 1;
2359 } 2360 }
2360#ifdef CONFIG_PPC_PMAC 2361#ifdef CONFIG_PPC_PMAC
2361 else if (!strncmp(this_opt, "vmode:", 6)) { 2362 else if (!strncmp(this_opt, "vmode:", 6)) {
2362 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0); 2363 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index b71737178d0d..9c25c2f7966b 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -25,13 +25,11 @@
25/* Guard accelerator accesses with spin_lock_irqsave... */ 25/* Guard accelerator accesses with spin_lock_irqsave... */
26#undef MATROXFB_USE_SPINLOCKS 26#undef MATROXFB_USE_SPINLOCKS
27 27
28#include <linux/config.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/errno.h> 30#include <linux/errno.h>
32#include <linux/string.h> 31#include <linux/string.h>
33#include <linux/mm.h> 32#include <linux/mm.h>
34#include <linux/tty.h>
35#include <linux/slab.h> 33#include <linux/slab.h>
36#include <linux/delay.h> 34#include <linux/delay.h>
37#include <linux/fb.h> 35#include <linux/fb.h>
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
index 263d801ef78f..18886b629cb1 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -84,7 +84,6 @@
84 * 84 *
85 */ 85 */
86 86
87#include <linux/config.h>
88 87
89#include "matroxfb_misc.h" 88#include "matroxfb_misc.h"
90#include <linux/interrupt.h> 89#include <linux/interrupt.h>
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
index f85421bf7cb5..38c8d38de4fd 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/maxinefb.c
@@ -29,7 +29,6 @@
29#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/tty.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
35#include <linux/init.h> 34#include <linux/init.h>
diff --git a/drivers/video/mbx/Makefile b/drivers/video/mbx/Makefile
new file mode 100644
index 000000000000..16c1165cf9c7
--- /dev/null
+++ b/drivers/video/mbx/Makefile
@@ -0,0 +1,4 @@
1# Makefile for the 2700G controller driver.
2
3obj-$(CONFIG_FB_MBX) += mbxfb.o
4obj-$(CONFIG_FB_MBX_DEBUG) += mbxfbdebugfs.o
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
new file mode 100644
index 000000000000..84aab3ad024e
--- /dev/null
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -0,0 +1,188 @@
1#include <linux/debugfs.h>
2
3#define BIG_BUFFER_SIZE (1024)
4
5static char big_buffer[BIG_BUFFER_SIZE];
6
7struct mbxfb_debugfs_data {
8 struct dentry *dir;
9 struct dentry *sysconf;
10 struct dentry *clock;
11 struct dentry *display;
12 struct dentry *gsctl;
13};
14
15static int open_file_generic(struct inode *inode, struct file *file)
16{
17 file->private_data = inode->u.generic_ip;
18 return 0;
19}
20
21static ssize_t write_file_dummy(struct file *file, const char __user *buf,
22 size_t count, loff_t *ppos)
23{
24 return count;
25}
26
27static ssize_t sysconf_read_file(struct file *file, char __user *userbuf,
28 size_t count, loff_t *ppos)
29{
30 char * s = big_buffer;
31
32 s += sprintf(s, "SYSCFG = %08lx\n", SYSCFG);
33 s += sprintf(s, "PFBASE = %08lx\n", PFBASE);
34 s += sprintf(s, "PFCEIL = %08lx\n", PFCEIL);
35 s += sprintf(s, "POLLFLAG = %08lx\n", POLLFLAG);
36 s += sprintf(s, "SYSRST = %08lx\n", SYSRST);
37
38 return simple_read_from_buffer(userbuf, count, ppos,
39 big_buffer, s-big_buffer);
40}
41
42
43static ssize_t gsctl_read_file(struct file *file, char __user *userbuf,
44 size_t count, loff_t *ppos)
45{
46 char * s = big_buffer;
47
48 s += sprintf(s, "GSCTRL = %08lx\n", GSCTRL);
49 s += sprintf(s, "VSCTRL = %08lx\n", VSCTRL);
50 s += sprintf(s, "GBBASE = %08lx\n", GBBASE);
51 s += sprintf(s, "VBBASE = %08lx\n", VBBASE);
52 s += sprintf(s, "GDRCTRL = %08lx\n", GDRCTRL);
53 s += sprintf(s, "VCMSK = %08lx\n", VCMSK);
54 s += sprintf(s, "GSCADR = %08lx\n", GSCADR);
55 s += sprintf(s, "VSCADR = %08lx\n", VSCADR);
56 s += sprintf(s, "VUBASE = %08lx\n", VUBASE);
57 s += sprintf(s, "VVBASE = %08lx\n", VVBASE);
58 s += sprintf(s, "GSADR = %08lx\n", GSADR);
59 s += sprintf(s, "VSADR = %08lx\n", VSADR);
60 s += sprintf(s, "HCCTRL = %08lx\n", HCCTRL);
61 s += sprintf(s, "HCSIZE = %08lx\n", HCSIZE);
62 s += sprintf(s, "HCPOS = %08lx\n", HCPOS);
63 s += sprintf(s, "HCBADR = %08lx\n", HCBADR);
64 s += sprintf(s, "HCCKMSK = %08lx\n", HCCKMSK);
65 s += sprintf(s, "GPLUT = %08lx\n", GPLUT);
66
67 return simple_read_from_buffer(userbuf, count, ppos,
68 big_buffer, s-big_buffer);
69}
70
71static ssize_t display_read_file(struct file *file, char __user *userbuf,
72 size_t count, loff_t *ppos)
73{
74 char * s = big_buffer;
75
76 s += sprintf(s, "DSCTRL = %08lx\n", DSCTRL);
77 s += sprintf(s, "DHT01 = %08lx\n", DHT01);
78 s += sprintf(s, "DHT02 = %08lx\n", DHT02);
79 s += sprintf(s, "DHT03 = %08lx\n", DHT03);
80 s += sprintf(s, "DVT01 = %08lx\n", DVT01);
81 s += sprintf(s, "DVT02 = %08lx\n", DVT02);
82 s += sprintf(s, "DVT03 = %08lx\n", DVT03);
83 s += sprintf(s, "DBCOL = %08lx\n", DBCOL);
84 s += sprintf(s, "BGCOLOR = %08lx\n", BGCOLOR);
85 s += sprintf(s, "DINTRS = %08lx\n", DINTRS);
86 s += sprintf(s, "DINTRE = %08lx\n", DINTRE);
87 s += sprintf(s, "DINTRCNT = %08lx\n", DINTRCNT);
88 s += sprintf(s, "DSIG = %08lx\n", DSIG);
89 s += sprintf(s, "DMCTRL = %08lx\n", DMCTRL);
90 s += sprintf(s, "CLIPCTRL = %08lx\n", CLIPCTRL);
91 s += sprintf(s, "SPOCTRL = %08lx\n", SPOCTRL);
92 s += sprintf(s, "SVCTRL = %08lx\n", SVCTRL);
93 s += sprintf(s, "DLSTS = %08lx\n", DLSTS);
94 s += sprintf(s, "DLLCTRL = %08lx\n", DLLCTRL);
95 s += sprintf(s, "DVLNUM = %08lx\n", DVLNUM);
96 s += sprintf(s, "DUCTRL = %08lx\n", DUCTRL);
97 s += sprintf(s, "DVECTRL = %08lx\n", DVECTRL);
98 s += sprintf(s, "DHDET = %08lx\n", DHDET);
99 s += sprintf(s, "DVDET = %08lx\n", DVDET);
100 s += sprintf(s, "DODMSK = %08lx\n", DODMSK);
101 s += sprintf(s, "CSC01 = %08lx\n", CSC01);
102 s += sprintf(s, "CSC02 = %08lx\n", CSC02);
103 s += sprintf(s, "CSC03 = %08lx\n", CSC03);
104 s += sprintf(s, "CSC04 = %08lx\n", CSC04);
105 s += sprintf(s, "CSC05 = %08lx\n", CSC05);
106
107 return simple_read_from_buffer(userbuf, count, ppos,
108 big_buffer, s-big_buffer);
109}
110
111static ssize_t clock_read_file(struct file *file, char __user *userbuf,
112 size_t count, loff_t *ppos)
113{
114 char * s = big_buffer;
115
116 s += sprintf(s, "SYSCLKSRC = %08lx\n", SYSCLKSRC);
117 s += sprintf(s, "PIXCLKSRC = %08lx\n", PIXCLKSRC);
118 s += sprintf(s, "CLKSLEEP = %08lx\n", CLKSLEEP);
119 s += sprintf(s, "COREPLL = %08lx\n", COREPLL);
120 s += sprintf(s, "DISPPLL = %08lx\n", DISPPLL);
121 s += sprintf(s, "PLLSTAT = %08lx\n", PLLSTAT);
122 s += sprintf(s, "VOVRCLK = %08lx\n", VOVRCLK);
123 s += sprintf(s, "PIXCLK = %08lx\n", PIXCLK);
124 s += sprintf(s, "MEMCLK = %08lx\n", MEMCLK);
125 s += sprintf(s, "M24CLK = %08lx\n", M24CLK);
126 s += sprintf(s, "MBXCLK = %08lx\n", MBXCLK);
127 s += sprintf(s, "SDCLK = %08lx\n", SDCLK);
128 s += sprintf(s, "PIXCLKDIV = %08lx\n", PIXCLKDIV);
129
130 return simple_read_from_buffer(userbuf, count, ppos,
131 big_buffer, s-big_buffer);
132}
133
134static struct file_operations sysconf_fops = {
135 .read = sysconf_read_file,
136 .write = write_file_dummy,
137 .open = open_file_generic,
138};
139
140static struct file_operations clock_fops = {
141 .read = clock_read_file,
142 .write = write_file_dummy,
143 .open = open_file_generic,
144};
145
146static struct file_operations display_fops = {
147 .read = display_read_file,
148 .write = write_file_dummy,
149 .open = open_file_generic,
150};
151
152static struct file_operations gsctl_fops = {
153 .read = gsctl_read_file,
154 .write = write_file_dummy,
155 .open = open_file_generic,
156};
157
158
159static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
160{
161 struct mbxfb_info *mfbi = fbi->par;
162 struct mbxfb_debugfs_data *dbg;
163
164 dbg = kzalloc(sizeof(struct mbxfb_debugfs_data), GFP_KERNEL);
165 mfbi->debugfs_data = dbg;
166
167 dbg->dir = debugfs_create_dir("mbxfb", NULL);
168 dbg->sysconf = debugfs_create_file("sysconf", 0444, dbg->dir,
169 fbi, &sysconf_fops);
170 dbg->clock = debugfs_create_file("clock", 0444, dbg->dir,
171 fbi, &clock_fops);
172 dbg->display = debugfs_create_file("display", 0444, dbg->dir,
173 fbi, &display_fops);
174 dbg->gsctl = debugfs_create_file("gsctl", 0444, dbg->dir,
175 fbi, &gsctl_fops);
176}
177
178static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
179{
180 struct mbxfb_info *mfbi = fbi->par;
181 struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data;
182
183 debugfs_remove(dbg->gsctl);
184 debugfs_remove(dbg->display);
185 debugfs_remove(dbg->clock);
186 debugfs_remove(dbg->sysconf);
187 debugfs_remove(dbg->dir);
188}
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
new file mode 100644
index 000000000000..6849ab75d403
--- /dev/null
+++ b/drivers/video/mbx/mbxfb.c
@@ -0,0 +1,683 @@
1/*
2 * linux/drivers/video/mbx/mbxfb.c
3 *
4 * Copyright (C) 2006 Compulab, Ltd.
5 * Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on pxafb.c
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for
11 * more details.
12 *
13 * Intel 2700G (Marathon) Graphics Accelerator Frame Buffer Driver
14 *
15 */
16
17#include <linux/delay.h>
18#include <linux/fb.h>
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22
23#include <asm/io.h>
24
25#include <video/mbxfb.h>
26
27#include "regs.h"
28#include "reg_bits.h"
29
30static unsigned long virt_base_2700;
31
32#define MIN_XRES 16
33#define MIN_YRES 16
34#define MAX_XRES 2048
35#define MAX_YRES 2048
36
37#define MAX_PALETTES 16
38
39/* FIXME: take care of different chip revisions with different sizes
40 of ODFB */
41#define MEMORY_OFFSET 0x60000
42
43struct mbxfb_info {
44 struct device *dev;
45
46 struct resource *fb_res;
47 struct resource *fb_req;
48
49 struct resource *reg_res;
50 struct resource *reg_req;
51
52 void __iomem *fb_virt_addr;
53 unsigned long fb_phys_addr;
54
55 void __iomem *reg_virt_addr;
56 unsigned long reg_phys_addr;
57
58 int (*platform_probe) (struct fb_info * fb);
59 int (*platform_remove) (struct fb_info * fb);
60
61 u32 pseudo_palette[MAX_PALETTES];
62#ifdef CONFIG_FB_MBX_DEBUG
63 void *debugfs_data;
64#endif
65
66};
67
68static struct fb_var_screeninfo mbxfb_default __devinitdata = {
69 .xres = 640,
70 .yres = 480,
71 .xres_virtual = 640,
72 .yres_virtual = 480,
73 .bits_per_pixel = 16,
74 .red = {11, 5, 0},
75 .green = {5, 6, 0},
76 .blue = {0, 5, 0},
77 .activate = FB_ACTIVATE_TEST,
78 .height = -1,
79 .width = -1,
80 .pixclock = 40000,
81 .left_margin = 48,
82 .right_margin = 16,
83 .upper_margin = 33,
84 .lower_margin = 10,
85 .hsync_len = 96,
86 .vsync_len = 2,
87 .vmode = FB_VMODE_NONINTERLACED,
88 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
89};
90
91static struct fb_fix_screeninfo mbxfb_fix __devinitdata = {
92 .id = "MBX",
93 .type = FB_TYPE_PACKED_PIXELS,
94 .visual = FB_VISUAL_TRUECOLOR,
95 .xpanstep = 0,
96 .ypanstep = 0,
97 .ywrapstep = 0,
98 .accel = FB_ACCEL_NONE,
99};
100
101struct pixclock_div {
102 u8 m;
103 u8 n;
104 u8 p;
105};
106
107static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps,
108 struct pixclock_div *div)
109{
110 u8 m, n, p;
111 unsigned int err = 0;
112 unsigned int min_err = ~0x0;
113 unsigned int clk;
114 unsigned int best_clk = 0;
115 unsigned int ref_clk = 13000; /* FIXME: take from platform data */
116 unsigned int pixclock;
117
118 /* convert pixclock to KHz */
119 pixclock = PICOS2KHZ(pixclock_ps);
120
121 for (m = 1; m < 64; m++) {
122 for (n = 1; n < 8; n++) {
123 for (p = 0; p < 8; p++) {
124 clk = (ref_clk * m) / (n * (1 << p));
125 err = (clk > pixclock) ? (clk - pixclock) :
126 (pixclock - clk);
127 if (err < min_err) {
128 min_err = err;
129 best_clk = clk;
130 div->m = m;
131 div->n = n;
132 div->p = p;
133 }
134 }
135 }
136 }
137 return KHZ2PICOS(best_clk);
138}
139
140static int mbxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
141 u_int trans, struct fb_info *info)
142{
143 u32 val, ret = 1;
144
145 if (regno < MAX_PALETTES) {
146 u32 *pal = info->pseudo_palette;
147
148 val = (red & 0xf800) | ((green & 0xfc00) >> 5) |
149 ((blue & 0xf800) >> 11);
150 pal[regno] = val;
151 ret = 0;
152 }
153
154 return ret;
155}
156
157static int mbxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
158{
159 struct pixclock_div div;
160
161 var->pixclock = mbxfb_get_pixclock(var->pixclock, &div);
162
163 if (var->xres < MIN_XRES)
164 var->xres = MIN_XRES;
165 if (var->yres < MIN_YRES)
166 var->yres = MIN_YRES;
167 if (var->xres > MAX_XRES)
168 return -EINVAL;
169 if (var->yres > MAX_YRES)
170 return -EINVAL;
171 var->xres_virtual = max(var->xres_virtual, var->xres);
172 var->yres_virtual = max(var->yres_virtual, var->yres);
173
174 switch (var->bits_per_pixel) {
175 /* 8 bits-per-pixel is not supported yet */
176 case 8:
177 return -EINVAL;
178 case 16:
179 var->green.length = (var->green.length == 5) ? 5 : 6;
180 var->red.length = 5;
181 var->blue.length = 5;
182 var->transp.length = 6 - var->green.length;
183 var->blue.offset = 0;
184 var->green.offset = 5;
185 var->red.offset = 5 + var->green.length;
186 var->transp.offset = (5 + var->red.offset) & 15;
187 break;
188 case 24: /* RGB 888 */
189 case 32: /* RGBA 8888 */
190 var->red.offset = 16;
191 var->red.length = 8;
192 var->green.offset = 8;
193 var->green.length = 8;
194 var->blue.offset = 0;
195 var->blue.length = 8;
196 var->transp.length = var->bits_per_pixel - 24;
197 var->transp.offset = (var->transp.length) ? 24 : 0;
198 break;
199 }
200 var->red.msb_right = 0;
201 var->green.msb_right = 0;
202 var->blue.msb_right = 0;
203 var->transp.msb_right = 0;
204
205 return 0;
206}
207
208static int mbxfb_set_par(struct fb_info *info)
209{
210 struct fb_var_screeninfo *var = &info->var;
211 struct pixclock_div div;
212 ushort hbps, ht, hfps, has;
213 ushort vbps, vt, vfps, vas;
214 u32 gsctrl = readl(GSCTRL);
215 u32 gsadr = readl(GSADR);
216
217 info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
218
219 /* setup color mode */
220 gsctrl &= ~(FMsk(GSCTRL_GPIXFMT));
221 /* FIXME: add *WORKING* support for 8-bits per color */
222 if (info->var.bits_per_pixel == 8) {
223 return -EINVAL;
224 } else {
225 fb_dealloc_cmap(&info->cmap);
226 gsctrl &= ~GSCTRL_LUT_EN;
227
228 info->fix.visual = FB_VISUAL_TRUECOLOR;
229 switch (info->var.bits_per_pixel) {
230 case 16:
231 if (info->var.green.length == 5)
232 gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
233 else
234 gsctrl |= GSCTRL_GPIXFMT_RGB565;
235 break;
236 case 24:
237 gsctrl |= GSCTRL_GPIXFMT_RGB888;
238 break;
239 case 32:
240 gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
241 break;
242 }
243 }
244
245 /* setup resolution */
246 gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
247 gsctrl |= Gsctrl_Width(info->var.xres - 1) |
248 Gsctrl_Height(info->var.yres - 1);
249 writel(gsctrl, GSCTRL);
250 udelay(1000);
251
252 gsadr &= ~(FMsk(GSADR_SRCSTRIDE));
253 gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel /
254 (8 * 16) - 1);
255 writel(gsadr, GSADR);
256 udelay(1000);
257
258 /* setup timings */
259 var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);
260
261 writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
262 Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL);
263
264 hbps = var->hsync_len;
265 has = hbps + var->left_margin;
266 hfps = has + var->xres;
267 ht = hfps + var->right_margin;
268
269 vbps = var->vsync_len;
270 vas = vbps + var->upper_margin;
271 vfps = vas + var->yres;
272 vt = vfps + var->lower_margin;
273
274 writel((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
275 writel((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
276 writel((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
277 writel((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);
278
279 writel((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
280 writel((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
281 writel((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
282 writel((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
283 writel((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);
284
285 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
286
287 return 0;
288}
289
290static int mbxfb_blank(int blank, struct fb_info *info)
291{
292 switch (blank) {
293 case FB_BLANK_POWERDOWN:
294 case FB_BLANK_VSYNC_SUSPEND:
295 case FB_BLANK_HSYNC_SUSPEND:
296 case FB_BLANK_NORMAL:
297 writel((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
298 udelay(1000);
299 writel((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
300 udelay(1000);
301 writel((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
302 udelay(1000);
303 break;
304 case FB_BLANK_UNBLANK:
305 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
306 udelay(1000);
307 writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
308 udelay(1000);
309 break;
310 }
311 return 0;
312}
313
314static struct fb_ops mbxfb_ops = {
315 .owner = THIS_MODULE,
316 .fb_check_var = mbxfb_check_var,
317 .fb_set_par = mbxfb_set_par,
318 .fb_setcolreg = mbxfb_setcolreg,
319 .fb_fillrect = cfb_fillrect,
320 .fb_copyarea = cfb_copyarea,
321 .fb_imageblit = cfb_imageblit,
322 .fb_blank = mbxfb_blank,
323};
324
325/*
326 Enable external SDRAM controller. Assume that all clocks are active
327 by now.
328*/
329static void __devinit setup_memc(struct fb_info *fbi)
330{
331 struct mbxfb_info *mfbi = fbi->par;
332 unsigned long tmp;
333 int i;
334
335 /* FIXME: use platfrom specific parameters */
336 /* setup SDRAM controller */
337 writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
338 LMCFG_LMA_TS),
339 LMCFG);
340 udelay(1000);
341
342 writel(LMPWR_MC_PWR_ACT, LMPWR);
343 udelay(1000);
344
345 /* setup SDRAM timings */
346 writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
347 Lmtim_Trc(9) | Lmtim_Tdpl(2)),
348 LMTIM);
349 udelay(1000);
350 /* setup SDRAM refresh rate */
351 writel(0xc2b, LMREFRESH);
352 udelay(1000);
353 /* setup SDRAM type parameters */
354 writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
355 LMTYPE_COLSZ_8),
356 LMTYPE);
357 udelay(1000);
358 /* enable memory controller */
359 writel(LMPWR_MC_PWR_ACT, LMPWR);
360 udelay(1000);
361
362 /* perform dummy reads */
363 for ( i = 0; i < 16; i++ ) {
364 tmp = readl(fbi->screen_base);
365 }
366}
367
368static void enable_clocks(struct fb_info *fbi)
369{
370 /* enable clocks */
371 writel(SYSCLKSRC_PLL_2, SYSCLKSRC);
372 udelay(1000);
373 writel(PIXCLKSRC_PLL_1, PIXCLKSRC);
374 udelay(1000);
375 writel(0x00000000, CLKSLEEP);
376 udelay(1000);
377 writel((Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) |
378 CORE_PLL_EN),
379 COREPLL);
380 udelay(1000);
381 writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
382 DISP_PLL_EN),
383 DISPPLL);
384
385 writel(0x00000000, VOVRCLK);
386 udelay(1000);
387 writel(PIXCLK_EN, PIXCLK);
388 udelay(1000);
389 writel(MEMCLK_EN, MEMCLK);
390 udelay(1000);
391 writel(0x00000006, M24CLK);
392 udelay(1000);
393 writel(0x00000006, MBXCLK);
394 udelay(1000);
395 writel(SDCLK_EN, SDCLK);
396 udelay(1000);
397 writel(0x00000001, PIXCLKDIV);
398 udelay(1000);
399}
400
401static void __devinit setup_graphics(struct fb_info *fbi)
402{
403 unsigned long gsctrl;
404
405 gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) |
406 Gsctrl_Height(fbi->var.yres - 1);
407 switch (fbi->var.bits_per_pixel) {
408 case 16:
409 if (fbi->var.green.length == 5)
410 gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
411 else
412 gsctrl |= GSCTRL_GPIXFMT_RGB565;
413 break;
414 case 24:
415 gsctrl |= GSCTRL_GPIXFMT_RGB888;
416 break;
417 case 32:
418 gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
419 break;
420 }
421
422 writel(gsctrl, GSCTRL);
423 udelay(1000);
424 writel(0x00000000, GBBASE);
425 udelay(1000);
426 writel(0x00ffffff, GDRCTRL);
427 udelay(1000);
428 writel((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
429 udelay(1000);
430 writel(0x00000000, GPLUT);
431 udelay(1000);
432}
433
434static void __devinit setup_display(struct fb_info *fbi)
435{
436 unsigned long dsctrl = 0;
437
438 dsctrl = DSCTRL_BLNK_POL;
439 if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
440 dsctrl |= DSCTRL_HS_POL;
441 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
442 dsctrl |= DSCTRL_VS_POL;
443 writel(dsctrl, DSCTRL);
444 udelay(1000);
445 writel(0xd0303010, DMCTRL);
446 udelay(1000);
447 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
448}
449
450static void __devinit enable_controller(struct fb_info *fbi)
451{
452 writel(SYSRST_RST, SYSRST);
453 udelay(1000);
454
455
456 enable_clocks(fbi);
457 setup_memc(fbi);
458 setup_graphics(fbi);
459 setup_display(fbi);
460}
461
462#ifdef CONFIG_PM
463/*
464 * Power management hooks. Note that we won't be called from IRQ context,
465 * unlike the blank functions above, so we may sleep.
466 */
467static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
468{
469 /* make frame buffer memory enter self-refresh mode */
470 writel(LMPWR_MC_PWR_SRM, LMPWR);
471 while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)
472 ; /* empty statement */
473
474 /* reset the device, since it's initial state is 'mostly sleeping' */
475 writel(SYSRST_RST, SYSRST);
476 return 0;
477}
478
479static int mbxfb_resume(struct platform_device *dev)
480{
481 struct fb_info *fbi = platform_get_drvdata(dev);
482
483 enable_clocks(fbi);
484/* setup_graphics(fbi); */
485/* setup_display(fbi); */
486
487 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
488 return 0;
489}
490#else
491#define mbxfb_suspend NULL
492#define mbxfb_resume NULL
493#endif
494
495/* debugfs entries */
496#ifndef CONFIG_FB_MBX_DEBUG
497#define mbxfb_debugfs_init(x) do {} while(0)
498#define mbxfb_debugfs_remove(x) do {} while(0)
499#endif
500
501#define res_size(_r) (((_r)->end - (_r)->start) + 1)
502
503static int __devinit mbxfb_probe(struct platform_device *dev)
504{
505 int ret;
506 struct fb_info *fbi;
507 struct mbxfb_info *mfbi;
508 struct mbxfb_platform_data *pdata;
509
510 dev_dbg(dev, "mbxfb_probe\n");
511
512 fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
513 if (fbi == NULL) {
514 dev_err(&dev->dev, "framebuffer_alloc failed\n");
515 return -ENOMEM;
516 }
517
518 mfbi = fbi->par;
519 fbi->pseudo_palette = mfbi->pseudo_palette;
520 pdata = dev->dev.platform_data;
521 if (pdata->probe)
522 mfbi->platform_probe = pdata->probe;
523 if (pdata->remove)
524 mfbi->platform_remove = pdata->remove;
525
526 mfbi->fb_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
527 mfbi->reg_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
528
529 if (!mfbi->fb_res || !mfbi->reg_res) {
530 dev_err(&dev->dev, "no resources found\n");
531 ret = -ENODEV;
532 goto err1;
533 }
534
535 mfbi->fb_req = request_mem_region(mfbi->fb_res->start,
536 res_size(mfbi->fb_res), dev->name);
537 if (mfbi->fb_req == NULL) {
538 dev_err(&dev->dev, "failed to claim framebuffer memory\n");
539 ret = -EINVAL;
540 goto err1;
541 }
542 mfbi->fb_phys_addr = mfbi->fb_res->start;
543
544 mfbi->reg_req = request_mem_region(mfbi->reg_res->start,
545 res_size(mfbi->reg_res), dev->name);
546 if (mfbi->reg_req == NULL) {
547 dev_err(&dev->dev, "failed to claim Marathon registers\n");
548 ret = -EINVAL;
549 goto err2;
550 }
551 mfbi->reg_phys_addr = mfbi->reg_res->start;
552
553 mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
554 res_size(mfbi->reg_req));
555 if (!mfbi->reg_virt_addr) {
556 dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
557 ret = -EINVAL;
558 goto err3;
559 }
560 virt_base_2700 = (unsigned long)mfbi->reg_virt_addr;
561
562 mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
563 res_size(mfbi->fb_req));
564 if (!mfbi->reg_virt_addr) {
565 dev_err(&dev->dev, "failed to ioremap frame buffer\n");
566 ret = -EINVAL;
567 goto err4;
568 }
569
570 /* FIXME: get from platform */
571 fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
572 fbi->screen_size = 8 * 1024 * 1024; /* 8 Megs */
573 fbi->fbops = &mbxfb_ops;
574
575 fbi->var = mbxfb_default;
576 fbi->fix = mbxfb_fix;
577 fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
578 fbi->fix.smem_len = 8 * 1024 * 1024;
579 fbi->fix.line_length = 640 * 2;
580
581 ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
582 if (ret < 0) {
583 dev_err(&dev->dev, "fb_alloc_cmap failed\n");
584 ret = -EINVAL;
585 goto err5;
586 }
587
588 platform_set_drvdata(dev, fbi);
589
590 printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);
591
592 if (mfbi->platform_probe)
593 mfbi->platform_probe(fbi);
594
595 enable_controller(fbi);
596
597 mbxfb_debugfs_init(fbi);
598
599 ret = register_framebuffer(fbi);
600 if (ret < 0) {
601 dev_err(&dev->dev, "register_framebuffer failed\n");
602 ret = -EINVAL;
603 goto err6;
604 }
605
606 return 0;
607
608err6:
609 fb_dealloc_cmap(&fbi->cmap);
610err5:
611 iounmap(mfbi->fb_virt_addr);
612err4:
613 iounmap(mfbi->reg_virt_addr);
614err3:
615 release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));
616err2:
617 release_mem_region(mfbi->fb_res->start, res_size(mfbi->fb_res));
618err1:
619 framebuffer_release(fbi);
620
621 return ret;
622}
623
624static int __devexit mbxfb_remove(struct platform_device *dev)
625{
626 struct fb_info *fbi = platform_get_drvdata(dev);
627
628 writel(SYSRST_RST, SYSRST);
629 udelay(1000);
630
631 mbxfb_debugfs_remove(fbi);
632
633 if (fbi) {
634 struct mbxfb_info *mfbi = fbi->par;
635
636 unregister_framebuffer(fbi);
637 if (mfbi) {
638 if (mfbi->platform_remove)
639 mfbi->platform_remove(fbi);
640
641 if (mfbi->fb_virt_addr)
642 iounmap(mfbi->fb_virt_addr);
643 if (mfbi->reg_virt_addr)
644 iounmap(mfbi->reg_virt_addr);
645 if (mfbi->reg_req)
646 release_mem_region(mfbi->reg_req->start,
647 res_size(mfbi->reg_req));
648 if (mfbi->fb_req)
649 release_mem_region(mfbi->fb_req->start,
650 res_size(mfbi->fb_req));
651 }
652 framebuffer_release(fbi);
653 }
654
655 return 0;
656}
657
658static struct platform_driver mbxfb_driver = {
659 .probe = mbxfb_probe,
660 .remove = mbxfb_remove,
661 .suspend = mbxfb_suspend,
662 .resume = mbxfb_resume,
663 .driver = {
664 .name = "mbx-fb",
665 },
666};
667
668int __devinit mbxfb_init(void)
669{
670 return platform_driver_register(&mbxfb_driver);
671}
672
673static void __devexit mbxfb_exit(void)
674{
675 platform_driver_unregister(&mbxfb_driver);
676}
677
678module_init(mbxfb_init);
679module_exit(mbxfb_exit);
680
681MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");
682MODULE_AUTHOR("Mike Rapoport, Compulab");
683MODULE_LICENSE("GPL");
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
new file mode 100644
index 000000000000..c226a8e45312
--- /dev/null
+++ b/drivers/video/mbx/reg_bits.h
@@ -0,0 +1,418 @@
1#ifndef __REG_BITS_2700G_
2#define __REG_BITS_2700G_
3
4/* use defines from asm-arm/arch-pxa/bitfields.h for bit fields access */
5#define UData(Data) ((unsigned long) (Data))
6#define Fld(Size, Shft) (((Size) << 16) + (Shft))
7#define FSize(Field) ((Field) >> 16)
8#define FShft(Field) ((Field) & 0x0000FFFF)
9#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field))
10#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1)
11#define F1stBit(Field) (UData (1) << FShft (Field))
12
13#define SYSRST_RST (1 << 0)
14
15/* SYSCLKSRC - SYSCLK Source Control Register */
16#define SYSCLKSRC_SEL Fld(2,0)
17#define SYSCLKSRC_REF ((0x0) << FShft(SYSCLKSRC_SEL))
18#define SYSCLKSRC_PLL_1 ((0x1) << FShft(SYSCLKSRC_SEL))
19#define SYSCLKSRC_PLL_2 ((0x2) << FShft(SYSCLKSRC_SEL))
20
21/* PIXCLKSRC - PIXCLK Source Control Register */
22#define PIXCLKSRC_SEL Fld(2,0)
23#define PIXCLKSRC_REF ((0x0) << FShft(PIXCLKSRC_SEL))
24#define PIXCLKSRC_PLL_1 ((0x1) << FShft(PIXCLKSRC_SEL))
25#define PIXCLKSRC_PLL_2 ((0x2) << FShft(PIXCLKSRC_SEL))
26
27/* Clock Disable Register */
28#define CLKSLEEP_SLP (1 << 0)
29
30/* Core PLL Control Register */
31#define CORE_PLL_M Fld(6,7)
32#define Core_Pll_M(x) ((x) << FShft(CORE_PLL_M))
33#define CORE_PLL_N Fld(3,4)
34#define Core_Pll_N(x) ((x) << FShft(CORE_PLL_N))
35#define CORE_PLL_P Fld(3,1)
36#define Core_Pll_P(x) ((x) << FShft(CORE_PLL_P))
37#define CORE_PLL_EN (1 << 0)
38
39/* Display PLL Control Register */
40#define DISP_PLL_M Fld(6,7)
41#define Disp_Pll_M(x) ((x) << FShft(DISP_PLL_M))
42#define DISP_PLL_N Fld(3,4)
43#define Disp_Pll_N(x) ((x) << FShft(DISP_PLL_N))
44#define DISP_PLL_P Fld(3,1)
45#define Disp_Pll_P(x) ((x) << FShft(DISP_PLL_P))
46#define DISP_PLL_EN (1 << 0)
47
48/* PLL status register */
49#define PLLSTAT_CORE_PLL_LOST_L (1 << 3)
50#define PLLSTAT_CORE_PLL_LSTS (1 << 2)
51#define PLLSTAT_DISP_PLL_LOST_L (1 << 1)
52#define PLLSTAT_DISP_PLL_LSTS (1 << 0)
53
54/* Video and scale clock control register */
55#define VOVRCLK_EN (1 << 0)
56
57/* Pixel clock control register */
58#define PIXCLK_EN (1 << 0)
59
60/* Memory clock control register */
61#define MEMCLK_EN (1 << 0)
62
63/* MBX clock control register */
64#define MBXCLK_DIV Fld(2,2)
65#define MBXCLK_DIV_1 ((0x0) << FShft(MBXCLK_DIV))
66#define MBXCLK_DIV_2 ((0x1) << FShft(MBXCLK_DIV))
67#define MBXCLK_DIV_3 ((0x2) << FShft(MBXCLK_DIV))
68#define MBXCLK_DIV_4 ((0x3) << FShft(MBXCLK_DIV))
69#define MBXCLK_EN Fld(2,0)
70#define MBXCLK_EN_NONE ((0x0) << FShft(MBXCLK_EN))
71#define MBXCLK_EN_2D ((0x1) << FShft(MBXCLK_EN))
72#define MBXCLK_EN_BOTH ((0x2) << FShft(MBXCLK_EN))
73
74/* M24 clock control register */
75#define M24CLK_DIV Fld(2,1)
76#define M24CLK_DIV_1 ((0x0) << FShft(M24CLK_DIV))
77#define M24CLK_DIV_2 ((0x1) << FShft(M24CLK_DIV))
78#define M24CLK_DIV_3 ((0x2) << FShft(M24CLK_DIV))
79#define M24CLK_DIV_4 ((0x3) << FShft(M24CLK_DIV))
80#define M24CLK_EN (1 << 0)
81
82/* SDRAM clock control register */
83#define SDCLK_EN (1 << 0)
84
85/* PixClk Divisor Register */
86#define PIXCLKDIV_PD Fld(9,0)
87#define Pixclkdiv_Pd(x) ((x) << FShft(PIXCLKDIV_PD))
88
89/* LCD Config control register */
90#define LCDCFG_IN_FMT Fld(3,28)
91#define Lcdcfg_In_Fmt(x) ((x) << FShft(LCDCFG_IN_FMT))
92#define LCDCFG_LCD1DEN_POL (1 << 27)
93#define LCDCFG_LCD1FCLK_POL (1 << 26)
94#define LCDCFG_LCD1LCLK_POL (1 << 25)
95#define LCDCFG_LCD1D_POL (1 << 24)
96#define LCDCFG_LCD2DEN_POL (1 << 23)
97#define LCDCFG_LCD2FCLK_POL (1 << 22)
98#define LCDCFG_LCD2LCLK_POL (1 << 21)
99#define LCDCFG_LCD2D_POL (1 << 20)
100#define LCDCFG_LCD1_TS (1 << 19)
101#define LCDCFG_LCD1D_DS (1 << 18)
102#define LCDCFG_LCD1C_DS (1 << 17)
103#define LCDCFG_LCD1_IS_IN (1 << 16)
104#define LCDCFG_LCD2_TS (1 << 3)
105#define LCDCFG_LCD2D_DS (1 << 2)
106#define LCDCFG_LCD2C_DS (1 << 1)
107#define LCDCFG_LCD2_IS_IN (1 << 0)
108
109/* On-Die Frame Buffer Power Control Register */
110#define ODFBPWR_SLOW (1 << 2)
111#define ODFBPWR_MODE Fld(2,0)
112#define ODFBPWR_MODE_ACT ((0x0) << FShft(ODFBPWR_MODE))
113#define ODFBPWR_MODE_ACT_LP ((0x1) << FShft(ODFBPWR_MODE))
114#define ODFBPWR_MODE_SLEEP ((0x2) << FShft(ODFBPWR_MODE))
115#define ODFBPWR_MODE_SHUTD ((0x3) << FShft(ODFBPWR_MODE))
116
117/* On-Die Frame Buffer Power State Status Register */
118#define ODFBSTAT_ACT (1 << 2)
119#define ODFBSTAT_SLP (1 << 1)
120#define ODFBSTAT_SDN (1 << 0)
121
122/* LMRST - Local Memory (SDRAM) Reset */
123#define LMRST_MC_RST (1 << 0)
124
125/* LMCFG - Local Memory (SDRAM) Configuration Register */
126#define LMCFG_LMC_DS (1 << 5)
127#define LMCFG_LMD_DS (1 << 4)
128#define LMCFG_LMA_DS (1 << 3)
129#define LMCFG_LMC_TS (1 << 2)
130#define LMCFG_LMD_TS (1 << 1)
131#define LMCFG_LMA_TS (1 << 0)
132
133/* LMPWR - Local Memory (SDRAM) Power Control Register */
134#define LMPWR_MC_PWR_CNT Fld(2,0)
135#define LMPWR_MC_PWR_ACT ((0x0) << FShft(LMPWR_MC_PWR_CNT)) /* Active */
136#define LMPWR_MC_PWR_SRM ((0x1) << FShft(LMPWR_MC_PWR_CNT)) /* Self-refresh */
137#define LMPWR_MC_PWR_DPD ((0x3) << FShft(LMPWR_MC_PWR_CNT)) /* deep power down */
138
139/* LMPWRSTAT - Local Memory (SDRAM) Power Status Register */
140#define LMPWRSTAT_MC_PWR_CNT Fld(2,0)
141#define LMPWRSTAT_MC_PWR_ACT ((0x0) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Active */
142#define LMPWRSTAT_MC_PWR_SRM ((0x1) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Self-refresh */
143#define LMPWRSTAT_MC_PWR_DPD ((0x3) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* deep power down */
144
145/* LMTYPE - Local Memory (SDRAM) Type Register */
146#define LMTYPE_CASLAT Fld(3,10)
147#define LMTYPE_CASLAT_1 ((0x1) << FShft(LMTYPE_CASLAT))
148#define LMTYPE_CASLAT_2 ((0x2) << FShft(LMTYPE_CASLAT))
149#define LMTYPE_CASLAT_3 ((0x3) << FShft(LMTYPE_CASLAT))
150#define LMTYPE_BKSZ Fld(2,8)
151#define LMTYPE_BKSZ_1 ((0x1) << FShft(LMTYPE_BKSZ))
152#define LMTYPE_BKSZ_2 ((0x2) << FShft(LMTYPE_BKSZ))
153#define LMTYPE_ROWSZ Fld(4,4)
154#define LMTYPE_ROWSZ_11 ((0xb) << FShft(LMTYPE_ROWSZ))
155#define LMTYPE_ROWSZ_12 ((0xc) << FShft(LMTYPE_ROWSZ))
156#define LMTYPE_ROWSZ_13 ((0xd) << FShft(LMTYPE_ROWSZ))
157#define LMTYPE_COLSZ Fld(4,0)
158#define LMTYPE_COLSZ_7 ((0x7) << FShft(LMTYPE_COLSZ))
159#define LMTYPE_COLSZ_8 ((0x8) << FShft(LMTYPE_COLSZ))
160#define LMTYPE_COLSZ_9 ((0x9) << FShft(LMTYPE_COLSZ))
161#define LMTYPE_COLSZ_10 ((0xa) << FShft(LMTYPE_COLSZ))
162#define LMTYPE_COLSZ_11 ((0xb) << FShft(LMTYPE_COLSZ))
163#define LMTYPE_COLSZ_12 ((0xc) << FShft(LMTYPE_COLSZ))
164
165/* LMTIM - Local Memory (SDRAM) Timing Register */
166#define LMTIM_TRAS Fld(4,16)
167#define Lmtim_Tras(x) ((x) << FShft(LMTIM_TRAS))
168#define LMTIM_TRP Fld(4,12)
169#define Lmtim_Trp(x) ((x) << FShft(LMTIM_TRP))
170#define LMTIM_TRCD Fld(4,8)
171#define Lmtim_Trcd(x) ((x) << FShft(LMTIM_TRCD))
172#define LMTIM_TRC Fld(4,4)
173#define Lmtim_Trc(x) ((x) << FShft(LMTIM_TRC))
174#define LMTIM_TDPL Fld(4,0)
175#define Lmtim_Tdpl(x) ((x) << FShft(LMTIM_TDPL))
176
177/* LMREFRESH - Local Memory (SDRAM) tREF Control Register */
178#define LMREFRESH_TREF Fld(2,0)
179#define Lmrefresh_Tref(x) ((x) << FShft(LMREFRESH_TREF))
180
181/* GSCTRL - Graphics surface control register */
182#define GSCTRL_LUT_EN (1 << 31)
183#define GSCTRL_GPIXFMT Fld(4,27)
184#define GSCTRL_GPIXFMT_INDEXED ((0x0) << FShft(GSCTRL_GPIXFMT))
185#define GSCTRL_GPIXFMT_ARGB4444 ((0x4) << FShft(GSCTRL_GPIXFMT))
186#define GSCTRL_GPIXFMT_ARGB1555 ((0x5) << FShft(GSCTRL_GPIXFMT))
187#define GSCTRL_GPIXFMT_RGB888 ((0x6) << FShft(GSCTRL_GPIXFMT))
188#define GSCTRL_GPIXFMT_RGB565 ((0x7) << FShft(GSCTRL_GPIXFMT))
189#define GSCTRL_GPIXFMT_ARGB8888 ((0x8) << FShft(GSCTRL_GPIXFMT))
190#define GSCTRL_GAMMA_EN (1 << 26)
191
192#define GSCTRL_GSWIDTH Fld(11,11)
193#define Gsctrl_Width(Pixel) /* Display Width [1..2048 pix.] */ \
194 (((Pixel) - 1) << FShft(GSCTRL_GSWIDTH))
195
196#define GSCTRL_GSHEIGHT Fld(11,0)
197#define Gsctrl_Height(Pixel) /* Display Height [1..2048 pix.] */ \
198 (((Pixel) - 1) << FShft(GSCTRL_GSHEIGHT))
199
200/* GBBASE fileds */
201#define GBBASE_GLALPHA Fld(8,24)
202#define Gbbase_Glalpha(x) ((x) << FShft(GBBASE_GLALPHA))
203
204#define GBBASE_COLKEY Fld(24,0)
205#define Gbbase_Colkey(x) ((x) << FShft(GBBASE_COLKEY))
206
207/* GDRCTRL fields */
208#define GDRCTRL_PIXDBL (1 << 31)
209#define GDRCTRL_PIXHLV (1 << 30)
210#define GDRCTRL_LNDBL (1 << 29)
211#define GDRCTRL_LNHLV (1 << 28)
212#define GDRCTRL_COLKEYM Fld(24,0)
213#define Gdrctrl_Colkeym(x) ((x) << FShft(GDRCTRL_COLKEYM))
214
215/* GSCADR graphics stream control address register fields */
216#define GSCADR_STR_EN (1 << 31)
217#define GSCADR_COLKEY_EN (1 << 30)
218#define GSCADR_COLKEYSCR (1 << 29)
219#define GSCADR_BLEND_M Fld(2,27)
220#define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M))
221#define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M))
222#define GSCADR_BLEND_GLOB ((0x2) << FShft(GSCADR_BLEND_M))
223#define GSCADR_BLEND_PIX ((0x3) << FShft(GSCADR_BLEND_M))
224#define GSCADR_BLEND_POS Fld(2,24)
225#define GSCADR_BLEND_GFX ((0x0) << FShft(GSCADR_BLEND_POS))
226#define GSCADR_BLEND_VID ((0x1) << FShft(GSCADR_BLEND_POS))
227#define GSCADR_BLEND_CUR ((0x2) << FShft(GSCADR_BLEND_POS))
228#define GSCADR_GBASE_ADR Fld(23,0)
229#define Gscadr_Gbase_Adr(x) ((x) << FShft(GSCADR_GBASE_ADR))
230
231/* GSADR graphics stride address register fields */
232#define GSADR_SRCSTRIDE Fld(10,22)
233#define Gsadr_Srcstride(x) ((x) << FShft(GSADR_SRCSTRIDE))
234#define GSADR_XSTART Fld(11,11)
235#define Gsadr_Xstart(x) ((x) << FShft(GSADR_XSTART))
236#define GSADR_YSTART Fld(11,0)
237#define Gsadr_Ystart(y) ((y) << FShft(GSADR_YSTART))
238
239/* GPLUT graphics palette register fields */
240#define GPLUT_LUTADR Fld(8,24)
241#define Gplut_Lutadr(x) ((x) << FShft(GPLUT_LUTADR))
242#define GPLUT_LUTDATA Fld(24,0)
243#define Gplut_Lutdata(x) ((x) << FShft(GPLUT_LUTDATA))
244
245/* HCCTRL - Hardware Cursor Register fields */
246#define HCCTRL_CUR_EN (1 << 31)
247#define HCCTRL_COLKEY_EN (1 << 29)
248#define HCCTRL_COLKEYSRC (1 << 28)
249#define HCCTRL_BLEND_M Fld(2,26)
250#define HCCTRL_BLEND_NONE ((0x0) << FShft(HCCTRL_BLEND_M))
251#define HCCTRL_BLEND_INV ((0x1) << FShft(HCCTRL_BLEND_M))
252#define HCCTRL_BLEND_GLOB ((0x2) << FShft(HCCTRL_BLEND_M))
253#define HCCTRL_BLEND_PIX ((0x3) << FShft(HCCTRL_BLEND_M))
254#define HCCTRL_CPIXFMT Fld(3,23)
255#define HCCTRL_CPIXFMT_RGB332 ((0x3) << FShft(HCCTRL_CPIXFMT))
256#define HCCTRL_CPIXFMT_ARGB4444 ((0x4) << FShft(HCCTRL_CPIXFMT))
257#define HCCTRL_CPIXFMT_ARGB1555 ((0x5) << FShft(HCCTRL_CPIXFMT))
258#define HCCTRL_CBASE_ADR Fld(23,0)
259#define Hcctrl_Cbase_Adr(x) ((x) << FShft(HCCTRL_CBASE_ADR))
260
261/* HCSIZE Hardware Cursor Size Register fields */
262#define HCSIZE_BLEND_POS Fld(2,29)
263#define HCSIZE_BLEND_GFX ((0x0) << FShft(HCSIZE_BLEND_POS))
264#define HCSIZE_BLEND_VID ((0x1) << FShft(HCSIZE_BLEND_POS))
265#define HCSIZE_BLEND_CUR ((0x2) << FShft(HCSIZE_BLEND_POS))
266#define HCSIZE_CWIDTH Fld(3,16)
267#define Hcsize_Cwidth(x) ((x) << FShft(HCSIZE_CWIDTH))
268#define HCSIZE_CHEIGHT Fld(3,0)
269#define Hcsize_Cheight(x) ((x) << FShft(HCSIZE_CHEIGHT))
270
271/* HCPOS Hardware Cursor Position Register fields */
272#define HCPOS_SWITCHSRC (1 << 30)
273#define HCPOS_CURBLINK Fld(6,24)
274#define Hcpos_Curblink(x) ((x) << FShft(HCPOS_CURBLINK))
275#define HCPOS_XSTART Fld(12,12)
276#define Hcpos_Xstart(x) ((x) << FShft(HCPOS_XSTART))
277#define HCPOS_YSTART Fld(12,0)
278#define Hcpos_Ystart(y) ((y) << FShft(HCPOS_YSTART))
279
280/* HCBADR Hardware Cursor Blend Address Register */
281#define HCBADR_GLALPHA Fld(8,24)
282#define Hcbadr_Glalpha(x) ((x) << FShft(HCBADR_GLALPHA))
283#define HCBADR_COLKEY Fld(24,0)
284#define Hcbadr_Colkey(x) ((x) << FShft(HCBADR_COLKEY))
285
286/* HCCKMSK - Hardware Cursor Color Key Mask Register */
287#define HCCKMSK_COLKEY_M Fld(24,0)
288#define Hcckmsk_Colkey_M(x) ((x) << FShft(HCCKMSK_COLKEY_M))
289
290/* DSCTRL - Display sync control register */
291#define DSCTRL_SYNCGEN_EN (1 << 31)
292#define DSCTRL_DPL_RST (1 << 29)
293#define DSCTRL_PWRDN_M (1 << 28)
294#define DSCTRL_UPDSYNCCNT (1 << 26)
295#define DSCTRL_UPDINTCNT (1 << 25)
296#define DSCTRL_UPDCNT (1 << 24)
297#define DSCTRL_UPDWAIT Fld(4,16)
298#define Dsctrl_Updwait(x) ((x) << FShft(DSCTRL_UPDWAIT))
299#define DSCTRL_CLKPOL (1 << 11)
300#define DSCTRL_CSYNC_EN (1 << 10)
301#define DSCTRL_VS_SLAVE (1 << 7)
302#define DSCTRL_HS_SLAVE (1 << 6)
303#define DSCTRL_BLNK_POL (1 << 5)
304#define DSCTRL_BLNK_DIS (1 << 4)
305#define DSCTRL_VS_POL (1 << 3)
306#define DSCTRL_VS_DIS (1 << 2)
307#define DSCTRL_HS_POL (1 << 1)
308#define DSCTRL_HS_DIS (1 << 0)
309
310/* DHT01 - Display horizontal timing register 01 */
311#define DHT01_HBPS Fld(12,16)
312#define Dht01_Hbps(x) ((x) << FShft(DHT01_HBPS))
313#define DHT01_HT Fld(12,0)
314#define Dht01_Ht(x) ((x) << FShft(DHT01_HT))
315
316/* DHT02 - Display horizontal timing register 02 */
317#define DHT02_HAS Fld(12,16)
318#define Dht02_Has(x) ((x) << FShft(DHT02_HAS))
319#define DHT02_HLBS Fld(12,0)
320#define Dht02_Hlbs(x) ((x) << FShft(DHT02_HLBS))
321
322/* DHT03 - Display horizontal timing register 03 */
323#define DHT03_HFPS Fld(12,16)
324#define Dht03_Hfps(x) ((x) << FShft(DHT03_HFPS))
325#define DHT03_HRBS Fld(12,0)
326#define Dht03_Hrbs(x) ((x) << FShft(DHT03_HRBS))
327
328/* DVT01 - Display vertical timing register 01 */
329#define DVT01_VBPS Fld(12,16)
330#define Dvt01_Vbps(x) ((x) << FShft(DVT01_VBPS))
331#define DVT01_VT Fld(12,0)
332#define Dvt01_Vt(x) ((x) << FShft(DVT01_VT))
333
334/* DVT02 - Display vertical timing register 02 */
335#define DVT02_VAS Fld(12,16)
336#define Dvt02_Vas(x) ((x) << FShft(DVT02_VAS))
337#define DVT02_VTBS Fld(12,0)
338#define Dvt02_Vtbs(x) ((x) << FShft(DVT02_VTBS))
339
340/* DVT03 - Display vertical timing register 03 */
341#define DVT03_VFPS Fld(12,16)
342#define Dvt03_Vfps(x) ((x) << FShft(DVT03_VFPS))
343#define DVT03_VBBS Fld(12,0)
344#define Dvt03_Vbbs(x) ((x) << FShft(DVT03_VBBS))
345
346/* DVECTRL - display vertical event control register */
347#define DVECTRL_VEVENT Fld(12,16)
348#define Dvectrl_Vevent(x) ((x) << FShft(DVECTRL_VEVENT))
349#define DVECTRL_VFETCH Fld(12,0)
350#define Dvectrl_Vfetch(x) ((x) << FShft(DVECTRL_VFETCH))
351
352/* DHDET - display horizontal DE timing register */
353#define DHDET_HDES Fld(12,16)
354#define Dhdet_Hdes(x) ((x) << FShft(DHDET_HDES))
355#define DHDET_HDEF Fld(12,0)
356#define Dhdet_Hdef(x) ((x) << FShft(DHDET_HDEF))
357
358/* DVDET - display vertical DE timing register */
359#define DVDET_VDES Fld(12,16)
360#define Dvdet_Vdes(x) ((x) << FShft(DVDET_VDES))
361#define DVDET_VDEF Fld(12,0)
362#define Dvdet_Vdef(x) ((x) << FShft(DVDET_VDEF))
363
364/* DODMSK - display output data mask register */
365#define DODMSK_MASK_LVL (1 << 31)
366#define DODMSK_BLNK_LVL (1 << 30)
367#define DODMSK_MASK_B Fld(8,16)
368#define Dodmsk_Mask_B(x) ((x) << FShft(DODMSK_MASK_B))
369#define DODMSK_MASK_G Fld(8,8)
370#define Dodmsk_Mask_G(x) ((x) << FShft(DODMSK_MASK_G))
371#define DODMSK_MASK_R Fld(8,0)
372#define Dodmsk_Mask_R(x) ((x) << FShft(DODMSK_MASK_R))
373
374/* DBCOL - display border color control register */
375#define DBCOL_BORDCOL Fld(24,0)
376#define Dbcol_Bordcol(x) ((x) << FShft(DBCOL_BORDCOL))
377
378/* DVLNUM - display vertical line number register */
379#define DVLNUM_VLINE Fld(12,0)
380#define Dvlnum_Vline(x) ((x) << FShft(DVLNUM_VLINE))
381
382/* DMCTRL - Display Memory Control Register */
383#define DMCTRL_MEM_REF Fld(2,30)
384#define DMCTRL_MEM_REF_ACT ((0x0) << FShft(DMCTRL_MEM_REF))
385#define DMCTRL_MEM_REF_HB ((0x1) << FShft(DMCTRL_MEM_REF))
386#define DMCTRL_MEM_REF_VB ((0x2) << FShft(DMCTRL_MEM_REF))
387#define DMCTRL_MEM_REF_BOTH ((0x3) << FShft(DMCTRL_MEM_REF))
388#define DMCTRL_UV_THRHLD Fld(6,24)
389#define Dmctrl_Uv_Thrhld(x) ((x) << FShft(DMCTRL_UV_THRHLD))
390#define DMCTRL_V_THRHLD Fld(7,16)
391#define Dmctrl_V_Thrhld(x) ((x) << FShft(DMCTRL_V_THRHLD))
392#define DMCTRL_D_THRHLD Fld(7,8)
393#define Dmctrl_D_Thrhld(x) ((x) << FShft(DMCTRL_D_THRHLD))
394#define DMCTRL_BURSTLEN Fld(6,0)
395#define Dmctrl_Burstlen(x) ((x) << FShft(DMCTRL_BURSTLEN))
396
397
398/* DLSTS - display load status register */
399#define DLSTS_RLD_ADONE (1 << 23)
400/* #define DLSTS_RLD_ADOUT Fld(23,0) */
401
402/* DLLCTRL - display list load control register */
403#define DLLCTRL_RLD_ADRLN Fld(8,24)
404#define Dllctrl_Rld_Adrln(x) ((x) << FShft(DLLCTRL_RLD_ADRLN))
405
406/* SPOCTRL - Scale Pitch/Order Control Register */
407#define SPOCTRL_H_SC_BP (1 << 31)
408#define SPOCTRL_V_SC_BP (1 << 30)
409#define SPOCTRL_HV_SC_OR (1 << 29)
410#define SPOCTRL_VS_UR_C (1 << 27)
411#define SPOCTRL_VORDER Fld(2,16)
412#define SPOCTRL_VORDER_1TAP ((0x0) << FShft(SPOCTRL_VORDER))
413#define SPOCTRL_VORDER_2TAP ((0x1) << FShft(SPOCTRL_VORDER))
414#define SPOCTRL_VORDER_4TAP ((0x3) << FShft(SPOCTRL_VORDER))
415#define SPOCTRL_VPITCH Fld(16,0)
416#define Spoctrl_Vpitch(x) ((x) << FShft(SPOCTRL_VPITCH))
417
418#endif /* __REG_BITS_2700G_ */
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
new file mode 100644
index 000000000000..ad20be07666b
--- /dev/null
+++ b/drivers/video/mbx/regs.h
@@ -0,0 +1,195 @@
1#ifndef __REGS_2700G_
2#define __REGS_2700G_
3
4/* extern unsigned long virt_base_2700; */
5/* #define __REG_2700G(x) (*(volatile unsigned long*)((x)+virt_base_2700)) */
6#define __REG_2700G(x) ((x)+virt_base_2700)
7
8/* System Configuration Registers (0x0000_0000 0x0000_0010) */
9#define SYSCFG __REG_2700G(0x00000000)
10#define PFBASE __REG_2700G(0x00000004)
11#define PFCEIL __REG_2700G(0x00000008)
12#define POLLFLAG __REG_2700G(0x0000000c)
13#define SYSRST __REG_2700G(0x00000010)
14
15/* Interrupt Control Registers (0x0000_0014 0x0000_002F) */
16#define NINTPW __REG_2700G(0x00000014)
17#define MINTENABLE __REG_2700G(0x00000018)
18#define MINTSTAT __REG_2700G(0x0000001c)
19#define SINTENABLE __REG_2700G(0x00000020)
20#define SINTSTAT __REG_2700G(0x00000024)
21#define SINTCLR __REG_2700G(0x00000028)
22
23/* Clock Control Registers (0x0000_002C 0x0000_005F) */
24#define SYSCLKSRC __REG_2700G(0x0000002c)
25#define PIXCLKSRC __REG_2700G(0x00000030)
26#define CLKSLEEP __REG_2700G(0x00000034)
27#define COREPLL __REG_2700G(0x00000038)
28#define DISPPLL __REG_2700G(0x0000003c)
29#define PLLSTAT __REG_2700G(0x00000040)
30#define VOVRCLK __REG_2700G(0x00000044)
31#define PIXCLK __REG_2700G(0x00000048)
32#define MEMCLK __REG_2700G(0x0000004c)
33#define M24CLK __REG_2700G(0x00000054)
34#define MBXCLK __REG_2700G(0x00000054)
35#define SDCLK __REG_2700G(0x00000058)
36#define PIXCLKDIV __REG_2700G(0x0000005c)
37
38/* LCD Port Control Register (0x0000_0060 0x0000_006F) */
39#define LCD_CONFIG __REG_2700G(0x00000060)
40
41/* On-Die Frame Buffer Registers (0x0000_0064 0x0000_006B) */
42#define ODFBPWR __REG_2700G(0x00000064)
43#define ODFBSTAT __REG_2700G(0x00000068)
44
45/* GPIO Registers (0x0000_006C 0x0000_007F) */
46#define GPIOCGF __REG_2700G(0x0000006c)
47#define GPIOHI __REG_2700G(0x00000070)
48#define GPIOLO __REG_2700G(0x00000074)
49#define GPIOSTAT __REG_2700G(0x00000078)
50
51/* Pulse Width Modulator (PWM) Registers (0x0000_0200 0x0000_02FF) */
52#define PWMRST __REG_2700G(0x00000200)
53#define PWMCFG __REG_2700G(0x00000204)
54#define PWM0DIV __REG_2700G(0x00000210)
55#define PWM0DUTY __REG_2700G(0x00000214)
56#define PWM0PER __REG_2700G(0x00000218)
57#define PWM1DIV __REG_2700G(0x00000220)
58#define PWM1DUTY __REG_2700G(0x00000224)
59#define PWM1PER __REG_2700G(0x00000228)
60
61/* Identification (ID) Registers (0x0000_0300 0x0000_0FFF) */
62#define ID __REG_2700G(0x00000FF0)
63
64/* Local Memory (SDRAM) Interface Registers (0x0000_1000 0x0000_1FFF) */
65#define LMRST __REG_2700G(0x00001000)
66#define LMCFG __REG_2700G(0x00001004)
67#define LMPWR __REG_2700G(0x00001008)
68#define LMPWRSTAT __REG_2700G(0x0000100c)
69#define LMCEMR __REG_2700G(0x00001010)
70#define LMTYPE __REG_2700G(0x00001014)
71#define LMTIM __REG_2700G(0x00001018)
72#define LMREFRESH __REG_2700G(0x0000101c)
73#define LMPROTMIN __REG_2700G(0x00001020)
74#define LMPROTMAX __REG_2700G(0x00001024)
75#define LMPROTCFG __REG_2700G(0x00001028)
76#define LMPROTERR __REG_2700G(0x0000102c)
77
78/* Plane Controller Registers (0x0000_2000 0x0000_2FFF) */
79#define GSCTRL __REG_2700G(0x00002000)
80#define VSCTRL __REG_2700G(0x00002004)
81#define GBBASE __REG_2700G(0x00002020)
82#define VBBASE __REG_2700G(0x00002024)
83#define GDRCTRL __REG_2700G(0x00002040)
84#define VCMSK __REG_2700G(0x00002044)
85#define GSCADR __REG_2700G(0x00002060)
86#define VSCADR __REG_2700G(0x00002064)
87#define VUBASE __REG_2700G(0x00002084)
88#define VVBASE __REG_2700G(0x000020a4)
89#define GSADR __REG_2700G(0x000020c0)
90#define VSADR __REG_2700G(0x000020c4)
91#define HCCTRL __REG_2700G(0x00002100)
92#define HCSIZE __REG_2700G(0x00002110)
93#define HCPOS __REG_2700G(0x00002120)
94#define HCBADR __REG_2700G(0x00002130)
95#define HCCKMSK __REG_2700G(0x00002140)
96#define GPLUT __REG_2700G(0x00002150)
97#define DSCTRL __REG_2700G(0x00002154)
98#define DHT01 __REG_2700G(0x00002158)
99#define DHT02 __REG_2700G(0x0000215c)
100#define DHT03 __REG_2700G(0x00002160)
101#define DVT01 __REG_2700G(0x00002164)
102#define DVT02 __REG_2700G(0x00002168)
103#define DVT03 __REG_2700G(0x0000216c)
104#define DBCOL __REG_2700G(0x00002170)
105#define BGCOLOR __REG_2700G(0x00002174)
106#define DINTRS __REG_2700G(0x00002178)
107#define DINTRE __REG_2700G(0x0000217c)
108#define DINTRCNT __REG_2700G(0x00002180)
109#define DSIG __REG_2700G(0x00002184)
110#define DMCTRL __REG_2700G(0x00002188)
111#define CLIPCTRL __REG_2700G(0x0000218c)
112#define SPOCTRL __REG_2700G(0x00002190)
113#define SVCTRL __REG_2700G(0x00002194)
114
115/* 0x0000_2198 */
116/* 0x0000_21A8 VSCOEFF[0:4] Video Scalar Vertical Coefficient [0:4] 4.14.5 */
117#define VSCOEFF0 __REG_2700G(0x00002198)
118#define VSCOEFF1 __REG_2700G(0x0000219c)
119#define VSCOEFF2 __REG_2700G(0x000021a0)
120#define VSCOEFF3 __REG_2700G(0x000021a4)
121#define VSCOEFF4 __REG_2700G(0x000021a8)
122
123#define SHCTRL __REG_2700G(0x000021b0)
124
125/* 0x0000_21B4 */
126/* 0x0000_21D4 HSCOEFF[0:8] Video Scalar Horizontal Coefficient [0:8] 4.14.7 */
127#define HSCOEFF0 __REG_2700G(0x000021b4)
128#define HSCOEFF1 __REG_2700G(0x000021b8)
129#define HSCOEFF2 __REG_2700G(0x000021bc)
130#define HSCOEFF3 __REG_2700G(0x000021b0)
131#define HSCOEFF4 __REG_2700G(0x000021c4)
132#define HSCOEFF5 __REG_2700G(0x000021c8)
133#define HSCOEFF6 __REG_2700G(0x000021cc)
134#define HSCOEFF7 __REG_2700G(0x000021d0)
135#define HSCOEFF8 __REG_2700G(0x000021d4)
136
137#define SSSIZE __REG_2700G(0x000021D8)
138
139/* 0x0000_2200 */
140/* 0x0000_2240 VIDGAM[0:16] Video Gamma LUT Index [0:16] 4.15.2 */
141#define VIDGAM0 __REG_2700G(0x00002200)
142#define VIDGAM1 __REG_2700G(0x00002204)
143#define VIDGAM2 __REG_2700G(0x00002208)
144#define VIDGAM3 __REG_2700G(0x0000220c)
145#define VIDGAM4 __REG_2700G(0x00002210)
146#define VIDGAM5 __REG_2700G(0x00002214)
147#define VIDGAM6 __REG_2700G(0x00002218)
148#define VIDGAM7 __REG_2700G(0x0000221c)
149#define VIDGAM8 __REG_2700G(0x00002220)
150#define VIDGAM9 __REG_2700G(0x00002224)
151#define VIDGAM10 __REG_2700G(0x00002228)
152#define VIDGAM11 __REG_2700G(0x0000222c)
153#define VIDGAM12 __REG_2700G(0x00002230)
154#define VIDGAM13 __REG_2700G(0x00002234)
155#define VIDGAM14 __REG_2700G(0x00002238)
156#define VIDGAM15 __REG_2700G(0x0000223c)
157#define VIDGAM16 __REG_2700G(0x00002240)
158
159/* 0x0000_2250 */
160/* 0x0000_2290 GFXGAM[0:16] Graphics Gamma LUT Index [0:16] 4.15.3 */
161#define GFXGAM0 __REG_2700G(0x00002250)
162#define GFXGAM1 __REG_2700G(0x00002254)
163#define GFXGAM2 __REG_2700G(0x00002258)
164#define GFXGAM3 __REG_2700G(0x0000225c)
165#define GFXGAM4 __REG_2700G(0x00002260)
166#define GFXGAM5 __REG_2700G(0x00002264)
167#define GFXGAM6 __REG_2700G(0x00002268)
168#define GFXGAM7 __REG_2700G(0x0000226c)
169#define GFXGAM8 __REG_2700G(0x00002270)
170#define GFXGAM9 __REG_2700G(0x00002274)
171#define GFXGAM10 __REG_2700G(0x00002278)
172#define GFXGAM11 __REG_2700G(0x0000227c)
173#define GFXGAM12 __REG_2700G(0x00002280)
174#define GFXGAM13 __REG_2700G(0x00002284)
175#define GFXGAM14 __REG_2700G(0x00002288)
176#define GFXGAM15 __REG_2700G(0x0000228c)
177#define GFXGAM16 __REG_2700G(0x00002290)
178
179#define DLSTS __REG_2700G(0x00002300)
180#define DLLCTRL __REG_2700G(0x00002304)
181#define DVLNUM __REG_2700G(0x00002308)
182#define DUCTRL __REG_2700G(0x0000230c)
183#define DVECTRL __REG_2700G(0x00002310)
184#define DHDET __REG_2700G(0x00002314)
185#define DVDET __REG_2700G(0x00002318)
186#define DODMSK __REG_2700G(0x0000231c)
187#define CSC01 __REG_2700G(0x00002330)
188#define CSC02 __REG_2700G(0x00002334)
189#define CSC03 __REG_2700G(0x00002338)
190#define CSC04 __REG_2700G(0x0000233c)
191#define CSC05 __REG_2700G(0x00002340)
192
193#define FB_MEMORY_START __REG_2700G(0x00060000)
194
195#endif /* __REGS_2700G_ */
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 26a1c618a205..d1267904c280 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/tty.h>
16#include <linux/fb.h> 15#include <linux/fb.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
18 17
@@ -259,6 +258,10 @@ static const struct fb_videomode modedb[] = {
259 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ 258 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
260 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, 259 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
261 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 260 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
261 }, {
262 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
263 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
264 0, FB_VMODE_NONINTERLACED
262 }, 265 },
263}; 266};
264 267
@@ -787,8 +790,9 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
787 if (diff > d) { 790 if (diff > d) {
788 diff = d; 791 diff = d;
789 best = mode; 792 best = mode;
790 } else if (diff == d && mode->refresh > best->refresh) 793 } else if (diff == d && best &&
791 best = mode; 794 mode->refresh > best->refresh)
795 best = mode;
792 } 796 }
793 } 797 }
794 return best; 798 return best;
@@ -1016,8 +1020,6 @@ EXPORT_SYMBOL(fb_videomode_to_var);
1016EXPORT_SYMBOL(fb_var_to_videomode); 1020EXPORT_SYMBOL(fb_var_to_videomode);
1017EXPORT_SYMBOL(fb_mode_is_equal); 1021EXPORT_SYMBOL(fb_mode_is_equal);
1018EXPORT_SYMBOL(fb_add_videomode); 1022EXPORT_SYMBOL(fb_add_videomode);
1019EXPORT_SYMBOL(fb_delete_videomode);
1020EXPORT_SYMBOL(fb_destroy_modelist);
1021EXPORT_SYMBOL(fb_match_mode); 1023EXPORT_SYMBOL(fb_match_mode);
1022EXPORT_SYMBOL(fb_find_best_mode); 1024EXPORT_SYMBOL(fb_find_best_mode);
1023EXPORT_SYMBOL(fb_find_nearest_mode); 1025EXPORT_SYMBOL(fb_find_nearest_mode);
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 24b12f71d5a8..59a6f5fa5ae6 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -54,13 +54,11 @@
54 * 54 *
55 */ 55 */
56 56
57#include <linux/config.h>
58#include <linux/module.h> 57#include <linux/module.h>
59#include <linux/kernel.h> 58#include <linux/kernel.h>
60#include <linux/errno.h> 59#include <linux/errno.h>
61#include <linux/string.h> 60#include <linux/string.h>
62#include <linux/mm.h> 61#include <linux/mm.h>
63#include <linux/tty.h>
64#include <linux/slab.h> 62#include <linux/slab.h>
65#include <linux/delay.h> 63#include <linux/delay.h>
66#include <linux/fb.h> 64#include <linux/fb.h>
@@ -1333,17 +1331,22 @@ static int neofb_blank(int blank_mode, struct fb_info *info)
1333 * run "setterm -powersave powerdown" to take advantage 1331 * run "setterm -powersave powerdown" to take advantage
1334 */ 1332 */
1335 struct neofb_par *par = info->par; 1333 struct neofb_par *par = info->par;
1336 int seqflags, lcdflags, dpmsflags, reg; 1334 int seqflags, lcdflags, dpmsflags, reg, tmpdisp;
1337
1338 1335
1339 /* 1336 /*
1340 * Reload the value stored in the register, if sensible. It might have 1337 * Read back the register bits related to display configuration. They might
1341 * been changed via FN keystroke. 1338 * have been changed underneath the driver via Fn key stroke.
1339 */
1340 neoUnlock();
1341 tmpdisp = vga_rgfx(NULL, 0x20) & 0x03;
1342 neoLock(&par->state);
1343
1344 /* In case we blank the screen, we want to store the possibly new
1345 * configuration in the driver. During un-blank, we re-apply this setting,
1346 * since the LCD bit will be cleared in order to switch off the backlight.
1342 */ 1347 */
1343 if (par->PanelDispCntlRegRead) { 1348 if (par->PanelDispCntlRegRead) {
1344 neoUnlock(); 1349 par->PanelDispCntlReg1 = tmpdisp;
1345 par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03;
1346 neoLock(&par->state);
1347 } 1350 }
1348 par->PanelDispCntlRegRead = !blank_mode; 1351 par->PanelDispCntlRegRead = !blank_mode;
1349 1352
@@ -1378,12 +1381,21 @@ static int neofb_blank(int blank_mode, struct fb_info *info)
1378 break; 1381 break;
1379 case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ 1382 case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */
1380 seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ 1383 seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */
1381 lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ 1384 /*
1385 * During a blank operation with the LID shut, we might store "LCD off"
1386 * by mistake. Due to timing issues, the BIOS may switch the lights
1387 * back on, and we turn it back off once we "unblank".
1388 *
1389 * So here is an attempt to implement ">=" - if we are in the process
1390 * of unblanking, and the LCD bit is unset in the driver but set in the
1391 * register, we must keep it.
1392 */
1393 lcdflags = ((par->PanelDispCntlReg1 | tmpdisp) & 0x02); /* LCD normal */
1382 dpmsflags = 0x00; /* no hsync/vsync suppression */ 1394 dpmsflags = 0x00; /* no hsync/vsync suppression */
1383 break; 1395 break;
1384 case FB_BLANK_UNBLANK: /* unblank */ 1396 case FB_BLANK_UNBLANK: /* unblank */
1385 seqflags = 0; /* Enable sequencer */ 1397 seqflags = 0; /* Enable sequencer */
1386 lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ 1398 lcdflags = ((par->PanelDispCntlReg1 | tmpdisp) & 0x02); /* LCD normal */
1387 dpmsflags = 0x00; /* no hsync/vsync suppression */ 1399 dpmsflags = 0x00; /* no hsync/vsync suppression */
1388#ifdef CONFIG_TOSHIBA 1400#ifdef CONFIG_TOSHIBA
1389 /* Do we still need this ? */ 1401 /* Do we still need this ? */
diff --git a/drivers/video/nvidia/Makefile b/drivers/video/nvidia/Makefile
index 690d37e8de5b..ca47432113e0 100644
--- a/drivers/video/nvidia/Makefile
+++ b/drivers/video/nvidia/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_FB_NVIDIA) += nvidiafb.o
7nvidiafb-y := nvidia.o nv_hw.o nv_setup.o \ 7nvidiafb-y := nvidia.o nv_hw.o nv_setup.o \
8 nv_accel.o 8 nv_accel.o
9nvidiafb-$(CONFIG_FB_NVIDIA_I2C) += nv_i2c.o 9nvidiafb-$(CONFIG_FB_NVIDIA_I2C) += nv_i2c.o
10nvidiafb-$(CONFIG_FB_NVIDIA_BACKLIGHT) += nv_backlight.o
10nvidiafb-$(CONFIG_PPC_OF) += nv_of.o 11nvidiafb-$(CONFIG_PPC_OF) += nv_of.o
11 12
12nvidiafb-objs := $(nvidiafb-y) \ No newline at end of file 13nvidiafb-objs := $(nvidiafb-y)
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
new file mode 100644
index 000000000000..5b75ae4e9457
--- /dev/null
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -0,0 +1,203 @@
1/*
2 * Backlight code for nVidia based graphic cards
3 *
4 * Copyright 2004 Antonino Daplas <adaplas@pol.net>
5 * Copyright (c) 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/backlight.h>
13#include <linux/fb.h>
14#include <linux/pci.h>
15#include "nv_local.h"
16#include "nv_type.h"
17#include "nv_proto.h"
18
19#ifdef CONFIG_PMAC_BACKLIGHT
20#include <asm/backlight.h>
21#include <asm/machdep.h>
22#endif
23
24/* We do not have any information about which values are allowed, thus
25 * we used safe values.
26 */
27#define MIN_LEVEL 0x158
28#define MAX_LEVEL 0x534
29#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
30
31static struct backlight_properties nvidia_bl_data;
32
33/* Call with fb_info->bl_mutex held */
34static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
35 int level)
36{
37 struct fb_info *info = pci_get_drvdata(par->pci_dev);
38 int nlevel;
39
40 /* Get and convert the value */
41 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
42
43 if (nlevel < 0)
44 nlevel = 0;
45 else if (nlevel < MIN_LEVEL)
46 nlevel = MIN_LEVEL;
47 else if (nlevel > MAX_LEVEL)
48 nlevel = MAX_LEVEL;
49
50 return nlevel;
51}
52
53/* Call with fb_info->bl_mutex held */
54static int __nvidia_bl_update_status(struct backlight_device *bd)
55{
56 struct nvidia_par *par = class_get_devdata(&bd->class_dev);
57 u32 tmp_pcrt, tmp_pmc, fpcontrol;
58 int level;
59
60 if (!par->FlatPanel)
61 return 0;
62
63 if (bd->props->power != FB_BLANK_UNBLANK ||
64 bd->props->fb_blank != FB_BLANK_UNBLANK)
65 level = 0;
66 else
67 level = bd->props->brightness;
68
69 tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
70 tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC;
71 fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC;
72
73 if (level > 0) {
74 tmp_pcrt |= 0x1;
75 tmp_pmc |= (1 << 31); /* backlight bit */
76 tmp_pmc |= nvidia_bl_get_level_brightness(par, level) << 16;
77 fpcontrol |= par->fpSyncs;
78 } else
79 fpcontrol |= 0x20000022;
80
81 NV_WR32(par->PCRTC0, 0x081C, tmp_pcrt);
82 NV_WR32(par->PMC, 0x10F0, tmp_pmc);
83 NV_WR32(par->PRAMDAC, 0x848, fpcontrol);
84
85 return 0;
86}
87
88static int nvidia_bl_update_status(struct backlight_device *bd)
89{
90 struct nvidia_par *par = class_get_devdata(&bd->class_dev);
91 struct fb_info *info = pci_get_drvdata(par->pci_dev);
92 int ret;
93
94 mutex_lock(&info->bl_mutex);
95 ret = __nvidia_bl_update_status(bd);
96 mutex_unlock(&info->bl_mutex);
97
98 return ret;
99}
100
101static int nvidia_bl_get_brightness(struct backlight_device *bd)
102{
103 return bd->props->brightness;
104}
105
106static struct backlight_properties nvidia_bl_data = {
107 .owner = THIS_MODULE,
108 .get_brightness = nvidia_bl_get_brightness,
109 .update_status = nvidia_bl_update_status,
110 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
111};
112
113void nvidia_bl_set_power(struct fb_info *info, int power)
114{
115 mutex_lock(&info->bl_mutex);
116
117 if (info->bl_dev) {
118 down(&info->bl_dev->sem);
119 info->bl_dev->props->power = power;
120 __nvidia_bl_update_status(info->bl_dev);
121 up(&info->bl_dev->sem);
122 }
123
124 mutex_unlock(&info->bl_mutex);
125}
126
127void nvidia_bl_init(struct nvidia_par *par)
128{
129 struct fb_info *info = pci_get_drvdata(par->pci_dev);
130 struct backlight_device *bd;
131 char name[12];
132
133 if (!par->FlatPanel)
134 return;
135
136#ifdef CONFIG_PMAC_BACKLIGHT
137 if (!machine_is(powermac) ||
138 !pmac_has_backlight_type("mnca"))
139 return;
140#endif
141
142 snprintf(name, sizeof(name), "nvidiabl%d", info->node);
143
144 bd = backlight_device_register(name, par, &nvidia_bl_data);
145 if (IS_ERR(bd)) {
146 info->bl_dev = NULL;
147 printk(KERN_WARNING "nvidia: Backlight registration failed\n");
148 goto error;
149 }
150
151 mutex_lock(&info->bl_mutex);
152 info->bl_dev = bd;
153 fb_bl_default_curve(info, 0,
154 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
155 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
156 mutex_unlock(&info->bl_mutex);
157
158 down(&bd->sem);
159 bd->props->brightness = nvidia_bl_data.max_brightness;
160 bd->props->power = FB_BLANK_UNBLANK;
161 bd->props->update_status(bd);
162 up(&bd->sem);
163
164#ifdef CONFIG_PMAC_BACKLIGHT
165 mutex_lock(&pmac_backlight_mutex);
166 if (!pmac_backlight)
167 pmac_backlight = bd;
168 mutex_unlock(&pmac_backlight_mutex);
169#endif
170
171 printk("nvidia: Backlight initialized (%s)\n", name);
172
173 return;
174
175error:
176 return;
177}
178
179void nvidia_bl_exit(struct nvidia_par *par)
180{
181 struct fb_info *info = pci_get_drvdata(par->pci_dev);
182
183#ifdef CONFIG_PMAC_BACKLIGHT
184 mutex_lock(&pmac_backlight_mutex);
185#endif
186
187 mutex_lock(&info->bl_mutex);
188 if (info->bl_dev) {
189#ifdef CONFIG_PMAC_BACKLIGHT
190 if (pmac_backlight == info->bl_dev)
191 pmac_backlight = NULL;
192#endif
193
194 backlight_device_unregister(info->bl_dev);
195
196 printk("nvidia: Backlight unloaded\n");
197 }
198 mutex_unlock(&info->bl_mutex);
199
200#ifdef CONFIG_PMAC_BACKLIGHT
201 mutex_unlock(&pmac_backlight_mutex);
202#endif
203}
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index 99c3a8e6a237..9ed640d35728 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -886,7 +886,10 @@ void NVCalcStateExt(struct nvidia_par *par,
886 case NV_ARCH_20: 886 case NV_ARCH_20:
887 case NV_ARCH_30: 887 case NV_ARCH_30:
888 default: 888 default:
889 if (((par->Chipset & 0xffff) == 0x01A0) || 889 if ((par->Chipset & 0xfff0) == 0x0240) {
890 state->arbitration0 = 256;
891 state->arbitration1 = 0x0480;
892 } else if (((par->Chipset & 0xffff) == 0x01A0) ||
890 ((par->Chipset & 0xffff) == 0x01f0)) { 893 ((par->Chipset & 0xffff) == 0x01f0)) {
891 nForceUpdateArbitrationSettings(VClk, 894 nForceUpdateArbitrationSettings(VClk,
892 pixelDepth * 8, 895 pixelDepth * 8,
@@ -1235,6 +1238,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
1235 break; 1238 break;
1236 case 0x0160: 1239 case 0x0160:
1237 case 0x01D0: 1240 case 0x01D0:
1241 case 0x0240:
1238 NV_WR32(par->PMC, 0x1700, 1242 NV_WR32(par->PMC, 0x1700,
1239 NV_RD32(par->PFB, 0x020C)); 1243 NV_RD32(par->PFB, 0x020C));
1240 NV_WR32(par->PMC, 0x1704, 0); 1244 NV_WR32(par->PMC, 0x1704, 0);
@@ -1359,7 +1363,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
1359 if(((par->Chipset & 0xfff0) 1363 if(((par->Chipset & 0xfff0)
1360 != 0x0160) && 1364 != 0x0160) &&
1361 ((par->Chipset & 0xfff0) 1365 ((par->Chipset & 0xfff0)
1362 != 0x0220)) 1366 != 0x0220) &&
1367 ((par->Chipset & 0xfff0)
1368 != 0x240))
1363 NV_WR32(par->PGRAPH, 1369 NV_WR32(par->PGRAPH,
1364 0x6900 + i*4, 1370 0x6900 + i*4,
1365 NV_RD32(par->PFB, 1371 NV_RD32(par->PFB,
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 1edb1c432b75..19eef3a09023 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -10,7 +10,6 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/sched.h> 15#include <linux/sched.h>
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 7a03d040b1a3..d9af88c2b580 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -10,7 +10,6 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/sched.h> 15#include <linux/sched.h>
@@ -33,7 +32,7 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
33{ 32{
34 struct nvidia_par *par = info->par; 33 struct nvidia_par *par = info->par;
35 struct device_node *parent, *dp; 34 struct device_node *parent, *dp;
36 unsigned char *pedid = NULL; 35 const unsigned char *pedid = NULL;
37 static char *propnames[] = { 36 static char *propnames[] = {
38 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", 37 "DFP,EDID", "LCD,EDID", "EDID", "EDID1",
39 "EDID,B", "EDID,A", NULL }; 38 "EDID,B", "EDID,A", NULL };
@@ -43,20 +42,19 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
43 if (parent == NULL) 42 if (parent == NULL)
44 return -1; 43 return -1;
45 if (par->twoHeads) { 44 if (par->twoHeads) {
46 char *pname; 45 const char *pname;
47 int len; 46 int len;
48 47
49 for (dp = NULL; 48 for (dp = NULL;
50 (dp = of_get_next_child(parent, dp)) != NULL;) { 49 (dp = of_get_next_child(parent, dp)) != NULL;) {
51 pname = (char *)get_property(dp, "name", NULL); 50 pname = get_property(dp, "name", NULL);
52 if (!pname) 51 if (!pname)
53 continue; 52 continue;
54 len = strlen(pname); 53 len = strlen(pname);
55 if ((pname[len-1] == 'A' && conn == 1) || 54 if ((pname[len-1] == 'A' && conn == 1) ||
56 (pname[len-1] == 'B' && conn == 2)) { 55 (pname[len-1] == 'B' && conn == 2)) {
57 for (i = 0; propnames[i] != NULL; ++i) { 56 for (i = 0; propnames[i] != NULL; ++i) {
58 pedid = (unsigned char *) 57 pedid = get_property(dp, propnames[i],
59 get_property(dp, propnames[i],
60 NULL); 58 NULL);
61 if (pedid != NULL) 59 if (pedid != NULL)
62 break; 60 break;
@@ -68,8 +66,7 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
68 } 66 }
69 if (pedid == NULL) { 67 if (pedid == NULL) {
70 for (i = 0; propnames[i] != NULL; ++i) { 68 for (i = 0; propnames[i] != NULL; ++i) {
71 pedid = (unsigned char *) 69 pedid = get_property(parent, propnames[i], NULL);
72 get_property(parent, propnames[i], NULL);
73 if (pedid != NULL) 70 if (pedid != NULL)
74 break; 71 break;
75 } 72 }
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index b149a690ee0f..861271017655 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -63,4 +63,16 @@ extern void nvidiafb_imageblit(struct fb_info *info,
63 const struct fb_image *image); 63 const struct fb_image *image);
64extern int nvidiafb_sync(struct fb_info *info); 64extern int nvidiafb_sync(struct fb_info *info);
65extern u8 byte_rev[256]; 65extern u8 byte_rev[256];
66
67/* in nv_backlight.h */
68#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
69extern void nvidia_bl_init(struct nvidia_par *par);
70extern void nvidia_bl_exit(struct nvidia_par *par);
71extern void nvidia_bl_set_power(struct fb_info *info, int power);
72#else
73static inline void nvidia_bl_init(struct nvidia_par *par) {}
74static inline void nvidia_bl_exit(struct nvidia_par *par) {}
75static inline void nvidia_bl_set_power(struct fb_info *info, int power) {}
76#endif
77
66#endif /* __NV_PROTO_H__ */ 78#endif /* __NV_PROTO_H__ */
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 093ab9977c7c..f8cd4c519aeb 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -9,19 +9,18 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/module.h> 12#include <linux/module.h>
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/errno.h> 14#include <linux/errno.h>
16#include <linux/string.h> 15#include <linux/string.h>
17#include <linux/mm.h> 16#include <linux/mm.h>
18#include <linux/tty.h>
19#include <linux/slab.h> 17#include <linux/slab.h>
20#include <linux/delay.h> 18#include <linux/delay.h>
21#include <linux/fb.h> 19#include <linux/fb.h>
22#include <linux/init.h> 20#include <linux/init.h>
23#include <linux/pci.h> 21#include <linux/pci.h>
24#include <linux/console.h> 22#include <linux/console.h>
23#include <linux/backlight.h>
25#ifdef CONFIG_MTRR 24#ifdef CONFIG_MTRR
26#include <asm/mtrr.h> 25#include <asm/mtrr.h>
27#endif 26#endif
@@ -29,20 +28,12 @@
29#include <asm/prom.h> 28#include <asm/prom.h>
30#include <asm/pci-bridge.h> 29#include <asm/pci-bridge.h>
31#endif 30#endif
32#ifdef CONFIG_PMAC_BACKLIGHT
33#include <asm/machdep.h>
34#include <asm/backlight.h>
35#endif
36 31
37#include "nv_local.h" 32#include "nv_local.h"
38#include "nv_type.h" 33#include "nv_type.h"
39#include "nv_proto.h" 34#include "nv_proto.h"
40#include "nv_dma.h" 35#include "nv_dma.h"
41 36
42#ifndef CONFIG_PCI /* sanity check */
43#error This driver requires PCI support.
44#endif
45
46#undef CONFIG_FB_NVIDIA_DEBUG 37#undef CONFIG_FB_NVIDIA_DEBUG
47#ifdef CONFIG_FB_NVIDIA_DEBUG 38#ifdef CONFIG_FB_NVIDIA_DEBUG
48#define NVTRACE printk 39#define NVTRACE printk
@@ -70,359 +61,10 @@
70#define MAX_CURS 32 61#define MAX_CURS 32
71 62
72static struct pci_device_id nvidiafb_pci_tbl[] = { 63static struct pci_device_id nvidiafb_pci_tbl[] = {
73 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT, 64 {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
74 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 65 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0},
75 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2, 66 { 0, }
76 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
77 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
78 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
79 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN,
80 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
81 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
82 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
84 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
85 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
86 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
88 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
90 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
91 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
92 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
93 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
94 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
95 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
96 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
97 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
98 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
99 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
100 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
101 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
102 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
103 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
104 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
105 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
106 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
107 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
108 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
109 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460,
110 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
111 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
112 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
113 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
114 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
115 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_SE,
116 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
117 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
118 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
119 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO,
120 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
121 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_460_GO,
122 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
123 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32,
124 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
125 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL,
126 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
127 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64,
128 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
129 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200,
130 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
131 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL,
132 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
133 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL,
134 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
135 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_410_GO_M16,
136 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
137 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X,
138 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
139 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X,
140 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
141 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X,
142 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
143 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_4000,
144 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
145 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO,
146 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
147 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO,
148 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
149 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_580_XGL,
150 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
151 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_MAC,
152 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
153 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_280_NVS,
154 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
155 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_380_XGL,
156 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
157 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2,
158 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
159 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
160 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
161 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
162 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
163 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
164 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
165 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
166 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
167 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600,
168 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
169 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400,
170 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
171 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
172 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
173 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
175 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
177 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
178 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
179 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800,
180 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
181 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X,
182 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
183 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE,
184 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
185 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO,
186 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
187 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_980_XGL,
188 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
189 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_780_XGL,
190 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
191 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700_GOGL,
192 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
193 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA,
194 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
195 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800,
196 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
197 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_2000,
198 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
199 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1000,
200 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
201 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA,
202 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
203 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600,
204 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
205 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600SE,
206 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
207 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5600,
208 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
209 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5650,
210 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
211 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO700,
212 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
213 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200,
214 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
215 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA,
216 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
217 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1,
218 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
219 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE,
220 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
221 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5200,
222 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
223 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250,
224 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
225 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250_32,
226 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
227 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200,
228 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
229 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_NVS_280_PCI,
230 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
231 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_500,
232 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
233 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5300,
234 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
235 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5100,
236 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
237 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA,
238 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
239 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900,
240 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
241 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT,
242 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
243 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA,
244 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
245 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_3000,
246 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
247 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA,
248 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
249 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700,
250 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
251 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700LE,
252 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
253 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE,
254 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
255 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_1,
256 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
257 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2,
258 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
259 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000,
260 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
261 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100,
262 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
263 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5500,
264 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
265 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5100,
266 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
267 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_700,
268 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
269 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900ZT,
270 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
271 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA,
272 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
273 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800,
274 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
275 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_LE,
276 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
277 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_GT,
278 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
279 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_4000,
280 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
281 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT,
282 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
283 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600,
284 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
285 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6610_XL,
286 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
287 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_540,
288 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
289 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200,
290 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
291 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1,
292 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
293 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1,
294 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
295 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2,
296 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
297 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1,
298 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
299 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT,
300 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
301 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280,
302 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
303 {PCI_VENDOR_ID_NVIDIA, 0x0252,
304 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
305 {PCI_VENDOR_ID_NVIDIA, 0x0313,
306 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
307 {PCI_VENDOR_ID_NVIDIA, 0x0316,
308 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
309 {PCI_VENDOR_ID_NVIDIA, 0x0317,
310 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
311 {PCI_VENDOR_ID_NVIDIA, 0x031D,
312 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
313 {PCI_VENDOR_ID_NVIDIA, 0x031E,
314 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
315 {PCI_VENDOR_ID_NVIDIA, 0x031F,
316 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
317 {PCI_VENDOR_ID_NVIDIA, 0x0329,
318 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
319 {PCI_VENDOR_ID_NVIDIA, 0x032F,
320 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
321 {PCI_VENDOR_ID_NVIDIA, 0x0345,
322 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
323 {PCI_VENDOR_ID_NVIDIA, 0x0349,
324 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
325 {PCI_VENDOR_ID_NVIDIA, 0x034B,
326 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
327 {PCI_VENDOR_ID_NVIDIA, 0x034F,
328 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
329 {PCI_VENDOR_ID_NVIDIA, 0x00c0,
330 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
331 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A,
332 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
333 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A_LE,
334 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
335 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800,
336 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
337 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA,
338 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
339 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_GO1400,
340 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
341 {PCI_VENDOR_ID_NVIDIA, 0x00cd,
342 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
343 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_1400,
344 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
345 {PCI_VENDOR_ID_NVIDIA, 0x0142,
346 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
347 {PCI_VENDOR_ID_NVIDIA, 0x0143,
348 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
349 {PCI_VENDOR_ID_NVIDIA, 0x0144,
350 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
351 {PCI_VENDOR_ID_NVIDIA, 0x0145,
352 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
353 {PCI_VENDOR_ID_NVIDIA, 0x0146,
354 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
355 {PCI_VENDOR_ID_NVIDIA, 0x0147,
356 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
357 {PCI_VENDOR_ID_NVIDIA, 0x0148,
358 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
359 {PCI_VENDOR_ID_NVIDIA, 0x0149,
360 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
361 {PCI_VENDOR_ID_NVIDIA, 0x014b,
362 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
363 {PCI_VENDOR_ID_NVIDIA, 0x14c,
364 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
365 {PCI_VENDOR_ID_NVIDIA, 0x014d,
366 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
367 {PCI_VENDOR_ID_NVIDIA, 0x0160,
368 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
369 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE,
370 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
371 {PCI_VENDOR_ID_NVIDIA, 0x0162,
372 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
373 {PCI_VENDOR_ID_NVIDIA, 0x0163,
374 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
375 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200,
376 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
377 {PCI_VENDOR_ID_NVIDIA, 0x0165,
378 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
379 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250,
380 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
381 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1,
382 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1,
384 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385 {PCI_VENDOR_ID_NVIDIA, 0x0169,
386 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
387 {PCI_VENDOR_ID_NVIDIA, 0x016b,
388 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
389 {PCI_VENDOR_ID_NVIDIA, 0x016c,
390 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
391 {PCI_VENDOR_ID_NVIDIA, 0x016d,
392 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
393 {PCI_VENDOR_ID_NVIDIA, 0x016e,
394 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
395 {PCI_VENDOR_ID_NVIDIA, 0x0210,
396 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
397 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B,
398 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
399 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE,
400 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
401 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT,
402 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
403 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT,
404 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
405 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX,
406 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
407 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800,
408 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
409 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX,
410 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
411 {PCI_VENDOR_ID_NVIDIA, 0x021d,
412 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
413 {PCI_VENDOR_ID_NVIDIA, 0x021e,
414 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
415 {PCI_VENDOR_ID_NVIDIA, 0x0220,
416 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
417 {PCI_VENDOR_ID_NVIDIA, 0x0221,
418 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
419 {PCI_VENDOR_ID_NVIDIA, 0x0222,
420 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
421 {PCI_VENDOR_ID_NVIDIA, 0x0228,
422 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
423 {0,} /* terminate list */
424}; 67};
425
426MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl); 68MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
427 69
428/* command line data, set in nvidiafb_setup() */ 70/* command line data, set in nvidiafb_setup() */
@@ -470,75 +112,6 @@ static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
470 .vmode = FB_VMODE_NONINTERLACED 112 .vmode = FB_VMODE_NONINTERLACED
471}; 113};
472 114
473/*
474 * Backlight control
475 */
476#ifdef CONFIG_PMAC_BACKLIGHT
477
478static int nvidia_backlight_levels[] = {
479 0x158,
480 0x192,
481 0x1c6,
482 0x200,
483 0x234,
484 0x268,
485 0x2a2,
486 0x2d6,
487 0x310,
488 0x344,
489 0x378,
490 0x3b2,
491 0x3e6,
492 0x41a,
493 0x454,
494 0x534,
495};
496
497/* ------------------------------------------------------------------------- *
498 *
499 * Backlight operations
500 *
501 * ------------------------------------------------------------------------- */
502
503static int nvidia_set_backlight_enable(int on, int level, void *data)
504{
505 struct nvidia_par *par = data;
506 u32 tmp_pcrt, tmp_pmc, fpcontrol;
507
508 tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
509 tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC;
510 fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC;
511
512 if (on && (level > BACKLIGHT_OFF)) {
513 tmp_pcrt |= 0x1;
514 tmp_pmc |= (1 << 31); // backlight bit
515 tmp_pmc |= nvidia_backlight_levels[level - 1] << 16;
516 }
517
518 if (on)
519 fpcontrol |= par->fpSyncs;
520 else
521 fpcontrol |= 0x20000022;
522
523 NV_WR32(par->PCRTC0, 0x081C, tmp_pcrt);
524 NV_WR32(par->PMC, 0x10F0, tmp_pmc);
525 NV_WR32(par->PRAMDAC, 0x848, fpcontrol);
526
527 return 0;
528}
529
530static int nvidia_set_backlight_level(int level, void *data)
531{
532 return nvidia_set_backlight_enable(1, level, data);
533}
534
535static struct backlight_controller nvidia_backlight_controller = {
536 nvidia_set_backlight_enable,
537 nvidia_set_backlight_level
538};
539
540#endif /* CONFIG_PMAC_BACKLIGHT */
541
542static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8, 115static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
543 u16 bg, u16 fg, u32 w, u32 h) 116 u16 bg, u16 fg, u32 w, u32 h)
544{ 117{
@@ -1355,11 +928,7 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
1355 NVWriteSeq(par, 0x01, tmp); 928 NVWriteSeq(par, 0x01, tmp);
1356 NVWriteCrtc(par, 0x1a, vesa); 929 NVWriteCrtc(par, 0x1a, vesa);
1357 930
1358#ifdef CONFIG_PMAC_BACKLIGHT 931 nvidia_bl_set_power(info, blank);
1359 if (par->FlatPanel && machine_is(powermac)) {
1360 set_backlight_enable(!blank);
1361 }
1362#endif
1363 932
1364 NVTRACE_LEAVE(); 933 NVTRACE_LEAVE();
1365 934
@@ -1381,24 +950,25 @@ static struct fb_ops nvidia_fb_ops = {
1381}; 950};
1382 951
1383#ifdef CONFIG_PM 952#ifdef CONFIG_PM
1384static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t state) 953static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
1385{ 954{
1386 struct fb_info *info = pci_get_drvdata(dev); 955 struct fb_info *info = pci_get_drvdata(dev);
1387 struct nvidia_par *par = info->par; 956 struct nvidia_par *par = info->par;
1388 957
958 if (mesg.event == PM_EVENT_PRETHAW)
959 mesg.event = PM_EVENT_FREEZE;
1389 acquire_console_sem(); 960 acquire_console_sem();
1390 par->pm_state = state.event; 961 par->pm_state = mesg.event;
1391 962
1392 if (state.event == PM_EVENT_FREEZE) { 963 if (mesg.event == PM_EVENT_SUSPEND) {
1393 dev->dev.power.power_state = state;
1394 } else {
1395 fb_set_suspend(info, 1); 964 fb_set_suspend(info, 1);
1396 nvidiafb_blank(FB_BLANK_POWERDOWN, info); 965 nvidiafb_blank(FB_BLANK_POWERDOWN, info);
1397 nvidia_write_regs(par, &par->SavedReg); 966 nvidia_write_regs(par, &par->SavedReg);
1398 pci_save_state(dev); 967 pci_save_state(dev);
1399 pci_disable_device(dev); 968 pci_disable_device(dev);
1400 pci_set_power_state(dev, pci_choose_state(dev, state)); 969 pci_set_power_state(dev, pci_choose_state(dev, mesg));
1401 } 970 }
971 dev->dev.power.power_state = mesg;
1402 972
1403 release_console_sem(); 973 release_console_sem();
1404 return 0; 974 return 0;
@@ -1532,10 +1102,10 @@ static u32 __devinit nvidia_get_chipset(struct fb_info *info)
1532 struct nvidia_par *par = info->par; 1102 struct nvidia_par *par = info->par;
1533 u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device; 1103 u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
1534 1104
1535 printk("nvidiafb: PCI id - %x\n", id); 1105 printk(KERN_INFO PFX "Device ID: %x \n", id);
1106
1536 if ((id & 0xfff0) == 0x00f0) { 1107 if ((id & 0xfff0) == 0x00f0) {
1537 /* pci-e */ 1108 /* pci-e */
1538 printk("nvidiafb: PCI-E card\n");
1539 id = NV_RD32(par->REGS, 0x1800); 1109 id = NV_RD32(par->REGS, 0x1800);
1540 1110
1541 if ((id & 0x0000ffff) == 0x000010DE) 1111 if ((id & 0x0000ffff) == 0x000010DE)
@@ -1543,9 +1113,9 @@ static u32 __devinit nvidia_get_chipset(struct fb_info *info)
1543 else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */ 1113 else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
1544 id = 0x10DE0000 | ((id << 8) & 0x0000ff00) | 1114 id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
1545 ((id >> 8) & 0x000000ff); 1115 ((id >> 8) & 0x000000ff);
1116 printk(KERN_INFO PFX "Subsystem ID: %x \n", id);
1546 } 1117 }
1547 1118
1548 printk("nvidiafb: Actual id - %x\n", id);
1549 return id; 1119 return id;
1550} 1120}
1551 1121
@@ -1587,6 +1157,7 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info)
1587 case 0x0210: 1157 case 0x0210:
1588 case 0x0220: 1158 case 0x0220:
1589 case 0x0230: 1159 case 0x0230:
1160 case 0x0240:
1590 case 0x0290: 1161 case 0x0290:
1591 case 0x0390: 1162 case 0x0390:
1592 arch = NV_ARCH_40; 1163 arch = NV_ARCH_40;
@@ -1634,7 +1205,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1634 1205
1635 if (pci_request_regions(pd, "nvidiafb")) { 1206 if (pci_request_regions(pd, "nvidiafb")) {
1636 printk(KERN_ERR PFX "cannot request PCI regions\n"); 1207 printk(KERN_ERR PFX "cannot request PCI regions\n");
1637 goto err_out_request; 1208 goto err_out_enable;
1638 } 1209 }
1639 1210
1640 par->FlatPanel = flatpanel; 1211 par->FlatPanel = flatpanel;
@@ -1663,7 +1234,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1663 } 1234 }
1664 1235
1665 par->Chipset = nvidia_get_chipset(info); 1236 par->Chipset = nvidia_get_chipset(info);
1666 printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
1667 par->Architecture = nvidia_get_arch(info); 1237 par->Architecture = nvidia_get_arch(info);
1668 1238
1669 if (par->Architecture == 0) { 1239 if (par->Architecture == 0) {
@@ -1730,22 +1300,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1730 1300
1731 nvidia_save_vga(par, &par->SavedReg); 1301 nvidia_save_vga(par, &par->SavedReg);
1732 1302
1303 pci_set_drvdata(pd, info);
1304 nvidia_bl_init(par);
1733 if (register_framebuffer(info) < 0) { 1305 if (register_framebuffer(info) < 0) {
1734 printk(KERN_ERR PFX "error registering nVidia framebuffer\n"); 1306 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1735 goto err_out_iounmap_fb; 1307 goto err_out_iounmap_fb;
1736 } 1308 }
1737 1309
1738 pci_set_drvdata(pd, info);
1739 1310
1740 printk(KERN_INFO PFX 1311 printk(KERN_INFO PFX
1741 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n", 1312 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1742 info->fix.id, 1313 info->fix.id,
1743 par->FbMapSize / (1024 * 1024), info->fix.smem_start); 1314 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1744#ifdef CONFIG_PMAC_BACKLIGHT 1315
1745 if (par->FlatPanel && machine_is(powermac))
1746 register_backlight_controller(&nvidia_backlight_controller,
1747 par, "mnca");
1748#endif
1749 NVTRACE_LEAVE(); 1316 NVTRACE_LEAVE();
1750 return 0; 1317 return 0;
1751 1318
@@ -1756,10 +1323,8 @@ err_out_free_base1:
1756 nvidia_delete_i2c_busses(par); 1323 nvidia_delete_i2c_busses(par);
1757err_out_arch: 1324err_out_arch:
1758 iounmap(par->REGS); 1325 iounmap(par->REGS);
1759err_out_free_base0: 1326 err_out_free_base0:
1760 pci_release_regions(pd); 1327 pci_release_regions(pd);
1761err_out_request:
1762 pci_disable_device(pd);
1763err_out_enable: 1328err_out_enable:
1764 kfree(info->pixmap.addr); 1329 kfree(info->pixmap.addr);
1765err_out_kfree: 1330err_out_kfree:
@@ -1775,6 +1340,8 @@ static void __exit nvidiafb_remove(struct pci_dev *pd)
1775 1340
1776 NVTRACE_ENTER(); 1341 NVTRACE_ENTER();
1777 1342
1343 nvidia_bl_exit(par);
1344
1778 unregister_framebuffer(info); 1345 unregister_framebuffer(info);
1779#ifdef CONFIG_MTRR 1346#ifdef CONFIG_MTRR
1780 if (par->mtrr.vram_valid) 1347 if (par->mtrr.vram_valid)
@@ -1787,7 +1354,6 @@ static void __exit nvidiafb_remove(struct pci_dev *pd)
1787 nvidia_delete_i2c_busses(par); 1354 nvidia_delete_i2c_busses(par);
1788 iounmap(par->REGS); 1355 iounmap(par->REGS);
1789 pci_release_regions(pd); 1356 pci_release_regions(pd);
1790 pci_disable_device(pd);
1791 kfree(info->pixmap.addr); 1357 kfree(info->pixmap.addr);
1792 framebuffer_release(info); 1358 framebuffer_release(info);
1793 pci_set_drvdata(pd, NULL); 1359 pci_set_drvdata(pd, NULL);
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index ad1434e3f227..bad0e98fb3b6 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -12,13 +12,11 @@
12 * more details. 12 * more details.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/errno.h> 17#include <linux/errno.h>
19#include <linux/string.h> 18#include <linux/string.h>
20#include <linux/mm.h> 19#include <linux/mm.h>
21#include <linux/tty.h>
22#include <linux/slab.h> 20#include <linux/slab.h>
23#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
24#include <linux/delay.h> 22#include <linux/delay.h>
@@ -64,8 +62,6 @@ struct offb_par default_par;
64 * Interface used by the world 62 * Interface used by the world
65 */ 63 */
66 64
67int offb_init(void);
68
69static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 65static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
70 u_int transp, struct fb_info *info); 66 u_int transp, struct fb_info *info);
71static int offb_blank(int blank, struct fb_info *info); 67static int offb_blank(int blank, struct fb_info *info);
@@ -74,11 +70,6 @@ static int offb_blank(int blank, struct fb_info *info);
74extern boot_infos_t *boot_infos; 70extern boot_infos_t *boot_infos;
75#endif 71#endif
76 72
77static void offb_init_nodriver(struct device_node *);
78static void offb_init_fb(const char *name, const char *full_name,
79 int width, int height, int depth, int pitch,
80 unsigned long address, struct device_node *dp);
81
82static struct fb_ops offb_ops = { 73static struct fb_ops offb_ops = {
83 .owner = THIS_MODULE, 74 .owner = THIS_MODULE,
84 .fb_setcolreg = offb_setcolreg, 75 .fb_setcolreg = offb_setcolreg,
@@ -98,14 +89,43 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
98 u_int transp, struct fb_info *info) 89 u_int transp, struct fb_info *info)
99{ 90{
100 struct offb_par *par = (struct offb_par *) info->par; 91 struct offb_par *par = (struct offb_par *) info->par;
92 int i, depth;
93 u32 *pal = info->pseudo_palette;
101 94
102 if (!par->cmap_adr || regno > 255) 95 depth = info->var.bits_per_pixel;
96 if (depth == 16)
97 depth = (info->var.green.length == 5) ? 15 : 16;
98
99 if (regno > 255 ||
100 (depth == 16 && regno > 63) ||
101 (depth == 15 && regno > 31))
103 return 1; 102 return 1;
104 103
104 if (regno < 16) {
105 switch (depth) {
106 case 15:
107 pal[regno] = (regno << 10) | (regno << 5) | regno;
108 break;
109 case 16:
110 pal[regno] = (regno << 11) | (regno << 5) | regno;
111 break;
112 case 24:
113 pal[regno] = (regno << 16) | (regno << 8) | regno;
114 break;
115 case 32:
116 i = (regno << 8) | regno;
117 pal[regno] = (i << 16) | i;
118 break;
119 }
120 }
121
105 red >>= 8; 122 red >>= 8;
106 green >>= 8; 123 green >>= 8;
107 blue >>= 8; 124 blue >>= 8;
108 125
126 if (!par->cmap_adr)
127 return 0;
128
109 switch (par->cmap_type) { 129 switch (par->cmap_type) {
110 case cmap_m64: 130 case cmap_m64:
111 writeb(regno, par->cmap_adr); 131 writeb(regno, par->cmap_adr);
@@ -142,20 +162,6 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
142 break; 162 break;
143 } 163 }
144 164
145 if (regno < 16)
146 switch (info->var.bits_per_pixel) {
147 case 16:
148 ((u16 *) (info->pseudo_palette))[regno] =
149 (regno << 10) | (regno << 5) | regno;
150 break;
151 case 32:
152 {
153 int i = (regno << 8) | regno;
154 ((u32 *) (info->pseudo_palette))[regno] =
155 (i << 16) | i;
156 break;
157 }
158 }
159 return 0; 165 return 0;
160} 166}
161 167
@@ -216,196 +222,17 @@ static int offb_blank(int blank, struct fb_info *info)
216 return 0; 222 return 0;
217} 223}
218 224
219 /*
220 * Initialisation
221 */
222 225
223int __init offb_init(void) 226static void __iomem *offb_map_reg(struct device_node *np, int index,
227 unsigned long offset, unsigned long size)
224{ 228{
225 struct device_node *dp = NULL, *boot_disp = NULL; 229 struct resource r;
226
227#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
228 struct device_node *macos_display = NULL;
229#endif
230 if (fb_get_options("offb", NULL))
231 return -ENODEV;
232
233#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
234 /* If we're booted from BootX... */
235 if (boot_infos != 0) {
236 unsigned long addr =
237 (unsigned long) boot_infos->dispDeviceBase;
238 u32 *addrp;
239 u64 daddr, dsize;
240 unsigned int flags;
241
242 /* find the device node corresponding to the macos display */
243 while ((dp = of_find_node_by_type(dp, "display"))) {
244 int i;
245
246 /*
247 * Look for an AAPL,address property first.
248 */
249 unsigned int na;
250 unsigned int *ap =
251 (unsigned int *)get_property(dp, "AAPL,address",
252 &na);
253 if (ap != 0) {
254 for (na /= sizeof(unsigned int); na > 0;
255 --na, ++ap)
256 if (*ap <= addr &&
257 addr < *ap + 0x1000000) {
258 macos_display = dp;
259 goto foundit;
260 }
261 }
262
263 /*
264 * See if the display address is in one of the address
265 * ranges for this display.
266 */
267 i = 0;
268 for (;;) {
269 addrp = of_get_address(dp, i++, &dsize, &flags);
270 if (addrp == NULL)
271 break;
272 if (!(flags & IORESOURCE_MEM))
273 continue;
274 daddr = of_translate_address(dp, addrp);
275 if (daddr == OF_BAD_ADDR)
276 continue;
277 if (daddr <= addr && addr < (daddr + dsize)) {
278 macos_display = dp;
279 goto foundit;
280 }
281 }
282 foundit:
283 if (macos_display) {
284 printk(KERN_INFO "MacOS display is %s\n",
285 dp->full_name);
286 break;
287 }
288 }
289
290 /* initialize it */
291 offb_init_fb(macos_display ? macos_display->
292 name : "MacOS display",
293 macos_display ? macos_display->
294 full_name : "MacOS display",
295 boot_infos->dispDeviceRect[2],
296 boot_infos->dispDeviceRect[3],
297 boot_infos->dispDeviceDepth,
298 boot_infos->dispDeviceRowBytes, addr, NULL);
299 }
300#endif /* defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) */
301
302 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
303 if (get_property(dp, "linux,opened", NULL) &&
304 get_property(dp, "linux,boot-display", NULL)) {
305 boot_disp = dp;
306 offb_init_nodriver(dp);
307 }
308 }
309 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
310 if (get_property(dp, "linux,opened", NULL) &&
311 dp != boot_disp)
312 offb_init_nodriver(dp);
313 }
314
315 return 0;
316}
317
318
319static void __init offb_init_nodriver(struct device_node *dp)
320{
321 int *pp, i;
322 unsigned int len;
323 int width = 640, height = 480, depth = 8, pitch;
324 unsigned int flags, rsize, *up;
325 u64 address = OF_BAD_ADDR;
326 u32 *addrp;
327 u64 asize;
328
329 if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
330 && len == sizeof(int))
331 depth = *pp;
332 if ((pp = (int *) get_property(dp, "width", &len)) != NULL
333 && len == sizeof(int))
334 width = *pp;
335 if ((pp = (int *) get_property(dp, "height", &len)) != NULL
336 && len == sizeof(int))
337 height = *pp;
338 if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL
339 && len == sizeof(int)) {
340 pitch = *pp;
341 if (pitch == 1)
342 pitch = 0x1000;
343 } else
344 pitch = width;
345
346 rsize = (unsigned long)pitch * (unsigned long)height *
347 (unsigned long)(depth / 8);
348
349 /* Try to match device to a PCI device in order to get a properly
350 * translated address rather then trying to decode the open firmware
351 * stuff in various incorrect ways
352 */
353#ifdef CONFIG_PCI
354 /* First try to locate the PCI device if any */
355 {
356 struct pci_dev *pdev = NULL;
357
358 for_each_pci_dev(pdev) {
359 if (dp == pci_device_to_OF_node(pdev))
360 break;
361 }
362 if (pdev) {
363 for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) {
364 if ((pci_resource_flags(pdev, i) &
365 IORESOURCE_MEM) &&
366 (pci_resource_len(pdev, i) >= rsize))
367 address = pci_resource_start(pdev, i);
368 }
369 pci_dev_put(pdev);
370 }
371 }
372#endif /* CONFIG_PCI */
373
374 /* This one is dodgy, we may drop it ... */
375 if (address == OF_BAD_ADDR &&
376 (up = (unsigned *) get_property(dp, "address", &len)) != NULL &&
377 len == sizeof(unsigned int))
378 address = (u64) * up;
379
380 if (address == OF_BAD_ADDR) {
381 for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
382 != NULL; i++) {
383 if (!(flags & IORESOURCE_MEM))
384 continue;
385 if (asize >= pitch * height * depth / 8)
386 break;
387 }
388 if (addrp == NULL) {
389 printk(KERN_ERR
390 "no framebuffer address found for %s\n",
391 dp->full_name);
392 return;
393 }
394 address = of_translate_address(dp, addrp);
395 if (address == OF_BAD_ADDR) {
396 printk(KERN_ERR
397 "can't translate framebuffer address for %s\n",
398 dp->full_name);
399 return;
400 }
401
402 /* kludge for valkyrie */
403 if (strcmp(dp->name, "valkyrie") == 0)
404 address += 0x1000;
405 }
406 offb_init_fb(dp->name, dp->full_name, width, height, depth,
407 pitch, address, dp);
408 230
231 if (of_address_to_resource(np, index, &r))
232 return 0;
233 if ((r.start + offset + size) > r.end)
234 return 0;
235 return ioremap(r.start + offset, size);
409} 236}
410 237
411static void __init offb_init_fb(const char *name, const char *full_name, 238static void __init offb_init_fb(const char *name, const char *full_name,
@@ -413,7 +240,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
413 int pitch, unsigned long address, 240 int pitch, unsigned long address,
414 struct device_node *dp) 241 struct device_node *dp)
415{ 242{
416 unsigned long res_size = pitch * height * depth / 8; 243 unsigned long res_size = pitch * height * (depth + 7) / 8;
417 struct offb_par *par = &default_par; 244 struct offb_par *par = &default_par;
418 unsigned long res_start = address; 245 unsigned long res_start = address;
419 struct fb_fix_screeninfo *fix; 246 struct fb_fix_screeninfo *fix;
@@ -427,7 +254,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
427 printk(KERN_INFO 254 printk(KERN_INFO
428 "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", 255 "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
429 width, height, name, address, depth, pitch); 256 width, height, name, address, depth, pitch);
430 if (depth != 8 && depth != 16 && depth != 32) { 257 if (depth != 8 && depth != 15 && depth != 16 && depth != 32) {
431 printk(KERN_ERR "%s: can't use depth = %d\n", full_name, 258 printk(KERN_ERR "%s: can't use depth = %d\n", full_name,
432 depth); 259 depth);
433 release_mem_region(res_start, res_size); 260 release_mem_region(res_start, res_size);
@@ -462,48 +289,41 @@ static void __init offb_init_fb(const char *name, const char *full_name,
462 289
463 par->cmap_type = cmap_unknown; 290 par->cmap_type = cmap_unknown;
464 if (depth == 8) { 291 if (depth == 8) {
465
466 /* Palette hacks disabled for now */ 292 /* Palette hacks disabled for now */
467#if 0
468 if (dp && !strncmp(name, "ATY,Rage128", 11)) { 293 if (dp && !strncmp(name, "ATY,Rage128", 11)) {
469 unsigned long regbase = dp->addrs[2].address; 294 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
470 par->cmap_adr = ioremap(regbase, 0x1FFF); 295 if (par->cmap_adr)
471 par->cmap_type = cmap_r128; 296 par->cmap_type = cmap_r128;
472 } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12) 297 } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
473 || !strncmp(name, "ATY,RageM3p12A", 14))) { 298 || !strncmp(name, "ATY,RageM3p12A", 14))) {
474 unsigned long regbase = 299 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
475 dp->parent->addrs[2].address; 300 if (par->cmap_adr)
476 par->cmap_adr = ioremap(regbase, 0x1FFF); 301 par->cmap_type = cmap_M3A;
477 par->cmap_type = cmap_M3A;
478 } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) { 302 } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
479 unsigned long regbase = 303 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
480 dp->parent->addrs[2].address; 304 if (par->cmap_adr)
481 par->cmap_adr = ioremap(regbase, 0x1FFF); 305 par->cmap_type = cmap_M3B;
482 par->cmap_type = cmap_M3B;
483 } else if (dp && !strncmp(name, "ATY,Rage6", 9)) { 306 } else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
484 unsigned long regbase = dp->addrs[1].address; 307 par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
485 par->cmap_adr = ioremap(regbase, 0x1FFF); 308 if (par->cmap_adr)
486 par->cmap_type = cmap_radeon; 309 par->cmap_type = cmap_radeon;
487 } else if (!strncmp(name, "ATY,", 4)) { 310 } else if (!strncmp(name, "ATY,", 4)) {
488 unsigned long base = address & 0xff000000UL; 311 unsigned long base = address & 0xff000000UL;
489 par->cmap_adr = 312 par->cmap_adr =
490 ioremap(base + 0x7ff000, 0x1000) + 0xcc0; 313 ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
491 par->cmap_data = par->cmap_adr + 1; 314 par->cmap_data = par->cmap_adr + 1;
492 par->cmap_type = cmap_m64; 315 par->cmap_type = cmap_m64;
493 } else if (device_is_compatible(dp, "pci1014,b7")) { 316 } else if (dp && device_is_compatible(dp, "pci1014,b7")) {
494 unsigned long regbase = dp->addrs[0].address; 317 par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
495 par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); 318 if (par->cmap_adr)
496 par->cmap_type = cmap_gxt2000; 319 par->cmap_type = cmap_gxt2000;
497 } 320 }
498#endif 321 fix->visual = (par->cmap_type != cmap_unknown) ?
499 fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR 322 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
500 : FB_VISUAL_STATIC_PSEUDOCOLOR;
501 } else 323 } else
502 fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR 324 fix->visual = FB_VISUAL_TRUECOLOR;
503 : */ FB_VISUAL_TRUECOLOR;
504 325
505 var->xoffset = var->yoffset = 0; 326 var->xoffset = var->yoffset = 0;
506 var->bits_per_pixel = depth;
507 switch (depth) { 327 switch (depth) {
508 case 8: 328 case 8:
509 var->bits_per_pixel = 8; 329 var->bits_per_pixel = 8;
@@ -516,7 +336,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
516 var->transp.offset = 0; 336 var->transp.offset = 0;
517 var->transp.length = 0; 337 var->transp.length = 0;
518 break; 338 break;
519 case 16: /* RGB 555 */ 339 case 15: /* RGB 555 */
520 var->bits_per_pixel = 16; 340 var->bits_per_pixel = 16;
521 var->red.offset = 10; 341 var->red.offset = 10;
522 var->red.length = 5; 342 var->red.length = 5;
@@ -527,6 +347,17 @@ static void __init offb_init_fb(const char *name, const char *full_name,
527 var->transp.offset = 0; 347 var->transp.offset = 0;
528 var->transp.length = 0; 348 var->transp.length = 0;
529 break; 349 break;
350 case 16: /* RGB 565 */
351 var->bits_per_pixel = 16;
352 var->red.offset = 11;
353 var->red.length = 5;
354 var->green.offset = 5;
355 var->green.length = 6;
356 var->blue.offset = 0;
357 var->blue.length = 5;
358 var->transp.offset = 0;
359 var->transp.length = 0;
360 break;
530 case 32: /* RGB 888 */ 361 case 32: /* RGB 888 */
531 var->bits_per_pixel = 32; 362 var->bits_per_pixel = 32;
532 var->red.offset = 16; 363 var->red.offset = 16;
@@ -570,5 +401,139 @@ static void __init offb_init_fb(const char *name, const char *full_name,
570 info->node, full_name); 401 info->node, full_name);
571} 402}
572 403
404
405static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
406{
407 unsigned int len;
408 int i, width = 640, height = 480, depth = 8, pitch = 640;
409 unsigned int flags, rsize, addr_prop = 0;
410 unsigned long max_size = 0;
411 u64 rstart, address = OF_BAD_ADDR;
412 const u32 *pp, *addrp, *up;
413 u64 asize;
414
415 pp = get_property(dp, "linux,bootx-depth", &len);
416 if (pp == NULL)
417 pp = get_property(dp, "depth", &len);
418 if (pp && len == sizeof(u32))
419 depth = *pp;
420
421 pp = get_property(dp, "linux,bootx-width", &len);
422 if (pp == NULL)
423 pp = get_property(dp, "width", &len);
424 if (pp && len == sizeof(u32))
425 width = *pp;
426
427 pp = get_property(dp, "linux,bootx-height", &len);
428 if (pp == NULL)
429 pp = get_property(dp, "height", &len);
430 if (pp && len == sizeof(u32))
431 height = *pp;
432
433 pp = get_property(dp, "linux,bootx-linebytes", &len);
434 if (pp == NULL)
435 pp = get_property(dp, "linebytes", &len);
436 if (pp && len == sizeof(u32))
437 pitch = *pp;
438 else
439 pitch = width * ((depth + 7) / 8);
440
441 rsize = (unsigned long)pitch * (unsigned long)height;
442
443 /* Ok, now we try to figure out the address of the framebuffer.
444 *
445 * Unfortunately, Open Firmware doesn't provide a standard way to do
446 * so. All we can do is a dodgy heuristic that happens to work in
447 * practice. On most machines, the "address" property contains what
448 * we need, though not on Matrox cards found in IBM machines. What I've
449 * found that appears to give good results is to go through the PCI
450 * ranges and pick one that is both big enough and if possible encloses
451 * the "address" property. If none match, we pick the biggest
452 */
453 up = get_property(dp, "linux,bootx-addr", &len);
454 if (up == NULL)
455 up = get_property(dp, "address", &len);
456 if (up && len == sizeof(u32))
457 addr_prop = *up;
458
459 /* Hack for when BootX is passing us */
460 if (no_real_node)
461 goto skip_addr;
462
463 for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
464 != NULL; i++) {
465 int match_addrp = 0;
466
467 if (!(flags & IORESOURCE_MEM))
468 continue;
469 if (asize < rsize)
470 continue;
471 rstart = of_translate_address(dp, addrp);
472 if (rstart == OF_BAD_ADDR)
473 continue;
474 if (addr_prop && (rstart <= addr_prop) &&
475 ((rstart + asize) >= (addr_prop + rsize)))
476 match_addrp = 1;
477 if (match_addrp) {
478 address = addr_prop;
479 break;
480 }
481 if (rsize > max_size) {
482 max_size = rsize;
483 address = OF_BAD_ADDR;
484 }
485
486 if (address == OF_BAD_ADDR)
487 address = rstart;
488 }
489 skip_addr:
490 if (address == OF_BAD_ADDR && addr_prop)
491 address = (u64)addr_prop;
492 if (address != OF_BAD_ADDR) {
493 /* kludge for valkyrie */
494 if (strcmp(dp->name, "valkyrie") == 0)
495 address += 0x1000;
496 offb_init_fb(no_real_node ? "bootx" : dp->name,
497 no_real_node ? "display" : dp->full_name,
498 width, height, depth, pitch, address,
499 no_real_node ? dp : NULL);
500 }
501}
502
503static int __init offb_init(void)
504{
505 struct device_node *dp = NULL, *boot_disp = NULL;
506
507 if (fb_get_options("offb", NULL))
508 return -ENODEV;
509
510 /* Check if we have a MacOS display without a node spec */
511 if (get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) {
512 /* The old code tried to work out which node was the MacOS
513 * display based on the address. I'm dropping that since the
514 * lack of a node spec only happens with old BootX versions
515 * (users can update) and with this code, they'll still get
516 * a display (just not the palette hacks).
517 */
518 offb_init_nodriver(of_chosen, 1);
519 }
520
521 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
522 if (get_property(dp, "linux,opened", NULL) &&
523 get_property(dp, "linux,boot-display", NULL)) {
524 boot_disp = dp;
525 offb_init_nodriver(dp, 0);
526 }
527 }
528 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
529 if (get_property(dp, "linux,opened", NULL) &&
530 dp != boot_disp)
531 offb_init_nodriver(dp, 0);
532 }
533
534 return 0;
535}
536
537
573module_init(offb_init); 538module_init(offb_init);
574MODULE_LICENSE("GPL"); 539MODULE_LICENSE("GPL");
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 0d1957505359..56ac51d6a7f3 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -1,6 +1,6 @@
1/* p9100.c: P9100 frame buffer driver 1/* p9100.c: P9100 frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright 1999 Derrick J Brashear (shadow@dementia.org) 4 * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
5 * 5 *
6 * Driver layout based loosely on tgafb.c, see that file for credits. 6 * Driver layout based loosely on tgafb.c, see that file for credits.
@@ -17,8 +17,8 @@
17#include <linux/mm.h> 17#include <linux/mm.h>
18 18
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/sbus.h> 20#include <asm/prom.h>
21#include <asm/oplib.h> 21#include <asm/of_device.h>
22#include <asm/fbio.h> 22#include <asm/fbio.h>
23 23
24#include "sbuslib.h" 24#include "sbuslib.h"
@@ -72,60 +72,60 @@ static struct fb_ops p9100_ops = {
72 72
73struct p9100_regs { 73struct p9100_regs {
74 /* Registers for the system control */ 74 /* Registers for the system control */
75 volatile u32 sys_base; 75 u32 sys_base;
76 volatile u32 sys_config; 76 u32 sys_config;
77 volatile u32 sys_intr; 77 u32 sys_intr;
78 volatile u32 sys_int_ena; 78 u32 sys_int_ena;
79 volatile u32 sys_alt_rd; 79 u32 sys_alt_rd;
80 volatile u32 sys_alt_wr; 80 u32 sys_alt_wr;
81 volatile u32 sys_xxx[58]; 81 u32 sys_xxx[58];
82 82
83 /* Registers for the video control */ 83 /* Registers for the video control */
84 volatile u32 vid_base; 84 u32 vid_base;
85 volatile u32 vid_hcnt; 85 u32 vid_hcnt;
86 volatile u32 vid_htotal; 86 u32 vid_htotal;
87 volatile u32 vid_hsync_rise; 87 u32 vid_hsync_rise;
88 volatile u32 vid_hblank_rise; 88 u32 vid_hblank_rise;
89 volatile u32 vid_hblank_fall; 89 u32 vid_hblank_fall;
90 volatile u32 vid_hcnt_preload; 90 u32 vid_hcnt_preload;
91 volatile u32 vid_vcnt; 91 u32 vid_vcnt;
92 volatile u32 vid_vlen; 92 u32 vid_vlen;
93 volatile u32 vid_vsync_rise; 93 u32 vid_vsync_rise;
94 volatile u32 vid_vblank_rise; 94 u32 vid_vblank_rise;
95 volatile u32 vid_vblank_fall; 95 u32 vid_vblank_fall;
96 volatile u32 vid_vcnt_preload; 96 u32 vid_vcnt_preload;
97 volatile u32 vid_screenpaint_addr; 97 u32 vid_screenpaint_addr;
98 volatile u32 vid_screenpaint_timectl1; 98 u32 vid_screenpaint_timectl1;
99 volatile u32 vid_screenpaint_qsfcnt; 99 u32 vid_screenpaint_qsfcnt;
100 volatile u32 vid_screenpaint_timectl2; 100 u32 vid_screenpaint_timectl2;
101 volatile u32 vid_xxx[15]; 101 u32 vid_xxx[15];
102 102
103 /* Registers for the video control */ 103 /* Registers for the video control */
104 volatile u32 vram_base; 104 u32 vram_base;
105 volatile u32 vram_memcfg; 105 u32 vram_memcfg;
106 volatile u32 vram_refresh_pd; 106 u32 vram_refresh_pd;
107 volatile u32 vram_refresh_cnt; 107 u32 vram_refresh_cnt;
108 volatile u32 vram_raslo_max; 108 u32 vram_raslo_max;
109 volatile u32 vram_raslo_cur; 109 u32 vram_raslo_cur;
110 volatile u32 pwrup_cfg; 110 u32 pwrup_cfg;
111 volatile u32 vram_xxx[25]; 111 u32 vram_xxx[25];
112 112
113 /* Registers for IBM RGB528 Palette */ 113 /* Registers for IBM RGB528 Palette */
114 volatile u32 ramdac_cmap_wridx; 114 u32 ramdac_cmap_wridx;
115 volatile u32 ramdac_palette_data; 115 u32 ramdac_palette_data;
116 volatile u32 ramdac_pixel_mask; 116 u32 ramdac_pixel_mask;
117 volatile u32 ramdac_palette_rdaddr; 117 u32 ramdac_palette_rdaddr;
118 volatile u32 ramdac_idx_lo; 118 u32 ramdac_idx_lo;
119 volatile u32 ramdac_idx_hi; 119 u32 ramdac_idx_hi;
120 volatile u32 ramdac_idx_data; 120 u32 ramdac_idx_data;
121 volatile u32 ramdac_idx_ctl; 121 u32 ramdac_idx_ctl;
122 volatile u32 ramdac_xxx[1784]; 122 u32 ramdac_xxx[1784];
123}; 123};
124 124
125struct p9100_cmd_parameng { 125struct p9100_cmd_parameng {
126 volatile u32 parameng_status; 126 u32 parameng_status;
127 volatile u32 parameng_bltcmd; 127 u32 parameng_bltcmd;
128 volatile u32 parameng_quadcmd; 128 u32 parameng_quadcmd;
129}; 129};
130 130
131struct p9100_par { 131struct p9100_par {
@@ -136,9 +136,8 @@ struct p9100_par {
136#define P9100_FLAG_BLANKED 0x00000001 136#define P9100_FLAG_BLANKED 0x00000001
137 137
138 unsigned long physbase; 138 unsigned long physbase;
139 unsigned long which_io;
139 unsigned long fbsize; 140 unsigned long fbsize;
140
141 struct sbus_dev *sdev;
142}; 141};
143 142
144/** 143/**
@@ -227,8 +226,7 @@ static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
227 226
228 return sbusfb_mmap_helper(p9100_mmap_map, 227 return sbusfb_mmap_helper(p9100_mmap_map,
229 par->physbase, par->fbsize, 228 par->physbase, par->fbsize,
230 par->sdev->reg_addrs[0].which_io, 229 par->which_io, vma);
231 vma);
232} 230}
233 231
234static int p9100_ioctl(struct fb_info *info, unsigned int cmd, 232static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
@@ -245,12 +243,9 @@ static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
245 * Initialisation 243 * Initialisation
246 */ 244 */
247 245
248static void 246static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
249p9100_init_fix(struct fb_info *info, int linebytes)
250{ 247{
251 struct p9100_par *par = (struct p9100_par *)info->par; 248 strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
252
253 strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
254 249
255 info->fix.type = FB_TYPE_PACKED_PIXELS; 250 info->fix.type = FB_TYPE_PACKED_PIXELS;
256 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 251 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -263,121 +258,137 @@ p9100_init_fix(struct fb_info *info, int linebytes)
263struct all_info { 258struct all_info {
264 struct fb_info info; 259 struct fb_info info;
265 struct p9100_par par; 260 struct p9100_par par;
266 struct list_head list;
267}; 261};
268static LIST_HEAD(p9100_list);
269 262
270static void p9100_init_one(struct sbus_dev *sdev) 263static int __devinit p9100_init_one(struct of_device *op)
271{ 264{
265 struct device_node *dp = op->node;
272 struct all_info *all; 266 struct all_info *all;
273 int linebytes; 267 int linebytes, err;
274
275 all = kmalloc(sizeof(*all), GFP_KERNEL);
276 if (!all) {
277 printk(KERN_ERR "p9100: Cannot allocate memory.\n");
278 return;
279 }
280 memset(all, 0, sizeof(*all));
281 268
282 INIT_LIST_HEAD(&all->list); 269 all = kzalloc(sizeof(*all), GFP_KERNEL);
270 if (!all)
271 return -ENOMEM;
283 272
284 spin_lock_init(&all->par.lock); 273 spin_lock_init(&all->par.lock);
285 all->par.sdev = sdev;
286 274
287 /* This is the framebuffer and the only resource apps can mmap. */ 275 /* This is the framebuffer and the only resource apps can mmap. */
288 all->par.physbase = sdev->reg_addrs[2].phys_addr; 276 all->par.physbase = op->resource[2].start;
277 all->par.which_io = op->resource[2].flags & IORESOURCE_BITS;
289 278
290 sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 279 sbusfb_fill_var(&all->info.var, dp->node, 8);
291 all->info.var.red.length = 8; 280 all->info.var.red.length = 8;
292 all->info.var.green.length = 8; 281 all->info.var.green.length = 8;
293 all->info.var.blue.length = 8; 282 all->info.var.blue.length = 8;
294 283
295 linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 284 linebytes = of_getintprop_default(dp, "linebytes",
296 all->info.var.xres); 285 all->info.var.xres);
297 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 286 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
298 287
299 all->par.regs = sbus_ioremap(&sdev->resource[0], 0, 288 all->par.regs = of_ioremap(&op->resource[0], 0,
300 sizeof(struct p9100_regs), "p9100 regs"); 289 sizeof(struct p9100_regs), "p9100 regs");
290 if (!all->par.regs) {
291 kfree(all);
292 return -ENOMEM;
293 }
301 294
302 all->info.flags = FBINFO_DEFAULT; 295 all->info.flags = FBINFO_DEFAULT;
303 all->info.fbops = &p9100_ops; 296 all->info.fbops = &p9100_ops;
304#ifdef CONFIG_SPARC32 297 all->info.screen_base = of_ioremap(&op->resource[2], 0,
305 all->info.screen_base = (char __iomem *) 298 all->par.fbsize, "p9100 ram");
306 prom_getintdefault(sdev->prom_node, "address", 0); 299 if (!all->info.screen_base) {
307#endif 300 of_iounmap(all->par.regs, sizeof(struct p9100_regs));
308 if (!all->info.screen_base) 301 kfree(all);
309 all->info.screen_base = sbus_ioremap(&sdev->resource[2], 0, 302 return -ENOMEM;
310 all->par.fbsize, "p9100 ram"); 303 }
311 all->info.par = &all->par; 304 all->info.par = &all->par;
312 305
313 p9100_blank(0, &all->info); 306 p9100_blank(0, &all->info);
314 307
315 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 308 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
316 printk(KERN_ERR "p9100: Could not allocate color map.\n"); 309 of_iounmap(all->par.regs, sizeof(struct p9100_regs));
310 of_iounmap(all->info.screen_base, all->par.fbsize);
317 kfree(all); 311 kfree(all);
318 return; 312 return -ENOMEM;
319 } 313 }
320 314
321 p9100_init_fix(&all->info, linebytes); 315 p9100_init_fix(&all->info, linebytes, dp);
322 316
323 if (register_framebuffer(&all->info) < 0) { 317 err = register_framebuffer(&all->info);
324 printk(KERN_ERR "p9100: Could not register framebuffer.\n"); 318 if (err < 0) {
325 fb_dealloc_cmap(&all->info.cmap); 319 fb_dealloc_cmap(&all->info.cmap);
320 of_iounmap(all->par.regs, sizeof(struct p9100_regs));
321 of_iounmap(all->info.screen_base, all->par.fbsize);
326 kfree(all); 322 kfree(all);
327 return; 323 return err;
328 } 324 }
329 fb_set_cmap(&all->info.cmap, &all->info); 325 fb_set_cmap(&all->info.cmap, &all->info);
330 326
331 list_add(&all->list, &p9100_list); 327 dev_set_drvdata(&op->dev, all);
328
329 printk("%s: p9100 at %lx:%lx\n",
330 dp->full_name,
331 all->par.which_io, all->par.physbase);
332 332
333 printk("p9100: %s at %lx:%lx\n", 333 return 0;
334 sdev->prom_name,
335 (long) sdev->reg_addrs[0].which_io,
336 (long) sdev->reg_addrs[0].phys_addr);
337} 334}
338 335
339int __init p9100_init(void) 336static int __devinit p9100_probe(struct of_device *dev, const struct of_device_id *match)
340{ 337{
341 struct sbus_bus *sbus; 338 struct of_device *op = to_of_device(&dev->dev);
342 struct sbus_dev *sdev;
343 339
344 if (fb_get_options("p9100fb", NULL)) 340 return p9100_init_one(op);
345 return -ENODEV; 341}
346 342
347 for_all_sbusdev(sdev, sbus) { 343static int __devexit p9100_remove(struct of_device *dev)
348 if (!strcmp(sdev->prom_name, "p9100")) 344{
349 p9100_init_one(sdev); 345 struct all_info *all = dev_get_drvdata(&dev->dev);
350 } 346
347 unregister_framebuffer(&all->info);
348 fb_dealloc_cmap(&all->info.cmap);
349
350 of_iounmap(all->par.regs, sizeof(struct p9100_regs));
351 of_iounmap(all->info.screen_base, all->par.fbsize);
352
353 kfree(all);
354
355 dev_set_drvdata(&dev->dev, NULL);
351 356
352 return 0; 357 return 0;
353} 358}
354 359
355void __exit p9100_exit(void) 360static struct of_device_id p9100_match[] = {
356{ 361 {
357 struct list_head *pos, *tmp; 362 .name = "p9100",
363 },
364 {},
365};
366MODULE_DEVICE_TABLE(of, p9100_match);
358 367
359 list_for_each_safe(pos, tmp, &p9100_list) { 368static struct of_platform_driver p9100_driver = {
360 struct all_info *all = list_entry(pos, typeof(*all), list); 369 .name = "p9100",
370 .match_table = p9100_match,
371 .probe = p9100_probe,
372 .remove = __devexit_p(p9100_remove),
373};
361 374
362 unregister_framebuffer(&all->info); 375static int __init p9100_init(void)
363 fb_dealloc_cmap(&all->info.cmap); 376{
364 kfree(all); 377 if (fb_get_options("p9100fb", NULL))
365 } 378 return -ENODEV;
379
380 return of_register_driver(&p9100_driver, &of_bus_type);
366} 381}
367 382
368int __init 383static void __exit p9100_exit(void)
369p9100_setup(char *arg)
370{ 384{
371 /* No cmdline options yet... */ 385 of_unregister_driver(&p9100_driver);
372 return 0;
373} 386}
374 387
375module_init(p9100_init); 388module_init(p9100_init);
376
377#ifdef MODULE
378module_exit(p9100_exit); 389module_exit(p9100_exit);
379#endif
380 390
381MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets"); 391MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets");
382MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 392MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
393MODULE_VERSION("2.0");
383MODULE_LICENSE("GPL"); 394MODULE_LICENSE("GPL");
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 335e37465559..983be3ec2345 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -17,13 +17,11 @@
17 * more details. 17 * more details.
18 */ 18 */
19 19
20#include <linux/config.h>
21#include <linux/module.h> 20#include <linux/module.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/errno.h> 22#include <linux/errno.h>
24#include <linux/string.h> 23#include <linux/string.h>
25#include <linux/mm.h> 24#include <linux/mm.h>
26#include <linux/tty.h>
27#include <linux/slab.h> 25#include <linux/slab.h>
28#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
29#include <linux/delay.h> 27#include <linux/delay.h>
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 4e963930b50a..a560a2223825 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -27,14 +27,12 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
34#include <linux/errno.h> 33#include <linux/errno.h>
35#include <linux/string.h> 34#include <linux/string.h>
36#include <linux/mm.h> 35#include <linux/mm.h>
37#include <linux/tty.h>
38#include <linux/slab.h> 36#include <linux/slab.h>
39#include <linux/delay.h> 37#include <linux/delay.h>
40#include <linux/fb.h> 38#include <linux/fb.h>
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 52c18a35fb41..1d81ef47efd3 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -52,13 +52,11 @@
52 * Wed Feb 21 14:47:06 CET 2001, v 1.0.0: First working version 52 * Wed Feb 21 14:47:06 CET 2001, v 1.0.0: First working version
53 */ 53 */
54 54
55#include <linux/config.h>
56#include <linux/module.h> 55#include <linux/module.h>
57#include <linux/kernel.h> 56#include <linux/kernel.h>
58#include <linux/errno.h> 57#include <linux/errno.h>
59#include <linux/string.h> 58#include <linux/string.h>
60#include <linux/mm.h> 59#include <linux/mm.h>
61#include <linux/tty.h>
62#include <linux/slab.h> 60#include <linux/slab.h>
63#include <linux/vmalloc.h> 61#include <linux/vmalloc.h>
64#include <linux/delay.h> 62#include <linux/delay.h>
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c
index d92f352211ef..68ca3cc40770 100644
--- a/drivers/video/pmag-aa-fb.c
+++ b/drivers/video/pmag-aa-fb.c
@@ -29,7 +29,6 @@
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/tty.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
35#include <linux/init.h> 34#include <linux/init.h>
diff --git a/drivers/video/pnx4008/Makefile b/drivers/video/pnx4008/Makefile
new file mode 100644
index 000000000000..636aaccf01fd
--- /dev/null
+++ b/drivers/video/pnx4008/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the new PNX4008 framebuffer device driver
3#
4
5obj-$(CONFIG_FB_PNX4008_DUM) += sdum.o
6obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnxrgbfb.o
7
diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h
new file mode 100644
index 000000000000..d80a614d89ed
--- /dev/null
+++ b/drivers/video/pnx4008/dum.h
@@ -0,0 +1,211 @@
1/*
2 * linux/drivers/video/pnx4008/dum.h
3 *
4 * Internal header for SDUM
5 *
6 * 2005 (c) Koninklijke Philips N.V. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12#ifndef __PNX008_DUM_H__
13#define __PNX008_DUM_H__
14
15#include <asm/arch/platform.h>
16
17#define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE)
18#define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE)
19
20/* DUM CFG ADDRESSES */
21#define DUM_CH_BASE_ADR (PNX4008_DUMCONF_VA_BASE + 0x00)
22#define DUM_CH_MIN_ADR (PNX4008_DUMCONF_VA_BASE + 0x00)
23#define DUM_CH_MAX_ADR (PNX4008_DUMCONF_VA_BASE + 0x04)
24#define DUM_CH_CONF_ADR (PNX4008_DUMCONF_VA_BASE + 0x08)
25#define DUM_CH_STAT_ADR (PNX4008_DUMCONF_VA_BASE + 0x0C)
26#define DUM_CH_CTRL_ADR (PNX4008_DUMCONF_VA_BASE + 0x10)
27
28#define CH_MARG (0x100 / sizeof(u32))
29#define DUM_CH_MIN(i) (*((volatile u32 *)DUM_CH_MIN_ADR + (i) * CH_MARG))
30#define DUM_CH_MAX(i) (*((volatile u32 *)DUM_CH_MAX_ADR + (i) * CH_MARG))
31#define DUM_CH_CONF(i) (*((volatile u32 *)DUM_CH_CONF_ADR + (i) * CH_MARG))
32#define DUM_CH_STAT(i) (*((volatile u32 *)DUM_CH_STAT_ADR + (i) * CH_MARG))
33#define DUM_CH_CTRL(i) (*((volatile u32 *)DUM_CH_CTRL_ADR + (i) * CH_MARG))
34
35#define DUM_CONF_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x00)
36#define DUM_CTRL_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x04)
37#define DUM_STAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x08)
38#define DUM_DECODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x0C)
39#define DUM_COM_BASE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x10)
40#define DUM_SYNC_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x14)
41#define DUM_CLK_DIV_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x18)
42#define DUM_DIRTY_LOW_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x20)
43#define DUM_DIRTY_HIGH_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x24)
44#define DUM_FORMAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x28)
45#define DUM_WTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x30)
46#define DUM_RTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x34)
47#define DUM_WTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x38)
48#define DUM_RTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x3C)
49#define DUM_TCFG_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x40)
50#define DUM_OUTP_FORMAT1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x44)
51#define DUM_OUTP_FORMAT2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x48)
52#define DUM_SYNC_MODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x4C)
53#define DUM_SYNC_OUT_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x50)
54
55#define DUM_CONF (*(volatile u32 *)(DUM_CONF_ADR))
56#define DUM_CTRL (*(volatile u32 *)(DUM_CTRL_ADR))
57#define DUM_STAT (*(volatile u32 *)(DUM_STAT_ADR))
58#define DUM_DECODE (*(volatile u32 *)(DUM_DECODE_ADR))
59#define DUM_COM_BASE (*(volatile u32 *)(DUM_COM_BASE_ADR))
60#define DUM_SYNC_C (*(volatile u32 *)(DUM_SYNC_C_ADR))
61#define DUM_CLK_DIV (*(volatile u32 *)(DUM_CLK_DIV_ADR))
62#define DUM_DIRTY_LOW (*(volatile u32 *)(DUM_DIRTY_LOW_ADR))
63#define DUM_DIRTY_HIGH (*(volatile u32 *)(DUM_DIRTY_HIGH_ADR))
64#define DUM_FORMAT (*(volatile u32 *)(DUM_FORMAT_ADR))
65#define DUM_WTCFG1 (*(volatile u32 *)(DUM_WTCFG1_ADR))
66#define DUM_RTCFG1 (*(volatile u32 *)(DUM_RTCFG1_ADR))
67#define DUM_WTCFG2 (*(volatile u32 *)(DUM_WTCFG2_ADR))
68#define DUM_RTCFG2 (*(volatile u32 *)(DUM_RTCFG2_ADR))
69#define DUM_TCFG (*(volatile u32 *)(DUM_TCFG_ADR))
70#define DUM_OUTP_FORMAT1 (*(volatile u32 *)(DUM_OUTP_FORMAT1_ADR))
71#define DUM_OUTP_FORMAT2 (*(volatile u32 *)(DUM_OUTP_FORMAT2_ADR))
72#define DUM_SYNC_MODE (*(volatile u32 *)(DUM_SYNC_MODE_ADR))
73#define DUM_SYNC_OUT_C (*(volatile u32 *)(DUM_SYNC_OUT_C_ADR))
74
75/* DUM SLAVE ADDRESSES */
76#define DUM_SLAVE_WRITE_ADR (PNX4008_DUM_MAINCFG_BASE + 0x0000000)
77#define DUM_SLAVE_READ1_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000000)
78#define DUM_SLAVE_READ1_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000004)
79#define DUM_SLAVE_READ2_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000008)
80#define DUM_SLAVE_READ2_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x100000C)
81
82#define DUM_SLAVE_WRITE_W ((volatile u32 *)(DUM_SLAVE_WRITE_ADR))
83#define DUM_SLAVE_WRITE_HW ((volatile u16 *)(DUM_SLAVE_WRITE_ADR))
84#define DUM_SLAVE_READ1_I ((volatile u8 *)(DUM_SLAVE_READ1_I_ADR))
85#define DUM_SLAVE_READ1_R ((volatile u16 *)(DUM_SLAVE_READ1_R_ADR))
86#define DUM_SLAVE_READ2_I ((volatile u8 *)(DUM_SLAVE_READ2_I_ADR))
87#define DUM_SLAVE_READ2_R ((volatile u16 *)(DUM_SLAVE_READ2_R_ADR))
88
89/* Sony display register addresses */
90#define DISP_0_REG (0x00)
91#define DISP_1_REG (0x01)
92#define DISP_CAL_REG (0x20)
93#define DISP_ID_REG (0x2A)
94#define DISP_XMIN_L_REG (0x30)
95#define DISP_XMIN_H_REG (0x31)
96#define DISP_YMIN_REG (0x32)
97#define DISP_XMAX_L_REG (0x34)
98#define DISP_XMAX_H_REG (0x35)
99#define DISP_YMAX_REG (0x36)
100#define DISP_SYNC_EN_REG (0x38)
101#define DISP_SYNC_RISE_L_REG (0x3C)
102#define DISP_SYNC_RISE_H_REG (0x3D)
103#define DISP_SYNC_FALL_L_REG (0x3E)
104#define DISP_SYNC_FALL_H_REG (0x3F)
105#define DISP_PIXEL_REG (0x0B)
106#define DISP_DUMMY1_REG (0x28)
107#define DISP_DUMMY2_REG (0x29)
108#define DISP_TIMING_REG (0x98)
109#define DISP_DUMP_REG (0x99)
110
111/* Sony display constants */
112#define SONY_ID1 (0x22)
113#define SONY_ID2 (0x23)
114
115/* Philips display register addresses */
116#define PH_DISP_ORIENT_REG (0x003)
117#define PH_DISP_YPOINT_REG (0x200)
118#define PH_DISP_XPOINT_REG (0x201)
119#define PH_DISP_PIXEL_REG (0x202)
120#define PH_DISP_YMIN_REG (0x406)
121#define PH_DISP_YMAX_REG (0x407)
122#define PH_DISP_XMIN_REG (0x408)
123#define PH_DISP_XMAX_REG (0x409)
124
125/* Misc constants */
126#define NO_VALID_DISPLAY_FOUND (0)
127#define DISPLAY2_IS_NOT_CONNECTED (0)
128
129/* register values */
130#define V_BAC_ENABLE (BIT(0))
131#define V_BAC_DISABLE_IDLE (BIT(1))
132#define V_BAC_DISABLE_TRIG (BIT(2))
133#define V_DUM_RESET (BIT(3))
134#define V_MUX_RESET (BIT(4))
135#define BAC_ENABLED (BIT(0))
136#define BAC_DISABLED 0
137
138/* Sony LCD commands */
139#define V_LCD_STANDBY_OFF ((BIT(25)) | (0 << 16) | DISP_0_REG)
140#define V_LCD_USE_9BIT_BUS ((BIT(25)) | (2 << 16) | DISP_1_REG)
141#define V_LCD_SYNC_RISE_L ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_L_REG)
142#define V_LCD_SYNC_RISE_H ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_H_REG)
143#define V_LCD_SYNC_FALL_L ((BIT(25)) | (160 << 16) | DISP_SYNC_FALL_L_REG)
144#define V_LCD_SYNC_FALL_H ((BIT(25)) | (0 << 16) | DISP_SYNC_FALL_H_REG)
145#define V_LCD_SYNC_ENABLE ((BIT(25)) | (128 << 16) | DISP_SYNC_EN_REG)
146#define V_LCD_DISPLAY_ON ((BIT(25)) | (64 << 16) | DISP_0_REG)
147
148enum {
149 PAD_NONE,
150 PAD_512,
151 PAD_1024
152};
153
154enum {
155 RGB888,
156 RGB666,
157 RGB565,
158 BGR565,
159 ARGB1555,
160 ABGR1555,
161 ARGB4444,
162 ABGR4444
163};
164
165struct dum_setup {
166 int sync_neg_edge;
167 int round_robin;
168 int mux_int;
169 int synced_dirty_flag_int;
170 int dirty_flag_int;
171 int error_int;
172 int pf_empty_int;
173 int sf_empty_int;
174 int bac_dis_int;
175 u32 dirty_base_adr;
176 u32 command_base_adr;
177 u32 sync_clk_div;
178 int sync_output;
179 u32 sync_restart_val;
180 u32 set_sync_high;
181 u32 set_sync_low;
182};
183
184struct dum_ch_setup {
185 int disp_no;
186 u32 xmin;
187 u32 ymin;
188 u32 xmax;
189 u32 ymax;
190 int xmirror;
191 int ymirror;
192 int rotate;
193 u32 minadr;
194 u32 maxadr;
195 u32 dirtybuffer;
196 int pad;
197 int format;
198 int hwdirty;
199 int slave_trans;
200};
201
202struct disp_window {
203 u32 xmin_l;
204 u32 xmin_h;
205 u32 ymin;
206 u32 xmax_l;
207 u32 xmax_h;
208 u32 ymax;
209};
210
211#endif /* #ifndef __PNX008_DUM_H__ */
diff --git a/drivers/video/pnx4008/fbcommon.h b/drivers/video/pnx4008/fbcommon.h
new file mode 100644
index 000000000000..4ebc87dafafb
--- /dev/null
+++ b/drivers/video/pnx4008/fbcommon.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2005 Philips Semiconductors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
18*/
19
20#define QCIF_W (176)
21#define QCIF_H (144)
22
23#define CIF_W (352)
24#define CIF_H (288)
25
26#define LCD_X_RES 208
27#define LCD_Y_RES 320
28#define LCD_X_PAD 256
29#define LCD_BBP 4 /* Bytes Per Pixel */
30
31#define DISP_MAX_X_SIZE (320)
32#define DISP_MAX_Y_SIZE (208)
33
34#define RETURNVAL_BASE (0x400)
35
36enum fb_ioctl_returntype {
37 ENORESOURCESLEFT = RETURNVAL_BASE,
38 ERESOURCESNOTFREED,
39 EPROCNOTOWNER,
40 EFBNOTOWNER,
41 ECOPYFAILED,
42 EIOREMAPFAILED,
43};
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
new file mode 100644
index 000000000000..7d9453c91a42
--- /dev/null
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -0,0 +1,213 @@
1/*
2 * drivers/video/pnx4008/pnxrgbfb.c
3 *
4 * PNX4008's framebuffer support
5 *
6 * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
7 * Based on Philips Semiconductors's code
8 *
9 * Copyrght (c) 2005 MontaVista Software, Inc.
10 * Copyright (c) 2005 Philips Semiconductors
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/errno.h>
19#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/slab.h>
22#include <linux/vmalloc.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <linux/fb.h>
26#include <linux/init.h>
27#include <linux/platform_device.h>
28
29#include <asm/uaccess.h>
30#include "sdum.h"
31#include "fbcommon.h"
32
33static u32 colreg[16];
34
35static struct fb_var_screeninfo rgbfb_var __initdata = {
36 .xres = LCD_X_RES,
37 .yres = LCD_Y_RES,
38 .xres_virtual = LCD_X_RES,
39 .yres_virtual = LCD_Y_RES,
40 .bits_per_pixel = 32,
41 .red.offset = 16,
42 .red.length = 8,
43 .green.offset = 8,
44 .green.length = 8,
45 .blue.offset = 0,
46 .blue.length = 8,
47 .left_margin = 0,
48 .right_margin = 0,
49 .upper_margin = 0,
50 .lower_margin = 0,
51 .vmode = FB_VMODE_NONINTERLACED,
52};
53static struct fb_fix_screeninfo rgbfb_fix __initdata = {
54 .id = "RGBFB",
55 .line_length = LCD_X_RES * LCD_BBP,
56 .type = FB_TYPE_PACKED_PIXELS,
57 .visual = FB_VISUAL_TRUECOLOR,
58 .xpanstep = 0,
59 .ypanstep = 0,
60 .ywrapstep = 0,
61 .accel = FB_ACCEL_NONE,
62};
63
64static int channel_owned;
65
66static int no_cursor(struct fb_info *info, struct fb_cursor *cursor)
67{
68 return 0;
69}
70
71static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
72 u_int transp, struct fb_info *info)
73{
74 if (regno > 15)
75 return 1;
76
77 colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) |
78 ((blue & 0xff00) >> 8);
79 return 0;
80}
81
82static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
83{
84 return pnx4008_sdum_mmap(info, vma, NULL);
85}
86
87static struct fb_ops rgbfb_ops = {
88 .fb_mmap = rgbfb_mmap,
89 .fb_setcolreg = rgbfb_setcolreg,
90 .fb_fillrect = cfb_fillrect,
91 .fb_copyarea = cfb_copyarea,
92 .fb_imageblit = cfb_imageblit,
93};
94
95static int rgbfb_remove(struct platform_device *pdev)
96{
97 struct fb_info *info = platform_get_drvdata(pdev);
98
99 if (info) {
100 unregister_framebuffer(info);
101 fb_dealloc_cmap(&info->cmap);
102 framebuffer_release(info);
103 platform_set_drvdata(pdev, NULL);
104 kfree(info);
105 }
106
107 pnx4008_free_dum_channel(channel_owned, pdev->id);
108 pnx4008_set_dum_exit_notification(pdev->id);
109
110 return 0;
111}
112
113static int __devinit rgbfb_probe(struct platform_device *pdev)
114{
115 struct fb_info *info;
116 struct dumchannel_uf chan_uf;
117 int ret;
118 char *option;
119
120 info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
121 if (!info) {
122 ret = -ENOMEM;
123 goto err;
124 }
125
126 pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base,
127 (dma_addr_t *) &rgbfb_fix.smem_start,
128 &rgbfb_fix.smem_len);
129
130 if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0)
131 goto err0;
132 else {
133 channel_owned = ret;
134 chan_uf.channelnr = channel_owned;
135 chan_uf.dirty = (u32 *) NULL;
136 chan_uf.source = (u32 *) rgbfb_fix.smem_start;
137 chan_uf.x_offset = 0;
138 chan_uf.y_offset = 0;
139 chan_uf.width = LCD_X_RES;
140 chan_uf.height = LCD_Y_RES;
141
142 if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0)
143 goto err1;
144
145 if ((ret =
146 pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON,
147 pdev->id)) < 0)
148 goto err1;
149
150 if ((ret =
151 pnx4008_set_dum_channel_dirty_detect(channel_owned,
152 CONF_DIRTYDETECTION_ON,
153 pdev->id)) < 0)
154 goto err1;
155 }
156
157 if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor"))
158 rgbfb_ops.fb_cursor = no_cursor;
159
160 info->node = -1;
161 info->flags = FBINFO_FLAG_DEFAULT;
162 info->fbops = &rgbfb_ops;
163 info->fix = rgbfb_fix;
164 info->var = rgbfb_var;
165 info->screen_size = rgbfb_fix.smem_len;
166 info->pseudo_palette = info->par;
167 info->par = NULL;
168
169 ret = fb_alloc_cmap(&info->cmap, 256, 0);
170 if (ret < 0)
171 goto err2;
172
173 ret = register_framebuffer(info);
174 if (ret < 0)
175 goto err3;
176 platform_set_drvdata(pdev, info);
177
178 return 0;
179
180err3:
181 fb_dealloc_cmap(&info->cmap);
182err2:
183 framebuffer_release(info);
184err1:
185 pnx4008_free_dum_channel(channel_owned, pdev->id);
186err0:
187 kfree(info);
188err:
189 return ret;
190}
191
192static struct platform_driver rgbfb_driver = {
193 .driver = {
194 .name = "rgbfb",
195 },
196 .probe = rgbfb_probe,
197 .remove = rgbfb_remove,
198};
199
200static int __init rgbfb_init(void)
201{
202 return platform_driver_register(&rgbfb_driver);
203}
204
205static void __exit rgbfb_exit(void)
206{
207 platform_driver_unregister(&rgbfb_driver);
208}
209
210module_init(rgbfb_init);
211module_exit(rgbfb_exit);
212
213MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
new file mode 100644
index 000000000000..51f0ecc2a511
--- /dev/null
+++ b/drivers/video/pnx4008/sdum.c
@@ -0,0 +1,872 @@
1/*
2 * drivers/video/pnx4008/sdum.c
3 *
4 * Display Update Master support
5 *
6 * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
7 * Vitaly Wool <vitalywool@gmail.com>
8 * Based on Philips Semiconductors's code
9 *
10 * Copyrght (c) 2005-2006 MontaVista Software, Inc.
11 * Copyright (c) 2005 Philips Semiconductors
12 * This file is licensed under the terms of the GNU General Public License
13 * version 2. This program is licensed "as is" without any warranty of any
14 * kind, whether express or implied.
15 */
16
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/string.h>
21#include <linux/mm.h>
22#include <linux/tty.h>
23#include <linux/slab.h>
24#include <linux/vmalloc.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/platform_device.h>
28#include <linux/fb.h>
29#include <linux/init.h>
30#include <linux/dma-mapping.h>
31#include <linux/clk.h>
32#include <asm/uaccess.h>
33#include <asm/arch/gpio.h>
34
35#include "sdum.h"
36#include "fbcommon.h"
37#include "dum.h"
38
39/* Framebuffers we have */
40
41static struct pnx4008_fb_addr {
42 int fb_type;
43 long addr_offset;
44 long fb_length;
45} fb_addr[] = {
46 [0] = {
47 FB_TYPE_YUV, 0, 0xB0000
48 },
49 [1] = {
50 FB_TYPE_RGB, 0xB0000, 0x50000
51 },
52};
53
54static struct dum_data {
55 u32 lcd_phys_start;
56 u32 lcd_virt_start;
57 u32 slave_phys_base;
58 u32 *slave_virt_base;
59 int fb_owning_channel[MAX_DUM_CHANNELS];
60 struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS];
61} dum_data;
62
63/* Different local helper functions */
64
65static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup)
66{
67 return (ch_setup->xmax - ch_setup->xmin + 1);
68}
69
70static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup)
71{
72 return (ch_setup->ymax - ch_setup->ymin + 1);
73}
74
75static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup)
76{
77 return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup));
78}
79
80static u32 nof_bytes(struct dum_ch_setup *ch_setup)
81{
82 u32 r = nof_pixels_dxy(ch_setup);
83 switch (ch_setup->format) {
84 case RGB888:
85 case RGB666:
86 r *= 4;
87 break;
88
89 default:
90 r *= 2;
91 break;
92 }
93 return r;
94}
95
96static u32 build_command(int disp_no, u32 reg, u32 val)
97{
98 return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) |
99 (reg << 0));
100}
101
102static u32 build_double_index(int disp_no, u32 val)
103{
104 return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0));
105}
106
107static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw)
108{
109 dw->ymin = ch_setup->ymin;
110 dw->ymax = ch_setup->ymax;
111 dw->xmin_l = ch_setup->xmin & 0xFF;
112 dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8;
113 dw->xmax_l = ch_setup->xmax & 0xFF;
114 dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8;
115}
116
117static int put_channel(struct dumchannel chan)
118{
119 int i = chan.channelnr;
120
121 if (i < 0 || i > MAX_DUM_CHANNELS)
122 return -EINVAL;
123 else {
124 DUM_CH_MIN(i) = chan.dum_ch_min;
125 DUM_CH_MAX(i) = chan.dum_ch_max;
126 DUM_CH_CONF(i) = chan.dum_ch_conf;
127 DUM_CH_CTRL(i) = chan.dum_ch_ctrl;
128 }
129
130 return 0;
131}
132
133static void clear_channel(int channr)
134{
135 struct dumchannel chan;
136
137 chan.channelnr = channr;
138 chan.dum_ch_min = 0;
139 chan.dum_ch_max = 0;
140 chan.dum_ch_conf = 0;
141 chan.dum_ch_ctrl = 0;
142
143 put_channel(chan);
144}
145
146static int put_cmd_string(struct cmdstring cmds)
147{
148 u16 *cmd_str_virtaddr;
149 u32 *cmd_ptr0_virtaddr;
150 u32 cmd_str_physaddr;
151
152 int i = cmds.channelnr;
153
154 if (i < 0 || i > MAX_DUM_CHANNELS)
155 return -EINVAL;
156 else if ((cmd_ptr0_virtaddr =
157 (int *)ioremap_nocache(DUM_COM_BASE,
158 sizeof(int) * MAX_DUM_CHANNELS)) ==
159 NULL)
160 return -EIOREMAPFAILED;
161 else {
162 cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]);
163 if ((cmd_str_virtaddr =
164 (u16 *) ioremap_nocache(cmd_str_physaddr,
165 sizeof(cmds))) == NULL) {
166 iounmap(cmd_ptr0_virtaddr);
167 return -EIOREMAPFAILED;
168 } else {
169 int t;
170 for (t = 0; t < 8; t++)
171 iowrite16(*((u16 *)&cmds.prestringlen + t),
172 cmd_str_virtaddr + t);
173
174 for (t = 0; t < cmds.prestringlen / 2; t++)
175 iowrite16(*((u16 *)&cmds.precmd + t),
176 cmd_str_virtaddr + t + 8);
177
178 for (t = 0; t < cmds.poststringlen / 2; t++)
179 iowrite16(*((u16 *)&cmds.postcmd + t),
180 cmd_str_virtaddr + t + 8 +
181 cmds.prestringlen / 2);
182
183 iounmap(cmd_ptr0_virtaddr);
184 iounmap(cmd_str_virtaddr);
185 }
186 }
187
188 return 0;
189}
190
191static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup)
192{
193 struct cmdstring cmds_c;
194 struct cmdstring *cmds = &cmds_c;
195 struct disp_window dw;
196 int standard;
197 u32 orientation = 0;
198 struct dumchannel chan = { 0 };
199 int ret;
200
201 if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) {
202 standard = 0;
203
204 orientation = BIT(1); /* always set 9-bit-bus */
205 if (ch_setup->xmirror)
206 orientation |= BIT(4);
207 if (ch_setup->ymirror)
208 orientation |= BIT(3);
209 if (ch_setup->rotate)
210 orientation |= BIT(0);
211 } else
212 standard = 1;
213
214 cmds->channelnr = ch_no;
215
216 /* build command string header */
217 if (standard) {
218 cmds->prestringlen = 32;
219 cmds->poststringlen = 0;
220 } else {
221 cmds->prestringlen = 48;
222 cmds->poststringlen = 16;
223 }
224
225 cmds->format =
226 (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format));
227 cmds->reserved = 0x0;
228 cmds->startaddr_low = (ch_setup->minadr & 0xFFFF);
229 cmds->startaddr_high = (ch_setup->minadr >> 16);
230
231 if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0)
232 && (ch_setup->xmin == 0)
233 && (ch_setup->ymin == 0) && (ch_setup->xmax == 0)
234 && (ch_setup->ymax == 0)) {
235 cmds->pixdatlen_low = 0;
236 cmds->pixdatlen_high = 0;
237 } else {
238 u32 nbytes = nof_bytes(ch_setup);
239 cmds->pixdatlen_low = (nbytes & 0xFFFF);
240 cmds->pixdatlen_high = (nbytes >> 16);
241 }
242
243 if (ch_setup->slave_trans)
244 cmds->pixdatlen_high |= BIT(15);
245
246 /* build pre-string */
247 build_disp_window(ch_setup, &dw);
248
249 if (standard) {
250 cmds->precmd[0] =
251 build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99);
252 cmds->precmd[1] =
253 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
254 dw.xmin_l);
255 cmds->precmd[2] =
256 build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
257 dw.xmin_h);
258 cmds->precmd[3] =
259 build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
260 cmds->precmd[4] =
261 build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
262 dw.xmax_l);
263 cmds->precmd[5] =
264 build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
265 dw.xmax_h);
266 cmds->precmd[6] =
267 build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
268 cmds->precmd[7] =
269 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
270 } else {
271 if (dw.xmin_l == ch_no)
272 cmds->precmd[0] =
273 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
274 0x99);
275 else
276 cmds->precmd[0] =
277 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
278 ch_no);
279
280 cmds->precmd[1] =
281 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
282 dw.xmin_l);
283 cmds->precmd[2] =
284 build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
285 dw.xmin_h);
286 cmds->precmd[3] =
287 build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
288 cmds->precmd[4] =
289 build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
290 dw.xmax_l);
291 cmds->precmd[5] =
292 build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
293 dw.xmax_h);
294 cmds->precmd[6] =
295 build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
296 cmds->precmd[7] =
297 build_command(ch_setup->disp_no, DISP_1_REG, orientation);
298 cmds->precmd[8] =
299 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
300 cmds->precmd[9] =
301 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
302 cmds->precmd[0xA] =
303 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
304 cmds->precmd[0xB] =
305 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
306 cmds->postcmd[0] =
307 build_command(ch_setup->disp_no, DISP_1_REG, BIT(1));
308 cmds->postcmd[1] =
309 build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1);
310 cmds->postcmd[2] =
311 build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2);
312 cmds->postcmd[3] =
313 build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3);
314 }
315
316 if ((ret = put_cmd_string(cmds_c)) != 0) {
317 return ret;
318 }
319
320 chan.channelnr = cmds->channelnr;
321 chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr;
322 chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr;
323 chan.dum_ch_conf = 0x002;
324 chan.dum_ch_ctrl = 0x04;
325
326 put_channel(chan);
327
328 return 0;
329}
330
331static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer,
332 u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h)
333{
334
335 struct dum_ch_setup k;
336 int ret;
337
338 /* keep width & height within display area */
339 if ((xpos + w) > DISP_MAX_X_SIZE)
340 w = DISP_MAX_X_SIZE - xpos;
341
342 if ((ypos + h) > DISP_MAX_Y_SIZE)
343 h = DISP_MAX_Y_SIZE - ypos;
344
345 /* assume 1 display only */
346 k.disp_no = 0;
347 k.xmin = xpos;
348 k.ymin = ypos;
349 k.xmax = xpos + (w - 1);
350 k.ymax = ypos + (h - 1);
351
352 /* adjust min and max values if necessary */
353 if (k.xmin > DISP_MAX_X_SIZE - 1)
354 k.xmin = DISP_MAX_X_SIZE - 1;
355 if (k.ymin > DISP_MAX_Y_SIZE - 1)
356 k.ymin = DISP_MAX_Y_SIZE - 1;
357
358 if (k.xmax > DISP_MAX_X_SIZE - 1)
359 k.xmax = DISP_MAX_X_SIZE - 1;
360 if (k.ymax > DISP_MAX_Y_SIZE - 1)
361 k.ymax = DISP_MAX_Y_SIZE - 1;
362
363 k.xmirror = 0;
364 k.ymirror = 0;
365 k.rotate = 0;
366 k.minadr = (u32) frame_buffer;
367 k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2));
368 k.pad = PAD_1024;
369 k.dirtybuffer = (u32) dirty_buffer;
370 k.format = RGB888;
371 k.hwdirty = 0;
372 k.slave_trans = 0;
373
374 ret = dum_ch_setup(ch_no, &k);
375
376 return ret;
377}
378
379static void lcd_reset(void)
380{
381 u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE);
382
383 udelay(1);
384 iowrite32(BIT(19), &dum_pio_base[2]);
385 udelay(1);
386 iowrite32(BIT(19), &dum_pio_base[1]);
387 udelay(1);
388}
389
390static int dum_init(struct platform_device *pdev)
391{
392 struct clk *clk;
393
394 /* enable DUM clock */
395 clk = clk_get(&pdev->dev, "dum_ck");
396 if (IS_ERR(clk)) {
397 printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n");
398 return PTR_ERR(clk);
399 }
400
401 clk_set_rate(clk, 1);
402 clk_put(clk);
403
404 DUM_CTRL = V_DUM_RESET;
405
406 /* set priority to "round-robin". All other params to "false" */
407 DUM_CONF = BIT(9);
408
409 /* Display 1 */
410 DUM_WTCFG1 = PNX4008_DUM_WT_CFG;
411 DUM_RTCFG1 = PNX4008_DUM_RT_CFG;
412 DUM_TCFG = PNX4008_DUM_T_CFG;
413
414 return 0;
415}
416
417static void dum_chan_init(void)
418{
419 int i = 0, ch = 0;
420 u32 *cmdptrs;
421 u32 *cmdstrings;
422
423 DUM_COM_BASE =
424 CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS;
425
426 if ((cmdptrs =
427 (u32 *) ioremap_nocache(DUM_COM_BASE,
428 sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL)
429 return;
430
431 for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++)
432 iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch,
433 cmdptrs + ch);
434
435 for (ch = 0; ch < MAX_DUM_CHANNELS; ch++)
436 clear_channel(ch);
437
438 /* Clear the cmdstrings */
439 cmdstrings =
440 (u32 *)ioremap_nocache(*cmdptrs,
441 BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS);
442
443 if (!cmdstrings)
444 goto out;
445
446 for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32);
447 i++)
448 iowrite32(0, cmdstrings + i);
449
450 iounmap((u32 *)cmdstrings);
451
452out:
453 iounmap((u32 *)cmdptrs);
454}
455
456static void lcd_init(void)
457{
458 lcd_reset();
459
460 DUM_OUTP_FORMAT1 = 0; /* RGB666 */
461
462 udelay(1);
463 iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base);
464 udelay(1);
465 iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base);
466 udelay(1);
467 iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base);
468 udelay(1);
469 iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base);
470 udelay(1);
471 iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base);
472 udelay(1);
473 iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base);
474 udelay(1);
475 iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base);
476 udelay(1);
477 iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base);
478 udelay(1);
479}
480
481/* Interface exported to framebuffer drivers */
482
483int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
484 dma_addr_t *phys_addr, int *fb_length)
485{
486 int i;
487 int ret = -1;
488 for (i = 0; i < ARRAY_SIZE(fb_addr); i++)
489 if (fb_addr[i].fb_type == fb_type) {
490 *virt_addr = (void *)(dum_data.lcd_virt_start +
491 fb_addr[i].addr_offset);
492 *phys_addr =
493 dum_data.lcd_phys_start + fb_addr[i].addr_offset;
494 *fb_length = fb_addr[i].fb_length;
495 ret = 0;
496 break;
497 }
498
499 return ret;
500}
501
502EXPORT_SYMBOL(pnx4008_get_fb_addresses);
503
504int pnx4008_alloc_dum_channel(int dev_id)
505{
506 int i = 0;
507
508 while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1))
509 i++;
510
511 if (i == MAX_DUM_CHANNELS)
512 return -ENORESOURCESLEFT;
513 else {
514 dum_data.fb_owning_channel[i] = dev_id;
515 return i;
516 }
517}
518
519EXPORT_SYMBOL(pnx4008_alloc_dum_channel);
520
521int pnx4008_free_dum_channel(int channr, int dev_id)
522{
523 if (channr < 0 || channr > MAX_DUM_CHANNELS)
524 return -EINVAL;
525 else if (dum_data.fb_owning_channel[channr] != dev_id)
526 return -EFBNOTOWNER;
527 else {
528 clear_channel(channr);
529 dum_data.fb_owning_channel[channr] = -1;
530 }
531
532 return 0;
533}
534
535EXPORT_SYMBOL(pnx4008_free_dum_channel);
536
537int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id)
538{
539 int i = chan_uf.channelnr;
540 int ret;
541
542 if (i < 0 || i > MAX_DUM_CHANNELS)
543 return -EINVAL;
544 else if (dum_data.fb_owning_channel[i] != dev_id)
545 return -EFBNOTOWNER;
546 else if ((ret =
547 display_open(chan_uf.channelnr, 0, chan_uf.dirty,
548 chan_uf.source, chan_uf.y_offset,
549 chan_uf.x_offset, chan_uf.height,
550 chan_uf.width)) != 0)
551 return ret;
552 else {
553 dum_data.chan_uf_store[i].dirty = chan_uf.dirty;
554 dum_data.chan_uf_store[i].source = chan_uf.source;
555 dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset;
556 dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset;
557 dum_data.chan_uf_store[i].width = chan_uf.width;
558 dum_data.chan_uf_store[i].height = chan_uf.height;
559 }
560
561 return 0;
562}
563
564EXPORT_SYMBOL(pnx4008_put_dum_channel_uf);
565
566int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id)
567{
568 if (channr < 0 || channr > MAX_DUM_CHANNELS)
569 return -EINVAL;
570 else if (dum_data.fb_owning_channel[channr] != dev_id)
571 return -EFBNOTOWNER;
572 else {
573 if (val == CONF_SYNC_ON) {
574 DUM_CH_CONF(channr) |= CONF_SYNCENABLE;
575 DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK |
576 DUM_CHANNEL_CFG_SYNC_MASK_SET;
577 } else if (val == CONF_SYNC_OFF)
578 DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE;
579 else
580 return -EINVAL;
581 }
582
583 return 0;
584}
585
586EXPORT_SYMBOL(pnx4008_set_dum_channel_sync);
587
588int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id)
589{
590 if (channr < 0 || channr > MAX_DUM_CHANNELS)
591 return -EINVAL;
592 else if (dum_data.fb_owning_channel[channr] != dev_id)
593 return -EFBNOTOWNER;
594 else {
595 if (val == CONF_DIRTYDETECTION_ON)
596 DUM_CH_CONF(channr) |= CONF_DIRTYENABLE;
597 else if (val == CONF_DIRTYDETECTION_OFF)
598 DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE;
599 else
600 return -EINVAL;
601 }
602
603 return 0;
604}
605
606EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect);
607
608#if 0 /* Functions not used currently, but likely to be used in future */
609
610static int get_channel(struct dumchannel *p_chan)
611{
612 int i = p_chan->channelnr;
613
614 if (i < 0 || i > MAX_DUM_CHANNELS)
615 return -EINVAL;
616 else {
617 p_chan->dum_ch_min = DUM_CH_MIN(i);
618 p_chan->dum_ch_max = DUM_CH_MAX(i);
619 p_chan->dum_ch_conf = DUM_CH_CONF(i);
620 p_chan->dum_ch_stat = DUM_CH_STAT(i);
621 p_chan->dum_ch_ctrl = 0; /* WriteOnly control register */
622 }
623
624 return 0;
625}
626
627int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id)
628{
629 int i = p_chan_uf->channelnr;
630
631 if (i < 0 || i > MAX_DUM_CHANNELS)
632 return -EINVAL;
633 else if (dum_data.fb_owning_channel[i] != dev_id)
634 return -EFBNOTOWNER;
635 else {
636 p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty;
637 p_chan_uf->source = dum_data.chan_uf_store[i].source;
638 p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset;
639 p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset;
640 p_chan_uf->width = dum_data.chan_uf_store[i].width;
641 p_chan_uf->height = dum_data.chan_uf_store[i].height;
642 }
643
644 return 0;
645}
646
647EXPORT_SYMBOL(pnx4008_get_dum_channel_uf);
648
649int pnx4008_get_dum_channel_config(int channr, int dev_id)
650{
651 int ret;
652 struct dumchannel chan;
653
654 if (channr < 0 || channr > MAX_DUM_CHANNELS)
655 return -EINVAL;
656 else if (dum_data.fb_owning_channel[channr] != dev_id)
657 return -EFBNOTOWNER;
658 else {
659 chan.channelnr = channr;
660 if ((ret = get_channel(&chan)) != 0)
661 return ret;
662 }
663
664 return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK);
665}
666
667EXPORT_SYMBOL(pnx4008_get_dum_channel_config);
668
669int pnx4008_force_update_dum_channel(int channr, int dev_id)
670{
671 if (channr < 0 || channr > MAX_DUM_CHANNELS)
672 return -EINVAL;
673
674 else if (dum_data.fb_owning_channel[channr] != dev_id)
675 return -EFBNOTOWNER;
676 else
677 DUM_CH_CTRL(channr) = CTRL_SETDIRTY;
678
679 return 0;
680}
681
682EXPORT_SYMBOL(pnx4008_force_update_dum_channel);
683
684#endif
685
686int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma,
687 struct device *dev)
688{
689 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
690
691 if (off < info->fix.smem_len) {
692 vma->vm_pgoff += 1;
693 return dma_mmap_writecombine(dev, vma,
694 (void *)dum_data.lcd_virt_start,
695 dum_data.lcd_phys_start,
696 FB_DMA_SIZE);
697 }
698 return -EINVAL;
699}
700
701EXPORT_SYMBOL(pnx4008_sdum_mmap);
702
703int pnx4008_set_dum_exit_notification(int dev_id)
704{
705 int i;
706
707 for (i = 0; i < MAX_DUM_CHANNELS; i++)
708 if (dum_data.fb_owning_channel[i] == dev_id)
709 return -ERESOURCESNOTFREED;
710
711 return 0;
712}
713
714EXPORT_SYMBOL(pnx4008_set_dum_exit_notification);
715
716/* Platform device driver for DUM */
717
718static int sdum_suspend(struct platform_device *pdev, pm_message_t state)
719{
720 int retval = 0;
721 struct clk *clk;
722
723 clk = clk_get(0, "dum_ck");
724 if (!IS_ERR(clk)) {
725 clk_set_rate(clk, 0);
726 clk_put(clk);
727 } else
728 retval = PTR_ERR(clk);
729
730 /* disable BAC */
731 DUM_CTRL = V_BAC_DISABLE_IDLE;
732
733 /* LCD standby & turn off display */
734 lcd_reset();
735
736 return retval;
737}
738
739static int sdum_resume(struct platform_device *pdev)
740{
741 int retval = 0;
742 struct clk *clk;
743
744 clk = clk_get(0, "dum_ck");
745 if (!IS_ERR(clk)) {
746 clk_set_rate(clk, 1);
747 clk_put(clk);
748 } else
749 retval = PTR_ERR(clk);
750
751 /* wait for BAC disable */
752 DUM_CTRL = V_BAC_DISABLE_TRIG;
753
754 while (DUM_CTRL & BAC_ENABLED)
755 udelay(10);
756
757 /* re-init LCD */
758 lcd_init();
759
760 /* enable BAC and reset MUX */
761 DUM_CTRL = V_BAC_ENABLE;
762 udelay(1);
763 DUM_CTRL = V_MUX_RESET;
764 return 0;
765}
766
767static int __devinit sdum_probe(struct platform_device *pdev)
768{
769 int ret = 0, i = 0;
770
771 /* map frame buffer */
772 dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev,
773 FB_DMA_SIZE,
774 &dum_data.lcd_phys_start,
775 GFP_KERNEL);
776
777 if (!dum_data.lcd_virt_start) {
778 ret = -ENOMEM;
779 goto out_3;
780 }
781
782 /* map slave registers */
783 dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE;
784 dum_data.slave_virt_base =
785 (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32));
786
787 if (dum_data.slave_virt_base == NULL) {
788 ret = -ENOMEM;
789 goto out_2;
790 }
791
792 /* initialize DUM and LCD display */
793 ret = dum_init(pdev);
794 if (ret)
795 goto out_1;
796
797 dum_chan_init();
798 lcd_init();
799
800 DUM_CTRL = V_BAC_ENABLE;
801 udelay(1);
802 DUM_CTRL = V_MUX_RESET;
803
804 /* set decode address and sync clock divider */
805 DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK;
806 DUM_CLK_DIV = PNX4008_DUM_CLK_DIV;
807
808 for (i = 0; i < MAX_DUM_CHANNELS; i++)
809 dum_data.fb_owning_channel[i] = -1;
810
811 /*setup wakeup interrupt */
812 start_int_set_rising_edge(SE_DISP_SYNC_INT);
813 start_int_ack(SE_DISP_SYNC_INT);
814 start_int_umask(SE_DISP_SYNC_INT);
815
816 return 0;
817
818out_1:
819 iounmap((void *)dum_data.slave_virt_base);
820out_2:
821 dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
822 (void *)dum_data.lcd_virt_start,
823 dum_data.lcd_phys_start);
824out_3:
825 return ret;
826}
827
828static int sdum_remove(struct platform_device *pdev)
829{
830 struct clk *clk;
831
832 start_int_mask(SE_DISP_SYNC_INT);
833
834 clk = clk_get(0, "dum_ck");
835 if (!IS_ERR(clk)) {
836 clk_set_rate(clk, 0);
837 clk_put(clk);
838 }
839
840 iounmap((void *)dum_data.slave_virt_base);
841
842 dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
843 (void *)dum_data.lcd_virt_start,
844 dum_data.lcd_phys_start);
845
846 return 0;
847}
848
849static struct platform_driver sdum_driver = {
850 .driver = {
851 .name = "sdum",
852 },
853 .probe = sdum_probe,
854 .remove = sdum_remove,
855 .suspend = sdum_suspend,
856 .resume = sdum_resume,
857};
858
859int __init sdum_init(void)
860{
861 return platform_driver_register(&sdum_driver);
862}
863
864static void __exit sdum_exit(void)
865{
866 platform_driver_unregister(&sdum_driver);
867};
868
869module_init(sdum_init);
870module_exit(sdum_exit);
871
872MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h
new file mode 100644
index 000000000000..e8c5dcdd8813
--- /dev/null
+++ b/drivers/video/pnx4008/sdum.h
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2005 Philips Semiconductors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
18*/
19
20#define MAX_DUM_CHANNELS 64
21
22#define RGB_MEM_WINDOW(x) (0x10000000 + (x)*0x00100000)
23
24#define QCIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x30000: -1)
25#define CIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x60000: -1)
26
27#define CTRL_SETDIRTY (0x00000001)
28#define CONF_DIRTYENABLE (0x00000020)
29#define CONF_SYNCENABLE (0x00000004)
30
31#define DIRTY_ENABLED(conf) ((conf) & 0x0020)
32#define SYNC_ENABLED(conf) ((conf) & 0x0004)
33
34/* Display 1 & 2 Write Timing Configuration */
35#define PNX4008_DUM_WT_CFG 0x00372000
36
37/* Display 1 & 2 Read Timing Configuration */
38#define PNX4008_DUM_RT_CFG 0x00003A47
39
40/* DUM Transit State Timing Configuration */
41#define PNX4008_DUM_T_CFG 0x1D /* 29 HCLK cycles */
42
43/* DUM Sync count clock divider */
44#define PNX4008_DUM_CLK_DIV 0x02DD
45
46/* Memory size for framebuffer, allocated through dma_alloc_writecombine().
47 * Must be PAGE aligned
48 */
49#define FB_DMA_SIZE (PAGE_ALIGN(SZ_1M + PAGE_SIZE))
50
51#define OFFSET_RGBBUFFER (0xB0000)
52#define OFFSET_YUVBUFFER (0x00000)
53
54#define YUVBUFFER (lcd_video_start + OFFSET_YUVBUFFER)
55#define RGBBUFFER (lcd_video_start + OFFSET_RGBBUFFER)
56
57#define CMDSTRING_BASEADDR (0x00C000) /* iram */
58#define BYTES_PER_CMDSTRING (0x80)
59#define NR_OF_CMDSTRINGS (64)
60
61#define MAX_NR_PRESTRINGS (0x40)
62#define MAX_NR_POSTSTRINGS (0x40)
63
64/* various mask definitions */
65#define DUM_CLK_ENABLE 0x01
66#define DUM_CLK_DISABLE 0
67#define DUM_DECODE_MASK 0x1FFFFFFF
68#define DUM_CHANNEL_CFG_MASK 0x01FF
69#define DUM_CHANNEL_CFG_SYNC_MASK 0xFFFE00FF
70#define DUM_CHANNEL_CFG_SYNC_MASK_SET 0x0CA00
71
72#define SDUM_RETURNVAL_BASE (0x500)
73
74#define CONF_SYNC_OFF (0x602)
75#define CONF_SYNC_ON (0x603)
76
77#define CONF_DIRTYDETECTION_OFF (0x600)
78#define CONF_DIRTYDETECTION_ON (0x601)
79
80/* Set the corresponding bit. */
81#define BIT(n) (0x1U << (n))
82
83struct dumchannel_uf {
84 int channelnr;
85 u32 *dirty;
86 u32 *source;
87 u32 x_offset;
88 u32 y_offset;
89 u32 width;
90 u32 height;
91};
92
93enum {
94 FB_TYPE_YUV,
95 FB_TYPE_RGB
96};
97
98struct cmdstring {
99 int channelnr;
100 uint16_t prestringlen;
101 uint16_t poststringlen;
102 uint16_t format;
103 uint16_t reserved;
104 uint16_t startaddr_low;
105 uint16_t startaddr_high;
106 uint16_t pixdatlen_low;
107 uint16_t pixdatlen_high;
108 u32 precmd[MAX_NR_PRESTRINGS];
109 u32 postcmd[MAX_NR_POSTSTRINGS];
110
111};
112
113struct dumchannel {
114 int channelnr;
115 int dum_ch_min;
116 int dum_ch_max;
117 int dum_ch_conf;
118 int dum_ch_stat;
119 int dum_ch_ctrl;
120};
121
122int pnx4008_alloc_dum_channel(int dev_id);
123int pnx4008_free_dum_channel(int channr, int dev_id);
124
125int pnx4008_get_dum_channel_uf(struct dumchannel_uf *pChan_uf, int dev_id);
126int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id);
127
128int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id);
129int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id);
130
131int pnx4008_force_dum_update_channel(int channr, int dev_id);
132
133int pnx4008_get_dum_channel_config(int channr, int dev_id);
134
135int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, struct device *dev);
136int pnx4008_set_dum_exit_notification(int dev_id);
137
138int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
139 dma_addr_t * phys_addr, int *fb_length);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index ec4bacf9dd2e..78dc59a1751b 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -53,10 +53,8 @@
53#include <linux/errno.h> 53#include <linux/errno.h>
54#include <linux/string.h> 54#include <linux/string.h>
55#include <linux/mm.h> 55#include <linux/mm.h>
56#include <linux/tty.h>
57#include <linux/slab.h> 56#include <linux/slab.h>
58#include <linux/delay.h> 57#include <linux/delay.h>
59#include <linux/config.h>
60#include <linux/interrupt.h> 58#include <linux/interrupt.h>
61#include <linux/fb.h> 59#include <linux/fb.h>
62#include <linux/init.h> 60#include <linux/init.h>
@@ -189,7 +187,7 @@ static short do_blank = 0; /* (Un)Blank the screen */
189static unsigned int is_blanked = 0; /* Is the screen blanked? */ 187static unsigned int is_blanked = 0; /* Is the screen blanked? */
190 188
191#ifdef CONFIG_SH_STORE_QUEUES 189#ifdef CONFIG_SH_STORE_QUEUES
192static struct sq_mapping *pvr2fb_map; 190static unsigned long pvr2fb_map;
193#endif 191#endif
194 192
195#ifdef CONFIG_SH_DMA 193#ifdef CONFIG_SH_DMA
@@ -215,15 +213,17 @@ static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp);
215static int pvr2_init_cable(void); 213static int pvr2_init_cable(void);
216static int pvr2_get_param(const struct pvr2_params *p, const char *s, 214static int pvr2_get_param(const struct pvr2_params *p, const char *s,
217 int val, int size); 215 int val, int size);
216#ifdef CONFIG_SH_DMA
218static ssize_t pvr2fb_write(struct file *file, const char *buf, 217static ssize_t pvr2fb_write(struct file *file, const char *buf,
219 size_t count, loff_t *ppos); 218 size_t count, loff_t *ppos);
219#endif
220 220
221static struct fb_ops pvr2fb_ops = { 221static struct fb_ops pvr2fb_ops = {
222 .owner = THIS_MODULE, 222 .owner = THIS_MODULE,
223 .fb_setcolreg = pvr2fb_setcolreg, 223 .fb_setcolreg = pvr2fb_setcolreg,
224 .fb_blank = pvr2fb_blank, 224 .fb_blank = pvr2fb_blank,
225 .fb_check_var = pvr2fb_check_var, 225 .fb_check_var = pvr2fb_check_var,
226 .fb_set_par = pvr2fb_set_par, 226 .fb_set_par = pvr2fb_set_par,
227#ifdef CONFIG_SH_DMA 227#ifdef CONFIG_SH_DMA
228 .fb_write = pvr2fb_write, 228 .fb_write = pvr2fb_write,
229#endif 229#endif
@@ -785,7 +785,7 @@ static int __init pvr2fb_common_init(void)
785 goto out_err; 785 goto out_err;
786 } 786 }
787 787
788 fb_memset((unsigned long)fb_info->screen_base, 0, pvr2_fix.smem_len); 788 fb_memset(fb_info->screen_base, 0, pvr2_fix.smem_len);
789 789
790 pvr2_fix.ypanstep = nopan ? 0 : 1; 790 pvr2_fix.ypanstep = nopan ? 0 : 1;
791 pvr2_fix.ywrapstep = nowrap ? 0 : 1; 791 pvr2_fix.ywrapstep = nowrap ? 0 : 1;
@@ -822,7 +822,7 @@ static int __init pvr2fb_common_init(void)
822 modememused >> 10, (unsigned long)(fb_info->fix.smem_len >> 10)); 822 modememused >> 10, (unsigned long)(fb_info->fix.smem_len >> 10));
823 printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", 823 printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n",
824 fb_info->node, fb_info->var.xres, fb_info->var.yres, 824 fb_info->node, fb_info->var.xres, fb_info->var.yres,
825 fb_info->var.bits_per_pixel, 825 fb_info->var.bits_per_pixel,
826 get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel), 826 get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),
827 (char *)pvr2_get_param(cables, NULL, cable_type, 3), 827 (char *)pvr2_get_param(cables, NULL, cable_type, 3),
828 (char *)pvr2_get_param(outputs, NULL, video_output, 3)); 828 (char *)pvr2_get_param(outputs, NULL, video_output, 3));
@@ -831,10 +831,10 @@ static int __init pvr2fb_common_init(void)
831 printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node); 831 printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node);
832 832
833 pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len, 833 pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len,
834 fb_info->fix.id); 834 fb_info->fix.id, pgprot_val(PAGE_SHARED));
835 835
836 printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n", 836 printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n",
837 fb_info->node, pvr2fb_map->sq_addr); 837 fb_info->node, pvr2fb_map);
838#endif 838#endif
839 839
840 return 0; 840 return 0;
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 809fc5eefc15..bbb07106cd54 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -22,7 +22,6 @@
22 * 22 *
23 */ 23 */
24 24
25#include <linux/config.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
28#include <linux/kernel.h> 27#include <linux/kernel.h>
@@ -1335,7 +1334,7 @@ int __init pxafb_probe(struct platform_device *dev)
1335 goto failed; 1334 goto failed;
1336 } 1335 }
1337 1336
1338 ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi); 1337 ret = request_irq(IRQ_LCD, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi);
1339 if (ret) { 1338 if (ret) {
1340 dev_err(&dev->dev, "request_irq failed: %d\n", ret); 1339 dev_err(&dev->dev, "request_irq failed: %d\n", ret);
1341 ret = -EBUSY; 1340 ret = -EBUSY;
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index fc91dbf896d2..48536c3e58a4 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -14,7 +14,6 @@
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/tty.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/interrupt.h> 19#include <linux/interrupt.h>
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index 5e2c64f622cb..cf41ff177644 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -25,7 +25,6 @@
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/tty.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31#include <linux/fb.h> 30#include <linux/fb.h>
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 3e9308f0f165..4acde4f7dbf8 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -29,18 +29,17 @@
29 * doublescan modes are broken 29 * doublescan modes are broken
30 */ 30 */
31 31
32#include <linux/config.h>
33#include <linux/module.h> 32#include <linux/module.h>
34#include <linux/kernel.h> 33#include <linux/kernel.h>
35#include <linux/errno.h> 34#include <linux/errno.h>
36#include <linux/string.h> 35#include <linux/string.h>
37#include <linux/mm.h> 36#include <linux/mm.h>
38#include <linux/tty.h>
39#include <linux/slab.h> 37#include <linux/slab.h>
40#include <linux/delay.h> 38#include <linux/delay.h>
41#include <linux/fb.h> 39#include <linux/fb.h>
42#include <linux/init.h> 40#include <linux/init.h>
43#include <linux/pci.h> 41#include <linux/pci.h>
42#include <linux/backlight.h>
44#ifdef CONFIG_MTRR 43#ifdef CONFIG_MTRR
45#include <asm/mtrr.h> 44#include <asm/mtrr.h>
46#endif 45#endif
@@ -272,34 +271,183 @@ static const struct riva_regs reg_template = {
272/* 271/*
273 * Backlight control 272 * Backlight control
274 */ 273 */
275#ifdef CONFIG_PMAC_BACKLIGHT 274#ifdef CONFIG_FB_RIVA_BACKLIGHT
275/* We do not have any information about which values are allowed, thus
276 * we used safe values.
277 */
278#define MIN_LEVEL 0x158
279#define MAX_LEVEL 0x534
280#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
276 281
277static int riva_backlight_levels[] = { 282static struct backlight_properties riva_bl_data;
278 0x158, 283
279 0x192, 284/* Call with fb_info->bl_mutex held */
280 0x1c6, 285static int riva_bl_get_level_brightness(struct riva_par *par,
281 0x200, 286 int level)
282 0x234, 287{
283 0x268, 288 struct fb_info *info = pci_get_drvdata(par->pdev);
284 0x2a2, 289 int nlevel;
285 0x2d6, 290
286 0x310, 291 /* Get and convert the value */
287 0x344, 292 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
288 0x378, 293
289 0x3b2, 294 if (nlevel < 0)
290 0x3e6, 295 nlevel = 0;
291 0x41a, 296 else if (nlevel < MIN_LEVEL)
292 0x454, 297 nlevel = MIN_LEVEL;
293 0x534, 298 else if (nlevel > MAX_LEVEL)
294}; 299 nlevel = MAX_LEVEL;
300
301 return nlevel;
302}
303
304/* Call with fb_info->bl_mutex held */
305static int __riva_bl_update_status(struct backlight_device *bd)
306{
307 struct riva_par *par = class_get_devdata(&bd->class_dev);
308 U032 tmp_pcrt, tmp_pmc;
309 int level;
310
311 if (bd->props->power != FB_BLANK_UNBLANK ||
312 bd->props->fb_blank != FB_BLANK_UNBLANK)
313 level = 0;
314 else
315 level = bd->props->brightness;
316
317 tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
318 tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;
319 if(level > 0) {
320 tmp_pcrt |= 0x1;
321 tmp_pmc |= (1 << 31); /* backlight bit */
322 tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */
323 }
324 par->riva.PCRTC0[0x081C/4] = tmp_pcrt;
325 par->riva.PMC[0x10F0/4] = tmp_pmc;
326
327 return 0;
328}
329
330static int riva_bl_update_status(struct backlight_device *bd)
331{
332 struct riva_par *par = class_get_devdata(&bd->class_dev);
333 struct fb_info *info = pci_get_drvdata(par->pdev);
334 int ret;
295 335
296static int riva_set_backlight_enable(int on, int level, void *data); 336 mutex_lock(&info->bl_mutex);
297static int riva_set_backlight_level(int level, void *data); 337 ret = __riva_bl_update_status(bd);
298static struct backlight_controller riva_backlight_controller = { 338 mutex_unlock(&info->bl_mutex);
299 riva_set_backlight_enable, 339
300 riva_set_backlight_level 340 return ret;
341}
342
343static int riva_bl_get_brightness(struct backlight_device *bd)
344{
345 return bd->props->brightness;
346}
347
348static struct backlight_properties riva_bl_data = {
349 .owner = THIS_MODULE,
350 .get_brightness = riva_bl_get_brightness,
351 .update_status = riva_bl_update_status,
352 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
301}; 353};
302#endif /* CONFIG_PMAC_BACKLIGHT */ 354
355static void riva_bl_set_power(struct fb_info *info, int power)
356{
357 mutex_lock(&info->bl_mutex);
358
359 if (info->bl_dev) {
360 down(&info->bl_dev->sem);
361 info->bl_dev->props->power = power;
362 __riva_bl_update_status(info->bl_dev);
363 up(&info->bl_dev->sem);
364 }
365
366 mutex_unlock(&info->bl_mutex);
367}
368
369static void riva_bl_init(struct riva_par *par)
370{
371 struct fb_info *info = pci_get_drvdata(par->pdev);
372 struct backlight_device *bd;
373 char name[12];
374
375 if (!par->FlatPanel)
376 return;
377
378#ifdef CONFIG_PMAC_BACKLIGHT
379 if (!machine_is(powermac) ||
380 !pmac_has_backlight_type("mnca"))
381 return;
382#endif
383
384 snprintf(name, sizeof(name), "rivabl%d", info->node);
385
386 bd = backlight_device_register(name, par, &riva_bl_data);
387 if (IS_ERR(bd)) {
388 info->bl_dev = NULL;
389 printk(KERN_WARNING "riva: Backlight registration failed\n");
390 goto error;
391 }
392
393 mutex_lock(&info->bl_mutex);
394 info->bl_dev = bd;
395 fb_bl_default_curve(info, 0,
396 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
397 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
398 mutex_unlock(&info->bl_mutex);
399
400 down(&bd->sem);
401 bd->props->brightness = riva_bl_data.max_brightness;
402 bd->props->power = FB_BLANK_UNBLANK;
403 bd->props->update_status(bd);
404 up(&bd->sem);
405
406#ifdef CONFIG_PMAC_BACKLIGHT
407 mutex_lock(&pmac_backlight_mutex);
408 if (!pmac_backlight)
409 pmac_backlight = bd;
410 mutex_unlock(&pmac_backlight_mutex);
411#endif
412
413 printk("riva: Backlight initialized (%s)\n", name);
414
415 return;
416
417error:
418 return;
419}
420
421static void riva_bl_exit(struct riva_par *par)
422{
423 struct fb_info *info = pci_get_drvdata(par->pdev);
424
425#ifdef CONFIG_PMAC_BACKLIGHT
426 mutex_lock(&pmac_backlight_mutex);
427#endif
428
429 mutex_lock(&info->bl_mutex);
430 if (info->bl_dev) {
431#ifdef CONFIG_PMAC_BACKLIGHT
432 if (pmac_backlight == info->bl_dev)
433 pmac_backlight = NULL;
434#endif
435
436 backlight_device_unregister(info->bl_dev);
437
438 printk("riva: Backlight unloaded\n");
439 }
440 mutex_unlock(&info->bl_mutex);
441
442#ifdef CONFIG_PMAC_BACKLIGHT
443 mutex_unlock(&pmac_backlight_mutex);
444#endif
445}
446#else
447static inline void riva_bl_init(struct riva_par *par) {}
448static inline void riva_bl_exit(struct riva_par *par) {}
449static inline void riva_bl_set_power(struct fb_info *info, int power) {}
450#endif /* CONFIG_FB_RIVA_BACKLIGHT */
303 451
304/* ------------------------------------------------------------------------- * 452/* ------------------------------------------------------------------------- *
305 * 453 *
@@ -973,36 +1121,6 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
973 1121
974/* ------------------------------------------------------------------------- * 1122/* ------------------------------------------------------------------------- *
975 * 1123 *
976 * Backlight operations
977 *
978 * ------------------------------------------------------------------------- */
979
980#ifdef CONFIG_PMAC_BACKLIGHT
981static int riva_set_backlight_enable(int on, int level, void *data)
982{
983 struct riva_par *par = data;
984 U032 tmp_pcrt, tmp_pmc;
985
986 tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
987 tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;
988 if(on && (level > BACKLIGHT_OFF)) {
989 tmp_pcrt |= 0x1;
990 tmp_pmc |= (1 << 31); // backlight bit
991 tmp_pmc |= riva_backlight_levels[level-1] << 16; // level
992 }
993 par->riva.PCRTC0[0x081C/4] = tmp_pcrt;
994 par->riva.PMC[0x10F0/4] = tmp_pmc;
995 return 0;
996}
997
998static int riva_set_backlight_level(int level, void *data)
999{
1000 return riva_set_backlight_enable(1, level, data);
1001}
1002#endif /* CONFIG_PMAC_BACKLIGHT */
1003
1004/* ------------------------------------------------------------------------- *
1005 *
1006 * framebuffer operations 1124 * framebuffer operations
1007 * 1125 *
1008 * ------------------------------------------------------------------------- */ 1126 * ------------------------------------------------------------------------- */
@@ -1247,11 +1365,7 @@ static int rivafb_blank(int blank, struct fb_info *info)
1247 SEQout(par, 0x01, tmp); 1365 SEQout(par, 0x01, tmp);
1248 CRTCout(par, 0x1a, vesa); 1366 CRTCout(par, 0x1a, vesa);
1249 1367
1250#ifdef CONFIG_PMAC_BACKLIGHT 1368 riva_bl_set_power(info, blank);
1251 if ( par->FlatPanel && machine_is(powermac)) {
1252 set_backlight_enable(!blank);
1253 }
1254#endif
1255 1369
1256 NVTRACE_LEAVE(); 1370 NVTRACE_LEAVE();
1257 1371
@@ -1712,8 +1826,8 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1712{ 1826{
1713 struct riva_par *par = info->par; 1827 struct riva_par *par = info->par;
1714 struct device_node *dp; 1828 struct device_node *dp;
1715 unsigned char *pedid = NULL; 1829 const unsigned char *pedid = NULL;
1716 unsigned char *disptype = NULL; 1830 const unsigned char *disptype = NULL;
1717 static char *propnames[] = { 1831 static char *propnames[] = {
1718 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL }; 1832 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
1719 int i; 1833 int i;
@@ -1721,14 +1835,13 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1721 NVTRACE_ENTER(); 1835 NVTRACE_ENTER();
1722 dp = pci_device_to_OF_node(pd); 1836 dp = pci_device_to_OF_node(pd);
1723 for (; dp != NULL; dp = dp->child) { 1837 for (; dp != NULL; dp = dp->child) {
1724 disptype = (unsigned char *)get_property(dp, "display-type", NULL); 1838 disptype = get_property(dp, "display-type", NULL);
1725 if (disptype == NULL) 1839 if (disptype == NULL)
1726 continue; 1840 continue;
1727 if (strncmp(disptype, "LCD", 3) != 0) 1841 if (strncmp(disptype, "LCD", 3) != 0)
1728 continue; 1842 continue;
1729 for (i = 0; propnames[i] != NULL; ++i) { 1843 for (i = 0; propnames[i] != NULL; ++i) {
1730 pedid = (unsigned char *) 1844 pedid = get_property(dp, propnames[i], NULL);
1731 get_property(dp, propnames[i], NULL);
1732 if (pedid != NULL) { 1845 if (pedid != NULL) {
1733 par->EDID = pedid; 1846 par->EDID = pedid;
1734 NVTRACE("LCD found.\n"); 1847 NVTRACE("LCD found.\n");
@@ -2022,6 +2135,9 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
2022 2135
2023 fb_destroy_modedb(info->monspecs.modedb); 2136 fb_destroy_modedb(info->monspecs.modedb);
2024 info->monspecs.modedb = NULL; 2137 info->monspecs.modedb = NULL;
2138
2139 pci_set_drvdata(pd, info);
2140 riva_bl_init(info->par);
2025 ret = register_framebuffer(info); 2141 ret = register_framebuffer(info);
2026 if (ret < 0) { 2142 if (ret < 0) {
2027 printk(KERN_ERR PFX 2143 printk(KERN_ERR PFX
@@ -2029,19 +2145,13 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
2029 goto err_iounmap_screen_base; 2145 goto err_iounmap_screen_base;
2030 } 2146 }
2031 2147
2032 pci_set_drvdata(pd, info);
2033
2034 printk(KERN_INFO PFX 2148 printk(KERN_INFO PFX
2035 "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n", 2149 "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
2036 info->fix.id, 2150 info->fix.id,
2037 RIVAFB_VERSION, 2151 RIVAFB_VERSION,
2038 info->fix.smem_len / (1024 * 1024), 2152 info->fix.smem_len / (1024 * 1024),
2039 info->fix.smem_start); 2153 info->fix.smem_start);
2040#ifdef CONFIG_PMAC_BACKLIGHT 2154
2041 if (default_par->FlatPanel && machine_is(powermac))
2042 register_backlight_controller(&riva_backlight_controller,
2043 default_par, "mnca");
2044#endif
2045 NVTRACE_LEAVE(); 2155 NVTRACE_LEAVE();
2046 return 0; 2156 return 0;
2047 2157
@@ -2058,7 +2168,6 @@ err_iounmap_ctrl_base:
2058err_release_region: 2168err_release_region:
2059 pci_release_regions(pd); 2169 pci_release_regions(pd);
2060err_disable_device: 2170err_disable_device:
2061 pci_disable_device(pd);
2062err_free_pixmap: 2171err_free_pixmap:
2063 kfree(info->pixmap.addr); 2172 kfree(info->pixmap.addr);
2064err_framebuffer_release: 2173err_framebuffer_release:
@@ -2074,6 +2183,8 @@ static void __exit rivafb_remove(struct pci_dev *pd)
2074 2183
2075 NVTRACE_ENTER(); 2184 NVTRACE_ENTER();
2076 2185
2186 riva_bl_exit(par);
2187
2077#ifdef CONFIG_FB_RIVA_I2C 2188#ifdef CONFIG_FB_RIVA_I2C
2078 riva_delete_i2c_busses(par); 2189 riva_delete_i2c_busses(par);
2079 kfree(par->EDID); 2190 kfree(par->EDID);
@@ -2091,7 +2202,6 @@ static void __exit rivafb_remove(struct pci_dev *pd)
2091 if (par->riva.Architecture == NV_ARCH_03) 2202 if (par->riva.Architecture == NV_ARCH_03)
2092 iounmap(par->riva.PRAMIN); 2203 iounmap(par->riva.PRAMIN);
2093 pci_release_regions(pd); 2204 pci_release_regions(pd);
2094 pci_disable_device(pd);
2095 kfree(info->pixmap.addr); 2205 kfree(info->pixmap.addr);
2096 framebuffer_release(info); 2206 framebuffer_release(info);
2097 pci_set_drvdata(pd, NULL); 2207 pci_set_drvdata(pd, NULL);
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 8b1967fc116a..9751c37c0bfd 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -12,7 +12,6 @@
12 * for more details. 12 * for more details.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/sched.h> 17#include <linux/sched.h>
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
index 440ff445689b..7fa13fc9c413 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/riva/rivafb.h
@@ -1,7 +1,6 @@
1#ifndef __RIVAFB_H 1#ifndef __RIVAFB_H
2#define __RIVAFB_H 2#define __RIVAFB_H
3 3
4#include <linux/config.h>
5#include <linux/fb.h> 4#include <linux/fb.h>
6#include <video/vga.h> 5#include <video/vga.h>
7#include <linux/i2c.h> 6#include <linux/i2c.h>
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index feec47bdd479..a5333c190789 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -28,7 +28,6 @@
28 * more details. 28 * more details.
29 */ 29 */
30 30
31#include <linux/config.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/platform_device.h> 32#include <linux/platform_device.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 9451932fbaf2..ad3bdd6f1ac1 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -76,7 +76,6 @@
76#include <linux/errno.h> 76#include <linux/errno.h>
77#include <linux/string.h> 77#include <linux/string.h>
78#include <linux/mm.h> 78#include <linux/mm.h>
79#include <linux/tty.h>
80#include <linux/slab.h> 79#include <linux/slab.h>
81#include <linux/delay.h> 80#include <linux/delay.h>
82#include <linux/fb.h> 81#include <linux/fb.h>
@@ -641,6 +640,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
641 int ret; 640 int ret;
642 int irq; 641 int irq;
643 int i; 642 int i;
643 u32 lcdcon1;
644 644
645 mach_info = pdev->dev.platform_data; 645 mach_info = pdev->dev.platform_data;
646 if (mach_info == NULL) { 646 if (mach_info == NULL) {
@@ -672,6 +672,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
672 672
673 memcpy(&info->regs, &mach_info->regs, sizeof(info->regs)); 673 memcpy(&info->regs, &mach_info->regs, sizeof(info->regs));
674 674
675 /* Stop the video and unset ENVID if set */
676 info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
677 lcdcon1 = readl(S3C2410_LCDCON1);
678 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
679
675 info->mach_info = pdev->dev.platform_data; 680 info->mach_info = pdev->dev.platform_data;
676 681
677 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; 682 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -729,7 +734,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
729 734
730 dprintk("got LCD region\n"); 735 dprintk("got LCD region\n");
731 736
732 ret = request_irq(irq, s3c2410fb_irq, SA_INTERRUPT, pdev->name, info); 737 ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info);
733 if (ret) { 738 if (ret) {
734 dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret); 739 dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret);
735 ret = -EBUSY; 740 ret = -EBUSY;
@@ -794,15 +799,14 @@ dealloc_fb:
794 * shutdown the lcd controller 799 * shutdown the lcd controller
795*/ 800*/
796 801
797static void s3c2410fb_stop_lcd(void) 802static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
798{ 803{
799 unsigned long flags; 804 unsigned long flags;
800 unsigned long tmp;
801 805
802 local_irq_save(flags); 806 local_irq_save(flags);
803 807
804 tmp = readl(S3C2410_LCDCON1); 808 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
805 writel(tmp & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); 809 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
806 810
807 local_irq_restore(flags); 811 local_irq_restore(flags);
808} 812}
@@ -816,7 +820,7 @@ static int s3c2410fb_remove(struct platform_device *pdev)
816 struct s3c2410fb_info *info = fbinfo->par; 820 struct s3c2410fb_info *info = fbinfo->par;
817 int irq; 821 int irq;
818 822
819 s3c2410fb_stop_lcd(); 823 s3c2410fb_stop_lcd(info);
820 msleep(1); 824 msleep(1);
821 825
822 s3c2410fb_unmap_video_memory(info); 826 s3c2410fb_unmap_video_memory(info);
@@ -844,7 +848,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
844 struct fb_info *fbinfo = platform_get_drvdata(dev); 848 struct fb_info *fbinfo = platform_get_drvdata(dev);
845 struct s3c2410fb_info *info = fbinfo->par; 849 struct s3c2410fb_info *info = fbinfo->par;
846 850
847 s3c2410fb_stop_lcd(); 851 s3c2410fb_stop_lcd(info);
848 852
849 /* sleep before disabling the clock, we need to ensure 853 /* sleep before disabling the clock, we need to ensure
850 * the LCD DMA engine is not going to get back on the bus 854 * the LCD DMA engine is not going to get back on the bus
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index d9831fd42341..a2e6e7205d7e 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -160,7 +160,6 @@
160 * - Add patch 681/1 and clean up stork definitions. 160 * - Add patch 681/1 and clean up stork definitions.
161 */ 161 */
162 162
163#include <linux/config.h>
164#include <linux/module.h> 163#include <linux/module.h>
165#include <linux/kernel.h> 164#include <linux/kernel.h>
166#include <linux/sched.h> 165#include <linux/sched.h>
@@ -1473,7 +1472,7 @@ static int __init sa1100fb_probe(struct platform_device *pdev)
1473 if (ret) 1472 if (ret)
1474 goto failed; 1473 goto failed;
1475 1474
1476 ret = request_irq(irq, sa1100fb_handle_irq, SA_INTERRUPT, 1475 ret = request_irq(irq, sa1100fb_handle_irq, IRQF_DISABLED,
1477 "LCD", fbi); 1476 "LCD", fbi);
1478 if (ret) { 1477 if (ret) {
1479 printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret); 1478 printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 21debed863ac..d7d810dbf0bd 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -10,7 +10,6 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/sched.h> 15#include <linux/sched.h>
@@ -149,7 +148,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
149 chan->adapter.algo_data = &chan->algo; 148 chan->adapter.algo_data = &chan->algo;
150 chan->adapter.dev.parent = &chan->par->pcidev->dev; 149 chan->adapter.dev.parent = &chan->par->pcidev->dev;
151 chan->algo.udelay = 40; 150 chan->algo.udelay = 40;
152 chan->algo.mdelay = 5;
153 chan->algo.timeout = 20; 151 chan->algo.timeout = 20;
154 chan->algo.data = chan; 152 chan->algo.data = chan;
155 153
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index 58cfdfb41833..e648a6c0f6d9 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -147,7 +147,27 @@ struct xtimings {
147 int interlaced; 147 int interlaced;
148}; 148};
149 149
150struct savage_reg {
151 unsigned char MiscOutReg; /* Misc */
152 unsigned char CRTC[25]; /* Crtc Controller */
153 unsigned char Sequencer[5]; /* Video Sequencer */
154 unsigned char Graphics[9]; /* Video Graphics */
155 unsigned char Attribute[21]; /* Video Atribute */
150 156
157 unsigned int mode, refresh;
158 unsigned char SR08, SR0E, SR0F;
159 unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR29, SR30;
160 unsigned char SR54[8];
161 unsigned char Clock;
162 unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C;
163 unsigned char CR40, CR41, CR42, CR43, CR45;
164 unsigned char CR50, CR51, CR53, CR55, CR58, CR5B, CR5D, CR5E;
165 unsigned char CR60, CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F;
166 unsigned char CR86, CR88;
167 unsigned char CR90, CR91, CRB0;
168 unsigned int STREAMS[22]; /* yuck, streams regs */
169 unsigned int MMPR0, MMPR1, MMPR2, MMPR3;
170};
151/* --------------------------------------------------------------------- */ 171/* --------------------------------------------------------------------- */
152 172
153#define NR_PALETTE 256 173#define NR_PALETTE 256
@@ -167,6 +187,8 @@ struct savagefb_par {
167 struct pci_dev *pcidev; 187 struct pci_dev *pcidev;
168 savage_chipset chip; 188 savage_chipset chip;
169 struct savagefb_i2c_chan chan; 189 struct savagefb_i2c_chan chan;
190 struct savage_reg state;
191 struct savage_reg save;
170 unsigned char *edid; 192 unsigned char *edid;
171 u32 pseudo_palette[16]; 193 u32 pseudo_palette[16];
172 int paletteEnabled; 194 int paletteEnabled;
@@ -179,6 +201,7 @@ struct savagefb_par {
179 int minClock; 201 int minClock;
180 int numClocks; 202 int numClocks;
181 int clock[4]; 203 int clock[4];
204 int MCLK, REFCLK, LCDclk;
182 struct { 205 struct {
183 u8 __iomem *vbase; 206 u8 __iomem *vbase;
184 u32 pbase; 207 u32 pbase;
@@ -196,7 +219,6 @@ struct savagefb_par {
196 219
197 volatile u32 __iomem *bci_base; 220 volatile u32 __iomem *bci_base;
198 unsigned int bci_ptr; 221 unsigned int bci_ptr;
199
200 u32 cob_offset; 222 u32 cob_offset;
201 u32 cob_size; 223 u32 cob_size;
202 int cob_index; 224 int cob_index;
@@ -204,7 +226,6 @@ struct savagefb_par {
204 void (*SavageWaitIdle) (struct savagefb_par *par); 226 void (*SavageWaitIdle) (struct savagefb_par *par);
205 void (*SavageWaitFifo) (struct savagefb_par *par, int space); 227 void (*SavageWaitFifo) (struct savagefb_par *par, int space);
206 228
207 int MCLK, REFCLK, LCDclk;
208 int HorizScaleFactor; 229 int HorizScaleFactor;
209 230
210 /* Panels size */ 231 /* Panels size */
@@ -217,26 +238,6 @@ struct savagefb_par {
217 238
218 int depth; 239 int depth;
219 int vwidth; 240 int vwidth;
220
221 unsigned char MiscOutReg; /* Misc */
222 unsigned char CRTC[25]; /* Crtc Controller */
223 unsigned char Sequencer[5]; /* Video Sequencer */
224 unsigned char Graphics[9]; /* Video Graphics */
225 unsigned char Attribute[21]; /* Video Atribute */
226
227 unsigned int mode, refresh;
228 unsigned char SR08, SR0E, SR0F;
229 unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR29, SR30;
230 unsigned char SR54[8];
231 unsigned char Clock;
232 unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C;
233 unsigned char CR40, CR41, CR42, CR43, CR45;
234 unsigned char CR50, CR51, CR53, CR55, CR58, CR5B, CR5D, CR5E;
235 unsigned char CR60, CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F;
236 unsigned char CR86, CR88;
237 unsigned char CR90, CR91, CRB0;
238 unsigned int STREAMS[22]; /* yuck, streams regs */
239 unsigned int MMPR0, MMPR1, MMPR2, MMPR3;
240}; 241};
241 242
242#define BCI_BD_BW_DISABLE 0x10000000 243#define BCI_BD_BW_DISABLE 0x10000000
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 0da624e6524f..82b3deaae02d 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -41,13 +41,11 @@
41 * 41 *
42 */ 42 */
43 43
44#include <linux/config.h>
45#include <linux/module.h> 44#include <linux/module.h>
46#include <linux/kernel.h> 45#include <linux/kernel.h>
47#include <linux/errno.h> 46#include <linux/errno.h>
48#include <linux/string.h> 47#include <linux/string.h>
49#include <linux/mm.h> 48#include <linux/mm.h>
50#include <linux/tty.h>
51#include <linux/slab.h> 49#include <linux/slab.h>
52#include <linux/delay.h> 50#include <linux/delay.h>
53#include <linux/fb.h> 51#include <linux/fb.h>
@@ -86,15 +84,15 @@ MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips");
86 84
87/* --------------------------------------------------------------------- */ 85/* --------------------------------------------------------------------- */
88 86
89static void vgaHWSeqReset (struct savagefb_par *par, int start) 87static void vgaHWSeqReset(struct savagefb_par *par, int start)
90{ 88{
91 if (start) 89 if (start)
92 VGAwSEQ (0x00, 0x01, par); /* Synchronous Reset */ 90 VGAwSEQ(0x00, 0x01, par); /* Synchronous Reset */
93 else 91 else
94 VGAwSEQ (0x00, 0x03, par); /* End Reset */ 92 VGAwSEQ(0x00, 0x03, par); /* End Reset */
95} 93}
96 94
97static void vgaHWProtect (struct savagefb_par *par, int on) 95static void vgaHWProtect(struct savagefb_par *par, int on)
98{ 96{
99 unsigned char tmp; 97 unsigned char tmp;
100 98
@@ -102,10 +100,10 @@ static void vgaHWProtect (struct savagefb_par *par, int on)
102 /* 100 /*
103 * Turn off screen and disable sequencer. 101 * Turn off screen and disable sequencer.
104 */ 102 */
105 tmp = VGArSEQ (0x01, par); 103 tmp = VGArSEQ(0x01, par);
106 104
107 vgaHWSeqReset (par, 1); /* start synchronous reset */ 105 vgaHWSeqReset(par, 1); /* start synchronous reset */
108 VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */ 106 VGAwSEQ(0x01, tmp | 0x20, par);/* disable the display */
109 107
110 VGAenablePalette(par); 108 VGAenablePalette(par);
111 } else { 109 } else {
@@ -113,75 +111,76 @@ static void vgaHWProtect (struct savagefb_par *par, int on)
113 * Reenable sequencer, then turn on screen. 111 * Reenable sequencer, then turn on screen.
114 */ 112 */
115 113
116 tmp = VGArSEQ (0x01, par); 114 tmp = VGArSEQ(0x01, par);
117 115
118 VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */ 116 VGAwSEQ(0x01, tmp & ~0x20, par);/* reenable display */
119 vgaHWSeqReset (par, 0); /* clear synchronous reset */ 117 vgaHWSeqReset(par, 0); /* clear synchronous reset */
120 118
121 VGAdisablePalette(par); 119 VGAdisablePalette(par);
122 } 120 }
123} 121}
124 122
125static void vgaHWRestore (struct savagefb_par *par) 123static void vgaHWRestore(struct savagefb_par *par, struct savage_reg *reg)
126{ 124{
127 int i; 125 int i;
128 126
129 VGAwMISC (par->MiscOutReg, par); 127 VGAwMISC(reg->MiscOutReg, par);
130 128
131 for (i = 1; i < 5; i++) 129 for (i = 1; i < 5; i++)
132 VGAwSEQ (i, par->Sequencer[i], par); 130 VGAwSEQ(i, reg->Sequencer[i], par);
133 131
134 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or 132 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or
135 CRTC[17] */ 133 CRTC[17] */
136 VGAwCR (17, par->CRTC[17] & ~0x80, par); 134 VGAwCR(17, reg->CRTC[17] & ~0x80, par);
137 135
138 for (i = 0; i < 25; i++) 136 for (i = 0; i < 25; i++)
139 VGAwCR (i, par->CRTC[i], par); 137 VGAwCR(i, reg->CRTC[i], par);
140 138
141 for (i = 0; i < 9; i++) 139 for (i = 0; i < 9; i++)
142 VGAwGR (i, par->Graphics[i], par); 140 VGAwGR(i, reg->Graphics[i], par);
143 141
144 VGAenablePalette(par); 142 VGAenablePalette(par);
145 143
146 for (i = 0; i < 21; i++) 144 for (i = 0; i < 21; i++)
147 VGAwATTR (i, par->Attribute[i], par); 145 VGAwATTR(i, reg->Attribute[i], par);
148 146
149 VGAdisablePalette(par); 147 VGAdisablePalette(par);
150} 148}
151 149
152static void vgaHWInit (struct fb_var_screeninfo *var, 150static void vgaHWInit(struct fb_var_screeninfo *var,
153 struct savagefb_par *par, 151 struct savagefb_par *par,
154 struct xtimings *timings) 152 struct xtimings *timings,
153 struct savage_reg *reg)
155{ 154{
156 par->MiscOutReg = 0x23; 155 reg->MiscOutReg = 0x23;
157 156
158 if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT)) 157 if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT))
159 par->MiscOutReg |= 0x40; 158 reg->MiscOutReg |= 0x40;
160 159
161 if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT)) 160 if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT))
162 par->MiscOutReg |= 0x80; 161 reg->MiscOutReg |= 0x80;
163 162
164 /* 163 /*
165 * Time Sequencer 164 * Time Sequencer
166 */ 165 */
167 par->Sequencer[0x00] = 0x00; 166 reg->Sequencer[0x00] = 0x00;
168 par->Sequencer[0x01] = 0x01; 167 reg->Sequencer[0x01] = 0x01;
169 par->Sequencer[0x02] = 0x0F; 168 reg->Sequencer[0x02] = 0x0F;
170 par->Sequencer[0x03] = 0x00; /* Font select */ 169 reg->Sequencer[0x03] = 0x00; /* Font select */
171 par->Sequencer[0x04] = 0x0E; /* Misc */ 170 reg->Sequencer[0x04] = 0x0E; /* Misc */
172 171
173 /* 172 /*
174 * CRTC Controller 173 * CRTC Controller
175 */ 174 */
176 par->CRTC[0x00] = (timings->HTotal >> 3) - 5; 175 reg->CRTC[0x00] = (timings->HTotal >> 3) - 5;
177 par->CRTC[0x01] = (timings->HDisplay >> 3) - 1; 176 reg->CRTC[0x01] = (timings->HDisplay >> 3) - 1;
178 par->CRTC[0x02] = (timings->HSyncStart >> 3) - 1; 177 reg->CRTC[0x02] = (timings->HSyncStart >> 3) - 1;
179 par->CRTC[0x03] = (((timings->HSyncEnd >> 3) - 1) & 0x1f) | 0x80; 178 reg->CRTC[0x03] = (((timings->HSyncEnd >> 3) - 1) & 0x1f) | 0x80;
180 par->CRTC[0x04] = (timings->HSyncStart >> 3); 179 reg->CRTC[0x04] = (timings->HSyncStart >> 3);
181 par->CRTC[0x05] = ((((timings->HSyncEnd >> 3) - 1) & 0x20) << 2) | 180 reg->CRTC[0x05] = ((((timings->HSyncEnd >> 3) - 1) & 0x20) << 2) |
182 (((timings->HSyncEnd >> 3)) & 0x1f); 181 (((timings->HSyncEnd >> 3)) & 0x1f);
183 par->CRTC[0x06] = (timings->VTotal - 2) & 0xFF; 182 reg->CRTC[0x06] = (timings->VTotal - 2) & 0xFF;
184 par->CRTC[0x07] = (((timings->VTotal - 2) & 0x100) >> 8) | 183 reg->CRTC[0x07] = (((timings->VTotal - 2) & 0x100) >> 8) |
185 (((timings->VDisplay - 1) & 0x100) >> 7) | 184 (((timings->VDisplay - 1) & 0x100) >> 7) |
186 ((timings->VSyncStart & 0x100) >> 6) | 185 ((timings->VSyncStart & 0x100) >> 6) |
187 (((timings->VSyncStart - 1) & 0x100) >> 5) | 186 (((timings->VSyncStart - 1) & 0x100) >> 5) |
@@ -189,27 +188,27 @@ static void vgaHWInit (struct fb_var_screeninfo *var,
189 (((timings->VTotal - 2) & 0x200) >> 4) | 188 (((timings->VTotal - 2) & 0x200) >> 4) |
190 (((timings->VDisplay - 1) & 0x200) >> 3) | 189 (((timings->VDisplay - 1) & 0x200) >> 3) |
191 ((timings->VSyncStart & 0x200) >> 2); 190 ((timings->VSyncStart & 0x200) >> 2);
192 par->CRTC[0x08] = 0x00; 191 reg->CRTC[0x08] = 0x00;
193 par->CRTC[0x09] = (((timings->VSyncStart - 1) & 0x200) >> 4) | 0x40; 192 reg->CRTC[0x09] = (((timings->VSyncStart - 1) & 0x200) >> 4) | 0x40;
194 193
195 if (timings->dblscan) 194 if (timings->dblscan)
196 par->CRTC[0x09] |= 0x80; 195 reg->CRTC[0x09] |= 0x80;
197 196
198 par->CRTC[0x0a] = 0x00; 197 reg->CRTC[0x0a] = 0x00;
199 par->CRTC[0x0b] = 0x00; 198 reg->CRTC[0x0b] = 0x00;
200 par->CRTC[0x0c] = 0x00; 199 reg->CRTC[0x0c] = 0x00;
201 par->CRTC[0x0d] = 0x00; 200 reg->CRTC[0x0d] = 0x00;
202 par->CRTC[0x0e] = 0x00; 201 reg->CRTC[0x0e] = 0x00;
203 par->CRTC[0x0f] = 0x00; 202 reg->CRTC[0x0f] = 0x00;
204 par->CRTC[0x10] = timings->VSyncStart & 0xff; 203 reg->CRTC[0x10] = timings->VSyncStart & 0xff;
205 par->CRTC[0x11] = (timings->VSyncEnd & 0x0f) | 0x20; 204 reg->CRTC[0x11] = (timings->VSyncEnd & 0x0f) | 0x20;
206 par->CRTC[0x12] = (timings->VDisplay - 1) & 0xff; 205 reg->CRTC[0x12] = (timings->VDisplay - 1) & 0xff;
207 par->CRTC[0x13] = var->xres_virtual >> 4; 206 reg->CRTC[0x13] = var->xres_virtual >> 4;
208 par->CRTC[0x14] = 0x00; 207 reg->CRTC[0x14] = 0x00;
209 par->CRTC[0x15] = (timings->VSyncStart - 1) & 0xff; 208 reg->CRTC[0x15] = (timings->VSyncStart - 1) & 0xff;
210 par->CRTC[0x16] = (timings->VSyncEnd - 1) & 0xff; 209 reg->CRTC[0x16] = (timings->VSyncEnd - 1) & 0xff;
211 par->CRTC[0x17] = 0xc3; 210 reg->CRTC[0x17] = 0xc3;
212 par->CRTC[0x18] = 0xff; 211 reg->CRTC[0x18] = 0xff;
213 212
214 /* 213 /*
215 * are these unnecessary? 214 * are these unnecessary?
@@ -220,38 +219,38 @@ static void vgaHWInit (struct fb_var_screeninfo *var,
220 /* 219 /*
221 * Graphics Display Controller 220 * Graphics Display Controller
222 */ 221 */
223 par->Graphics[0x00] = 0x00; 222 reg->Graphics[0x00] = 0x00;
224 par->Graphics[0x01] = 0x00; 223 reg->Graphics[0x01] = 0x00;
225 par->Graphics[0x02] = 0x00; 224 reg->Graphics[0x02] = 0x00;
226 par->Graphics[0x03] = 0x00; 225 reg->Graphics[0x03] = 0x00;
227 par->Graphics[0x04] = 0x00; 226 reg->Graphics[0x04] = 0x00;
228 par->Graphics[0x05] = 0x40; 227 reg->Graphics[0x05] = 0x40;
229 par->Graphics[0x06] = 0x05; /* only map 64k VGA memory !!!! */ 228 reg->Graphics[0x06] = 0x05; /* only map 64k VGA memory !!!! */
230 par->Graphics[0x07] = 0x0F; 229 reg->Graphics[0x07] = 0x0F;
231 par->Graphics[0x08] = 0xFF; 230 reg->Graphics[0x08] = 0xFF;
232 231
233 232
234 par->Attribute[0x00] = 0x00; /* standard colormap translation */ 233 reg->Attribute[0x00] = 0x00; /* standard colormap translation */
235 par->Attribute[0x01] = 0x01; 234 reg->Attribute[0x01] = 0x01;
236 par->Attribute[0x02] = 0x02; 235 reg->Attribute[0x02] = 0x02;
237 par->Attribute[0x03] = 0x03; 236 reg->Attribute[0x03] = 0x03;
238 par->Attribute[0x04] = 0x04; 237 reg->Attribute[0x04] = 0x04;
239 par->Attribute[0x05] = 0x05; 238 reg->Attribute[0x05] = 0x05;
240 par->Attribute[0x06] = 0x06; 239 reg->Attribute[0x06] = 0x06;
241 par->Attribute[0x07] = 0x07; 240 reg->Attribute[0x07] = 0x07;
242 par->Attribute[0x08] = 0x08; 241 reg->Attribute[0x08] = 0x08;
243 par->Attribute[0x09] = 0x09; 242 reg->Attribute[0x09] = 0x09;
244 par->Attribute[0x0a] = 0x0A; 243 reg->Attribute[0x0a] = 0x0A;
245 par->Attribute[0x0b] = 0x0B; 244 reg->Attribute[0x0b] = 0x0B;
246 par->Attribute[0x0c] = 0x0C; 245 reg->Attribute[0x0c] = 0x0C;
247 par->Attribute[0x0d] = 0x0D; 246 reg->Attribute[0x0d] = 0x0D;
248 par->Attribute[0x0e] = 0x0E; 247 reg->Attribute[0x0e] = 0x0E;
249 par->Attribute[0x0f] = 0x0F; 248 reg->Attribute[0x0f] = 0x0F;
250 par->Attribute[0x10] = 0x41; 249 reg->Attribute[0x10] = 0x41;
251 par->Attribute[0x11] = 0xFF; 250 reg->Attribute[0x11] = 0xFF;
252 par->Attribute[0x12] = 0x0F; 251 reg->Attribute[0x12] = 0x0F;
253 par->Attribute[0x13] = 0x00; 252 reg->Attribute[0x13] = 0x00;
254 par->Attribute[0x14] = 0x00; 253 reg->Attribute[0x14] = 0x00;
255} 254}
256 255
257/* -------------------- Hardware specific routines ------------------------- */ 256/* -------------------- Hardware specific routines ------------------------- */
@@ -304,15 +303,15 @@ savage2000_waitidle(struct savagefb_par *par)
304 while ((savage_in32(0x48C60, par) & 0x009fffff)); 303 while ((savage_in32(0x48C60, par) & 0x009fffff));
305} 304}
306 305
307 306#ifdef CONFIG_FB_SAVAGE_ACCEL
308static void 307static void
309SavageSetup2DEngine (struct savagefb_par *par) 308SavageSetup2DEngine(struct savagefb_par *par)
310{ 309{
311 unsigned long GlobalBitmapDescriptor; 310 unsigned long GlobalBitmapDescriptor;
312 311
313 GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE; 312 GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE;
314 BCI_BD_SET_BPP (GlobalBitmapDescriptor, par->depth); 313 BCI_BD_SET_BPP(GlobalBitmapDescriptor, par->depth);
315 BCI_BD_SET_STRIDE (GlobalBitmapDescriptor, par->vwidth); 314 BCI_BD_SET_STRIDE(GlobalBitmapDescriptor, par->vwidth);
316 315
317 switch(par->chip) { 316 switch(par->chip) {
318 case S3_SAVAGE3D: 317 case S3_SAVAGE3D:
@@ -361,32 +360,48 @@ SavageSetup2DEngine (struct savagefb_par *par)
361 vga_out8(0x3d5, 0x0c, par); 360 vga_out8(0x3d5, 0x0c, par);
362 361
363 /* Set stride to use GBD. */ 362 /* Set stride to use GBD. */
364 vga_out8 (0x3d4, 0x50, par); 363 vga_out8(0x3d4, 0x50, par);
365 vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par); 364 vga_out8(0x3d5, vga_in8(0x3d5, par) | 0xC1, par);
366 365
367 /* Enable 2D engine. */ 366 /* Enable 2D engine. */
368 vga_out8 (0x3d4, 0x40, par); 367 vga_out8(0x3d4, 0x40, par);
369 vga_out8 (0x3d5, 0x01, par); 368 vga_out8(0x3d5, 0x01, par);
370 369
371 savage_out32 (MONO_PAT_0, ~0, par); 370 savage_out32(MONO_PAT_0, ~0, par);
372 savage_out32 (MONO_PAT_1, ~0, par); 371 savage_out32(MONO_PAT_1, ~0, par);
373 372
374 /* Setup plane masks */ 373 /* Setup plane masks */
375 savage_out32 (0x8128, ~0, par); /* enable all write planes */ 374 savage_out32(0x8128, ~0, par); /* enable all write planes */
376 savage_out32 (0x812C, ~0, par); /* enable all read planes */ 375 savage_out32(0x812C, ~0, par); /* enable all read planes */
377 savage_out16 (0x8134, 0x27, par); 376 savage_out16(0x8134, 0x27, par);
378 savage_out16 (0x8136, 0x07, par); 377 savage_out16(0x8136, 0x07, par);
379 378
380 /* Now set the GBD */ 379 /* Now set the GBD */
381 par->bci_ptr = 0; 380 par->bci_ptr = 0;
382 par->SavageWaitFifo (par, 4); 381 par->SavageWaitFifo(par, 4);
383 382
384 BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD1 ); 383 BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD1);
385 BCI_SEND( 0 ); 384 BCI_SEND(0);
386 BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD2 ); 385 BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2);
387 BCI_SEND( GlobalBitmapDescriptor ); 386 BCI_SEND(GlobalBitmapDescriptor);
388} 387}
389 388
389static void savagefb_set_clip(struct fb_info *info)
390{
391 struct savagefb_par *par = info->par;
392 int cmd;
393
394 cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW;
395 par->bci_ptr = 0;
396 par->SavageWaitFifo(par,3);
397 BCI_SEND(cmd);
398 BCI_SEND(BCI_CLIP_TL(0, 0));
399 BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff));
400}
401#else
402static void SavageSetup2DEngine(struct savagefb_par *par) {}
403
404#endif
390 405
391static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, 406static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1,
392 int min_n2, int max_n2, long freq_min, 407 int min_n2, int max_n2, long freq_min,
@@ -398,11 +413,11 @@ static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1,
398 unsigned char n1, n2, best_n1=16+2, best_n2=2, best_m=125+2; 413 unsigned char n1, n2, best_n1=16+2, best_n2=2, best_m=125+2;
399 414
400 if (freq < freq_min / (1 << max_n2)) { 415 if (freq < freq_min / (1 << max_n2)) {
401 printk (KERN_ERR "invalid frequency %ld Khz\n", freq); 416 printk(KERN_ERR "invalid frequency %ld Khz\n", freq);
402 freq = freq_min / (1 << max_n2); 417 freq = freq_min / (1 << max_n2);
403 } 418 }
404 if (freq > freq_max / (1 << min_n2)) { 419 if (freq > freq_max / (1 << min_n2)) {
405 printk (KERN_ERR "invalid frequency %ld Khz\n", freq); 420 printk(KERN_ERR "invalid frequency %ld Khz\n", freq);
406 freq = freq_max / (1 << min_n2); 421 freq = freq_max / (1 << min_n2);
407 } 422 }
408 423
@@ -453,12 +468,12 @@ static int common_calc_clock(long freq, int min_m, int min_n1, int max_n1,
453 BASE_FREQ; 468 BASE_FREQ;
454 if (m < min_m + 2 || m > 127+2) 469 if (m < min_m + 2 || m > 127+2)
455 continue; 470 continue;
456 if((m * BASE_FREQ >= freq_min * n1) && 471 if ((m * BASE_FREQ >= freq_min * n1) &&
457 (m * BASE_FREQ <= freq_max * n1)) { 472 (m * BASE_FREQ <= freq_max * n1)) {
458 diff = freq * (1 << n2) * n1 - BASE_FREQ * m; 473 diff = freq * (1 << n2) * n1 - BASE_FREQ * m;
459 if(diff < 0) 474 if (diff < 0)
460 diff = -diff; 475 diff = -diff;
461 if(diff < best_diff) { 476 if (diff < best_diff) {
462 best_diff = diff; 477 best_diff = diff;
463 best_m = m; 478 best_m = m;
464 best_n1 = n1; 479 best_n1 = n1;
@@ -468,7 +483,7 @@ static int common_calc_clock(long freq, int min_m, int min_n1, int max_n1,
468 } 483 }
469 } 484 }
470 485
471 if(max_n1 == 63) 486 if (max_n1 == 63)
472 *ndiv = (best_n1 - 2) | (best_n2 << 6); 487 *ndiv = (best_n1 - 2) | (best_n2 << 6);
473 else 488 else
474 *ndiv = (best_n1 - 2) | (best_n2 << 5); 489 *ndiv = (best_n1 - 2) | (best_n2 << 5);
@@ -488,23 +503,23 @@ static void SavagePrintRegs(void)
488 int vgaCRReg = 0x3d5; 503 int vgaCRReg = 0x3d5;
489 504
490 printk(KERN_DEBUG "SR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE " 505 printk(KERN_DEBUG "SR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE "
491 "xF" ); 506 "xF");
492 507
493 for( i = 0; i < 0x70; i++ ) { 508 for (i = 0; i < 0x70; i++) {
494 if( !(i % 16) ) 509 if (!(i % 16))
495 printk(KERN_DEBUG "\nSR%xx ", i >> 4 ); 510 printk(KERN_DEBUG "\nSR%xx ", i >> 4);
496 vga_out8( 0x3c4, i, par); 511 vga_out8(0x3c4, i, par);
497 printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) ); 512 printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par));
498 } 513 }
499 514
500 printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC " 515 printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC "
501 "xD xE xF" ); 516 "xD xE xF");
502 517
503 for( i = 0; i < 0xB7; i++ ) { 518 for (i = 0; i < 0xB7; i++) {
504 if( !(i % 16) ) 519 if (!(i % 16))
505 printk(KERN_DEBUG "\nCR%xx ", i >> 4 ); 520 printk(KERN_DEBUG "\nCR%xx ", i >> 4);
506 vga_out8( vgaCRIndex, i, par); 521 vga_out8(vgaCRIndex, i, par);
507 printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) ); 522 printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par));
508 } 523 }
509 524
510 printk(KERN_DEBUG "\n\n"); 525 printk(KERN_DEBUG "\n\n");
@@ -513,156 +528,309 @@ static void SavagePrintRegs(void)
513 528
514/* --------------------------------------------------------------------- */ 529/* --------------------------------------------------------------------- */
515 530
516static void savage_get_default_par(struct savagefb_par *par) 531static void savage_get_default_par(struct savagefb_par *par, struct savage_reg *reg)
517{ 532{
518 unsigned char cr3a, cr53, cr66; 533 unsigned char cr3a, cr53, cr66;
519 534
520 vga_out16 (0x3d4, 0x4838, par); 535 vga_out16(0x3d4, 0x4838, par);
521 vga_out16 (0x3d4, 0xa039, par); 536 vga_out16(0x3d4, 0xa039, par);
522 vga_out16 (0x3c4, 0x0608, par); 537 vga_out16(0x3c4, 0x0608, par);
523 538
524 vga_out8 (0x3d4, 0x66, par); 539 vga_out8(0x3d4, 0x66, par);
525 cr66 = vga_in8 (0x3d5, par); 540 cr66 = vga_in8(0x3d5, par);
526 vga_out8 (0x3d5, cr66 | 0x80, par); 541 vga_out8(0x3d5, cr66 | 0x80, par);
527 vga_out8 (0x3d4, 0x3a, par); 542 vga_out8(0x3d4, 0x3a, par);
528 cr3a = vga_in8 (0x3d5, par); 543 cr3a = vga_in8(0x3d5, par);
529 vga_out8 (0x3d5, cr3a | 0x80, par); 544 vga_out8(0x3d5, cr3a | 0x80, par);
530 vga_out8 (0x3d4, 0x53, par); 545 vga_out8(0x3d4, 0x53, par);
531 cr53 = vga_in8 (0x3d5, par); 546 cr53 = vga_in8(0x3d5, par);
532 vga_out8 (0x3d5, cr53 & 0x7f, par); 547 vga_out8(0x3d5, cr53 & 0x7f, par);
533 548
534 vga_out8 (0x3d4, 0x66, par); 549 vga_out8(0x3d4, 0x66, par);
535 vga_out8 (0x3d5, cr66, par); 550 vga_out8(0x3d5, cr66, par);
536 vga_out8 (0x3d4, 0x3a, par); 551 vga_out8(0x3d4, 0x3a, par);
537 vga_out8 (0x3d5, cr3a, par); 552 vga_out8(0x3d5, cr3a, par);
538 553
539 vga_out8 (0x3d4, 0x66, par); 554 vga_out8(0x3d4, 0x66, par);
540 vga_out8 (0x3d5, cr66, par); 555 vga_out8(0x3d5, cr66, par);
541 vga_out8 (0x3d4, 0x3a, par); 556 vga_out8(0x3d4, 0x3a, par);
542 vga_out8 (0x3d5, cr3a, par); 557 vga_out8(0x3d5, cr3a, par);
543 558
544 /* unlock extended seq regs */ 559 /* unlock extended seq regs */
545 vga_out8 (0x3c4, 0x08, par); 560 vga_out8(0x3c4, 0x08, par);
546 par->SR08 = vga_in8 (0x3c5, par); 561 reg->SR08 = vga_in8(0x3c5, par);
547 vga_out8 (0x3c5, 0x06, par); 562 vga_out8(0x3c5, 0x06, par);
548 563
549 /* now save all the extended regs we need */ 564 /* now save all the extended regs we need */
550 vga_out8 (0x3d4, 0x31, par); 565 vga_out8(0x3d4, 0x31, par);
551 par->CR31 = vga_in8 (0x3d5, par); 566 reg->CR31 = vga_in8(0x3d5, par);
552 vga_out8 (0x3d4, 0x32, par); 567 vga_out8(0x3d4, 0x32, par);
553 par->CR32 = vga_in8 (0x3d5, par); 568 reg->CR32 = vga_in8(0x3d5, par);
554 vga_out8 (0x3d4, 0x34, par); 569 vga_out8(0x3d4, 0x34, par);
555 par->CR34 = vga_in8 (0x3d5, par); 570 reg->CR34 = vga_in8(0x3d5, par);
556 vga_out8 (0x3d4, 0x36, par); 571 vga_out8(0x3d4, 0x36, par);
557 par->CR36 = vga_in8 (0x3d5, par); 572 reg->CR36 = vga_in8(0x3d5, par);
558 vga_out8 (0x3d4, 0x3a, par); 573 vga_out8(0x3d4, 0x3a, par);
559 par->CR3A = vga_in8 (0x3d5, par); 574 reg->CR3A = vga_in8(0x3d5, par);
560 vga_out8 (0x3d4, 0x40, par); 575 vga_out8(0x3d4, 0x40, par);
561 par->CR40 = vga_in8 (0x3d5, par); 576 reg->CR40 = vga_in8(0x3d5, par);
562 vga_out8 (0x3d4, 0x42, par); 577 vga_out8(0x3d4, 0x42, par);
563 par->CR42 = vga_in8 (0x3d5, par); 578 reg->CR42 = vga_in8(0x3d5, par);
564 vga_out8 (0x3d4, 0x45, par); 579 vga_out8(0x3d4, 0x45, par);
565 par->CR45 = vga_in8 (0x3d5, par); 580 reg->CR45 = vga_in8(0x3d5, par);
566 vga_out8 (0x3d4, 0x50, par); 581 vga_out8(0x3d4, 0x50, par);
567 par->CR50 = vga_in8 (0x3d5, par); 582 reg->CR50 = vga_in8(0x3d5, par);
568 vga_out8 (0x3d4, 0x51, par); 583 vga_out8(0x3d4, 0x51, par);
569 par->CR51 = vga_in8 (0x3d5, par); 584 reg->CR51 = vga_in8(0x3d5, par);
570 vga_out8 (0x3d4, 0x53, par); 585 vga_out8(0x3d4, 0x53, par);
571 par->CR53 = vga_in8 (0x3d5, par); 586 reg->CR53 = vga_in8(0x3d5, par);
572 vga_out8 (0x3d4, 0x58, par); 587 vga_out8(0x3d4, 0x58, par);
573 par->CR58 = vga_in8 (0x3d5, par); 588 reg->CR58 = vga_in8(0x3d5, par);
574 vga_out8 (0x3d4, 0x60, par); 589 vga_out8(0x3d4, 0x60, par);
575 par->CR60 = vga_in8 (0x3d5, par); 590 reg->CR60 = vga_in8(0x3d5, par);
576 vga_out8 (0x3d4, 0x66, par); 591 vga_out8(0x3d4, 0x66, par);
577 par->CR66 = vga_in8 (0x3d5, par); 592 reg->CR66 = vga_in8(0x3d5, par);
578 vga_out8 (0x3d4, 0x67, par); 593 vga_out8(0x3d4, 0x67, par);
579 par->CR67 = vga_in8 (0x3d5, par); 594 reg->CR67 = vga_in8(0x3d5, par);
580 vga_out8 (0x3d4, 0x68, par); 595 vga_out8(0x3d4, 0x68, par);
581 par->CR68 = vga_in8 (0x3d5, par); 596 reg->CR68 = vga_in8(0x3d5, par);
582 vga_out8 (0x3d4, 0x69, par); 597 vga_out8(0x3d4, 0x69, par);
583 par->CR69 = vga_in8 (0x3d5, par); 598 reg->CR69 = vga_in8(0x3d5, par);
584 vga_out8 (0x3d4, 0x6f, par); 599 vga_out8(0x3d4, 0x6f, par);
585 par->CR6F = vga_in8 (0x3d5, par); 600 reg->CR6F = vga_in8(0x3d5, par);
586 601
587 vga_out8 (0x3d4, 0x33, par); 602 vga_out8(0x3d4, 0x33, par);
588 par->CR33 = vga_in8 (0x3d5, par); 603 reg->CR33 = vga_in8(0x3d5, par);
589 vga_out8 (0x3d4, 0x86, par); 604 vga_out8(0x3d4, 0x86, par);
590 par->CR86 = vga_in8 (0x3d5, par); 605 reg->CR86 = vga_in8(0x3d5, par);
591 vga_out8 (0x3d4, 0x88, par); 606 vga_out8(0x3d4, 0x88, par);
592 par->CR88 = vga_in8 (0x3d5, par); 607 reg->CR88 = vga_in8(0x3d5, par);
593 vga_out8 (0x3d4, 0x90, par); 608 vga_out8(0x3d4, 0x90, par);
594 par->CR90 = vga_in8 (0x3d5, par); 609 reg->CR90 = vga_in8(0x3d5, par);
595 vga_out8 (0x3d4, 0x91, par); 610 vga_out8(0x3d4, 0x91, par);
596 par->CR91 = vga_in8 (0x3d5, par); 611 reg->CR91 = vga_in8(0x3d5, par);
597 vga_out8 (0x3d4, 0xb0, par); 612 vga_out8(0x3d4, 0xb0, par);
598 par->CRB0 = vga_in8 (0x3d5, par) | 0x80; 613 reg->CRB0 = vga_in8(0x3d5, par) | 0x80;
614
615 /* extended mode timing regs */
616 vga_out8(0x3d4, 0x3b, par);
617 reg->CR3B = vga_in8(0x3d5, par);
618 vga_out8(0x3d4, 0x3c, par);
619 reg->CR3C = vga_in8(0x3d5, par);
620 vga_out8(0x3d4, 0x43, par);
621 reg->CR43 = vga_in8(0x3d5, par);
622 vga_out8(0x3d4, 0x5d, par);
623 reg->CR5D = vga_in8(0x3d5, par);
624 vga_out8(0x3d4, 0x5e, par);
625 reg->CR5E = vga_in8(0x3d5, par);
626 vga_out8(0x3d4, 0x65, par);
627 reg->CR65 = vga_in8(0x3d5, par);
628
629 /* save seq extended regs for DCLK PLL programming */
630 vga_out8(0x3c4, 0x0e, par);
631 reg->SR0E = vga_in8(0x3c5, par);
632 vga_out8(0x3c4, 0x0f, par);
633 reg->SR0F = vga_in8(0x3c5, par);
634 vga_out8(0x3c4, 0x10, par);
635 reg->SR10 = vga_in8(0x3c5, par);
636 vga_out8(0x3c4, 0x11, par);
637 reg->SR11 = vga_in8(0x3c5, par);
638 vga_out8(0x3c4, 0x12, par);
639 reg->SR12 = vga_in8(0x3c5, par);
640 vga_out8(0x3c4, 0x13, par);
641 reg->SR13 = vga_in8(0x3c5, par);
642 vga_out8(0x3c4, 0x29, par);
643 reg->SR29 = vga_in8(0x3c5, par);
644
645 vga_out8(0x3c4, 0x15, par);
646 reg->SR15 = vga_in8(0x3c5, par);
647 vga_out8(0x3c4, 0x30, par);
648 reg->SR30 = vga_in8(0x3c5, par);
649 vga_out8(0x3c4, 0x18, par);
650 reg->SR18 = vga_in8(0x3c5, par);
651
652 /* Save flat panel expansion regsters. */
653 if (par->chip == S3_SAVAGE_MX) {
654 int i;
655
656 for (i = 0; i < 8; i++) {
657 vga_out8(0x3c4, 0x54+i, par);
658 reg->SR54[i] = vga_in8(0x3c5, par);
659 }
660 }
661
662 vga_out8(0x3d4, 0x66, par);
663 cr66 = vga_in8(0x3d5, par);
664 vga_out8(0x3d5, cr66 | 0x80, par);
665 vga_out8(0x3d4, 0x3a, par);
666 cr3a = vga_in8(0x3d5, par);
667 vga_out8(0x3d5, cr3a | 0x80, par);
668
669 /* now save MIU regs */
670 if (par->chip != S3_SAVAGE_MX) {
671 reg->MMPR0 = savage_in32(FIFO_CONTROL_REG, par);
672 reg->MMPR1 = savage_in32(MIU_CONTROL_REG, par);
673 reg->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par);
674 reg->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par);
675 }
676
677 vga_out8(0x3d4, 0x3a, par);
678 vga_out8(0x3d5, cr3a, par);
679 vga_out8(0x3d4, 0x66, par);
680 vga_out8(0x3d5, cr66, par);
681}
682
683static void savage_set_default_par(struct savagefb_par *par,
684 struct savage_reg *reg)
685{
686 unsigned char cr3a, cr53, cr66;
687
688 vga_out16(0x3d4, 0x4838, par);
689 vga_out16(0x3d4, 0xa039, par);
690 vga_out16(0x3c4, 0x0608, par);
691
692 vga_out8(0x3d4, 0x66, par);
693 cr66 = vga_in8(0x3d5, par);
694 vga_out8(0x3d5, cr66 | 0x80, par);
695 vga_out8(0x3d4, 0x3a, par);
696 cr3a = vga_in8(0x3d5, par);
697 vga_out8(0x3d5, cr3a | 0x80, par);
698 vga_out8(0x3d4, 0x53, par);
699 cr53 = vga_in8(0x3d5, par);
700 vga_out8(0x3d5, cr53 & 0x7f, par);
701
702 vga_out8(0x3d4, 0x66, par);
703 vga_out8(0x3d5, cr66, par);
704 vga_out8(0x3d4, 0x3a, par);
705 vga_out8(0x3d5, cr3a, par);
706
707 vga_out8(0x3d4, 0x66, par);
708 vga_out8(0x3d5, cr66, par);
709 vga_out8(0x3d4, 0x3a, par);
710 vga_out8(0x3d5, cr3a, par);
711
712 /* unlock extended seq regs */
713 vga_out8(0x3c4, 0x08, par);
714 vga_out8(0x3c5, reg->SR08, par);
715 vga_out8(0x3c5, 0x06, par);
716
717 /* now restore all the extended regs we need */
718 vga_out8(0x3d4, 0x31, par);
719 vga_out8(0x3d5, reg->CR31, par);
720 vga_out8(0x3d4, 0x32, par);
721 vga_out8(0x3d5, reg->CR32, par);
722 vga_out8(0x3d4, 0x34, par);
723 vga_out8(0x3d5, reg->CR34, par);
724 vga_out8(0x3d4, 0x36, par);
725 vga_out8(0x3d5,reg->CR36, par);
726 vga_out8(0x3d4, 0x3a, par);
727 vga_out8(0x3d5, reg->CR3A, par);
728 vga_out8(0x3d4, 0x40, par);
729 vga_out8(0x3d5, reg->CR40, par);
730 vga_out8(0x3d4, 0x42, par);
731 vga_out8(0x3d5, reg->CR42, par);
732 vga_out8(0x3d4, 0x45, par);
733 vga_out8(0x3d5, reg->CR45, par);
734 vga_out8(0x3d4, 0x50, par);
735 vga_out8(0x3d5, reg->CR50, par);
736 vga_out8(0x3d4, 0x51, par);
737 vga_out8(0x3d5, reg->CR51, par);
738 vga_out8(0x3d4, 0x53, par);
739 vga_out8(0x3d5, reg->CR53, par);
740 vga_out8(0x3d4, 0x58, par);
741 vga_out8(0x3d5, reg->CR58, par);
742 vga_out8(0x3d4, 0x60, par);
743 vga_out8(0x3d5, reg->CR60, par);
744 vga_out8(0x3d4, 0x66, par);
745 vga_out8(0x3d5, reg->CR66, par);
746 vga_out8(0x3d4, 0x67, par);
747 vga_out8(0x3d5, reg->CR67, par);
748 vga_out8(0x3d4, 0x68, par);
749 vga_out8(0x3d5, reg->CR68, par);
750 vga_out8(0x3d4, 0x69, par);
751 vga_out8(0x3d5, reg->CR69, par);
752 vga_out8(0x3d4, 0x6f, par);
753 vga_out8(0x3d5, reg->CR6F, par);
754
755 vga_out8(0x3d4, 0x33, par);
756 vga_out8(0x3d5, reg->CR33, par);
757 vga_out8(0x3d4, 0x86, par);
758 vga_out8(0x3d5, reg->CR86, par);
759 vga_out8(0x3d4, 0x88, par);
760 vga_out8(0x3d5, reg->CR88, par);
761 vga_out8(0x3d4, 0x90, par);
762 vga_out8(0x3d5, reg->CR90, par);
763 vga_out8(0x3d4, 0x91, par);
764 vga_out8(0x3d5, reg->CR91, par);
765 vga_out8(0x3d4, 0xb0, par);
766 vga_out8(0x3d5, reg->CRB0, par);
599 767
600 /* extended mode timing regs */ 768 /* extended mode timing regs */
601 vga_out8 (0x3d4, 0x3b, par); 769 vga_out8(0x3d4, 0x3b, par);
602 par->CR3B = vga_in8 (0x3d5, par); 770 vga_out8(0x3d5, reg->CR3B, par);
603 vga_out8 (0x3d4, 0x3c, par); 771 vga_out8(0x3d4, 0x3c, par);
604 par->CR3C = vga_in8 (0x3d5, par); 772 vga_out8(0x3d5, reg->CR3C, par);
605 vga_out8 (0x3d4, 0x43, par); 773 vga_out8(0x3d4, 0x43, par);
606 par->CR43 = vga_in8 (0x3d5, par); 774 vga_out8(0x3d5, reg->CR43, par);
607 vga_out8 (0x3d4, 0x5d, par); 775 vga_out8(0x3d4, 0x5d, par);
608 par->CR5D = vga_in8 (0x3d5, par); 776 vga_out8(0x3d5, reg->CR5D, par);
609 vga_out8 (0x3d4, 0x5e, par); 777 vga_out8(0x3d4, 0x5e, par);
610 par->CR5E = vga_in8 (0x3d5, par); 778 vga_out8(0x3d5, reg->CR5E, par);
611 vga_out8 (0x3d4, 0x65, par); 779 vga_out8(0x3d4, 0x65, par);
612 par->CR65 = vga_in8 (0x3d5, par); 780 vga_out8(0x3d5, reg->CR65, par);
613 781
614 /* save seq extended regs for DCLK PLL programming */ 782 /* save seq extended regs for DCLK PLL programming */
615 vga_out8 (0x3c4, 0x0e, par); 783 vga_out8(0x3c4, 0x0e, par);
616 par->SR0E = vga_in8 (0x3c5, par); 784 vga_out8(0x3c5, reg->SR0E, par);
617 vga_out8 (0x3c4, 0x0f, par); 785 vga_out8(0x3c4, 0x0f, par);
618 par->SR0F = vga_in8 (0x3c5, par); 786 vga_out8(0x3c5, reg->SR0F, par);
619 vga_out8 (0x3c4, 0x10, par); 787 vga_out8(0x3c4, 0x10, par);
620 par->SR10 = vga_in8 (0x3c5, par); 788 vga_out8(0x3c5, reg->SR10, par);
621 vga_out8 (0x3c4, 0x11, par); 789 vga_out8(0x3c4, 0x11, par);
622 par->SR11 = vga_in8 (0x3c5, par); 790 vga_out8(0x3c5, reg->SR11, par);
623 vga_out8 (0x3c4, 0x12, par); 791 vga_out8(0x3c4, 0x12, par);
624 par->SR12 = vga_in8 (0x3c5, par); 792 vga_out8(0x3c5, reg->SR12, par);
625 vga_out8 (0x3c4, 0x13, par); 793 vga_out8(0x3c4, 0x13, par);
626 par->SR13 = vga_in8 (0x3c5, par); 794 vga_out8(0x3c5, reg->SR13, par);
627 vga_out8 (0x3c4, 0x29, par); 795 vga_out8(0x3c4, 0x29, par);
628 par->SR29 = vga_in8 (0x3c5, par); 796 vga_out8(0x3c5, reg->SR29, par);
629 797
630 vga_out8 (0x3c4, 0x15, par); 798 vga_out8(0x3c4, 0x15, par);
631 par->SR15 = vga_in8 (0x3c5, par); 799 vga_out8(0x3c5, reg->SR15, par);
632 vga_out8 (0x3c4, 0x30, par); 800 vga_out8(0x3c4, 0x30, par);
633 par->SR30 = vga_in8 (0x3c5, par); 801 vga_out8(0x3c5, reg->SR30, par);
634 vga_out8 (0x3c4, 0x18, par); 802 vga_out8(0x3c4, 0x18, par);
635 par->SR18 = vga_in8 (0x3c5, par); 803 vga_out8(0x3c5, reg->SR18, par);
636 804
637 /* Save flat panel expansion regsters. */ 805 /* Save flat panel expansion regsters. */
638 if (par->chip == S3_SAVAGE_MX) { 806 if (par->chip == S3_SAVAGE_MX) {
639 int i; 807 int i;
640 808
641 for (i = 0; i < 8; i++) { 809 for (i = 0; i < 8; i++) {
642 vga_out8 (0x3c4, 0x54+i, par); 810 vga_out8(0x3c4, 0x54+i, par);
643 par->SR54[i] = vga_in8 (0x3c5, par); 811 vga_out8(0x3c5, reg->SR54[i], par);
644 } 812 }
645 } 813 }
646 814
647 vga_out8 (0x3d4, 0x66, par); 815 vga_out8(0x3d4, 0x66, par);
648 cr66 = vga_in8 (0x3d5, par); 816 cr66 = vga_in8(0x3d5, par);
649 vga_out8 (0x3d5, cr66 | 0x80, par); 817 vga_out8(0x3d5, cr66 | 0x80, par);
650 vga_out8 (0x3d4, 0x3a, par); 818 vga_out8(0x3d4, 0x3a, par);
651 cr3a = vga_in8 (0x3d5, par); 819 cr3a = vga_in8(0x3d5, par);
652 vga_out8 (0x3d5, cr3a | 0x80, par); 820 vga_out8(0x3d5, cr3a | 0x80, par);
653 821
654 /* now save MIU regs */ 822 /* now save MIU regs */
655 if (par->chip != S3_SAVAGE_MX) { 823 if (par->chip != S3_SAVAGE_MX) {
656 par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par); 824 savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par);
657 par->MMPR1 = savage_in32(MIU_CONTROL_REG, par); 825 savage_out32(MIU_CONTROL_REG, reg->MMPR1, par);
658 par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par); 826 savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par);
659 par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par); 827 savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par);
660 } 828 }
661 829
662 vga_out8 (0x3d4, 0x3a, par); 830 vga_out8(0x3d4, 0x3a, par);
663 vga_out8 (0x3d5, cr3a, par); 831 vga_out8(0x3d5, cr3a, par);
664 vga_out8 (0x3d4, 0x66, par); 832 vga_out8(0x3d4, 0x66, par);
665 vga_out8 (0x3d5, cr66, par); 833 vga_out8(0x3d5, cr66, par);
666} 834}
667 835
668static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) 836static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -683,8 +851,8 @@ static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode
683 var->vmode = modedb->vmode; 851 var->vmode = modedb->vmode;
684} 852}
685 853
686static int savagefb_check_var (struct fb_var_screeninfo *var, 854static int savagefb_check_var(struct fb_var_screeninfo *var,
687 struct fb_info *info) 855 struct fb_info *info)
688{ 856{
689 struct savagefb_par *par = info->par; 857 struct savagefb_par *par = info->par;
690 int memlen, vramlen, mode_valid = 0; 858 int memlen, vramlen, mode_valid = 0;
@@ -750,10 +918,10 @@ static int savagefb_check_var (struct fb_var_screeninfo *var,
750 if (par->SavagePanelWidth && 918 if (par->SavagePanelWidth &&
751 (var->xres > par->SavagePanelWidth || 919 (var->xres > par->SavagePanelWidth ||
752 var->yres > par->SavagePanelHeight)) { 920 var->yres > par->SavagePanelHeight)) {
753 printk (KERN_INFO "Mode (%dx%d) larger than the LCD panel " 921 printk(KERN_INFO "Mode (%dx%d) larger than the LCD panel "
754 "(%dx%d)\n", var->xres, var->yres, 922 "(%dx%d)\n", var->xres, var->yres,
755 par->SavagePanelWidth, 923 par->SavagePanelWidth,
756 par->SavagePanelHeight); 924 par->SavagePanelHeight);
757 return -1; 925 return -1;
758 } 926 }
759 927
@@ -788,8 +956,9 @@ static int savagefb_check_var (struct fb_var_screeninfo *var,
788} 956}
789 957
790 958
791static int savagefb_decode_var (struct fb_var_screeninfo *var, 959static int savagefb_decode_var(struct fb_var_screeninfo *var,
792 struct savagefb_par *par) 960 struct savagefb_par *par,
961 struct savage_reg *reg)
793{ 962{
794 struct xtimings timings; 963 struct xtimings timings;
795 int width, dclk, i, j; /*, refresh; */ 964 int width, dclk, i, j; /*, refresh; */
@@ -799,7 +968,7 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
799 968
800 DBG("savagefb_decode_var"); 969 DBG("savagefb_decode_var");
801 970
802 memset (&timings, 0, sizeof(timings)); 971 memset(&timings, 0, sizeof(timings));
803 972
804 if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */ 973 if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */
805 timings.Clock = 1000000000 / pixclock; 974 timings.Clock = 1000000000 / pixclock;
@@ -831,39 +1000,39 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
831 * This will allocate the datastructure and initialize all of the 1000 * This will allocate the datastructure and initialize all of the
832 * generic VGA registers. 1001 * generic VGA registers.
833 */ 1002 */
834 vgaHWInit (var, par, &timings); 1003 vgaHWInit(var, par, &timings, reg);
835 1004
836 /* We need to set CR67 whether or not we use the BIOS. */ 1005 /* We need to set CR67 whether or not we use the BIOS. */
837 1006
838 dclk = timings.Clock; 1007 dclk = timings.Clock;
839 par->CR67 = 0x00; 1008 reg->CR67 = 0x00;
840 1009
841 switch( var->bits_per_pixel ) { 1010 switch(var->bits_per_pixel) {
842 case 8: 1011 case 8:
843 if( (par->chip == S3_SAVAGE2000) && (dclk >= 230000) ) 1012 if ((par->chip == S3_SAVAGE2000) && (dclk >= 230000))
844 par->CR67 = 0x10; /* 8bpp, 2 pixels/clock */ 1013 reg->CR67 = 0x10; /* 8bpp, 2 pixels/clock */
845 else 1014 else
846 par->CR67 = 0x00; /* 8bpp, 1 pixel/clock */ 1015 reg->CR67 = 0x00; /* 8bpp, 1 pixel/clock */
847 break; 1016 break;
848 case 15: 1017 case 15:
849 if ( S3_SAVAGE_MOBILE_SERIES(par->chip) || 1018 if (S3_SAVAGE_MOBILE_SERIES(par->chip) ||
850 ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) ) 1019 ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)))
851 par->CR67 = 0x30; /* 15bpp, 2 pixel/clock */ 1020 reg->CR67 = 0x30; /* 15bpp, 2 pixel/clock */
852 else 1021 else
853 par->CR67 = 0x20; /* 15bpp, 1 pixels/clock */ 1022 reg->CR67 = 0x20; /* 15bpp, 1 pixels/clock */
854 break; 1023 break;
855 case 16: 1024 case 16:
856 if( S3_SAVAGE_MOBILE_SERIES(par->chip) || 1025 if (S3_SAVAGE_MOBILE_SERIES(par->chip) ||
857 ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) ) 1026 ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)))
858 par->CR67 = 0x50; /* 16bpp, 2 pixel/clock */ 1027 reg->CR67 = 0x50; /* 16bpp, 2 pixel/clock */
859 else 1028 else
860 par->CR67 = 0x40; /* 16bpp, 1 pixels/clock */ 1029 reg->CR67 = 0x40; /* 16bpp, 1 pixels/clock */
861 break; 1030 break;
862 case 24: 1031 case 24:
863 par->CR67 = 0x70; 1032 reg->CR67 = 0x70;
864 break; 1033 break;
865 case 32: 1034 case 32:
866 par->CR67 = 0xd0; 1035 reg->CR67 = 0xd0;
867 break; 1036 break;
868 } 1037 }
869 1038
@@ -872,61 +1041,61 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
872 * match. Fall back to traditional register-crunching. 1041 * match. Fall back to traditional register-crunching.
873 */ 1042 */
874 1043
875 vga_out8 (0x3d4, 0x3a, par); 1044 vga_out8(0x3d4, 0x3a, par);
876 tmp = vga_in8 (0x3d5, par); 1045 tmp = vga_in8(0x3d5, par);
877 if (1 /*FIXME:psav->pci_burst*/) 1046 if (1 /*FIXME:psav->pci_burst*/)
878 par->CR3A = (tmp & 0x7f) | 0x15; 1047 reg->CR3A = (tmp & 0x7f) | 0x15;
879 else 1048 else
880 par->CR3A = tmp | 0x95; 1049 reg->CR3A = tmp | 0x95;
881 1050
882 par->CR53 = 0x00; 1051 reg->CR53 = 0x00;
883 par->CR31 = 0x8c; 1052 reg->CR31 = 0x8c;
884 par->CR66 = 0x89; 1053 reg->CR66 = 0x89;
885 1054
886 vga_out8 (0x3d4, 0x58, par); 1055 vga_out8(0x3d4, 0x58, par);
887 par->CR58 = vga_in8 (0x3d5, par) & 0x80; 1056 reg->CR58 = vga_in8(0x3d5, par) & 0x80;
888 par->CR58 |= 0x13; 1057 reg->CR58 |= 0x13;
889 1058
890 par->SR15 = 0x03 | 0x80; 1059 reg->SR15 = 0x03 | 0x80;
891 par->SR18 = 0x00; 1060 reg->SR18 = 0x00;
892 par->CR43 = par->CR45 = par->CR65 = 0x00; 1061 reg->CR43 = reg->CR45 = reg->CR65 = 0x00;
893 1062
894 vga_out8 (0x3d4, 0x40, par); 1063 vga_out8(0x3d4, 0x40, par);
895 par->CR40 = vga_in8 (0x3d5, par) & ~0x01; 1064 reg->CR40 = vga_in8(0x3d5, par) & ~0x01;
896 1065
897 par->MMPR0 = 0x010400; 1066 reg->MMPR0 = 0x010400;
898 par->MMPR1 = 0x00; 1067 reg->MMPR1 = 0x00;
899 par->MMPR2 = 0x0808; 1068 reg->MMPR2 = 0x0808;
900 par->MMPR3 = 0x08080810; 1069 reg->MMPR3 = 0x08080810;
901 1070
902 SavageCalcClock (dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r); 1071 SavageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r);
903 /* m = 107; n = 4; r = 2; */ 1072 /* m = 107; n = 4; r = 2; */
904 1073
905 if (par->MCLK <= 0) { 1074 if (par->MCLK <= 0) {
906 par->SR10 = 255; 1075 reg->SR10 = 255;
907 par->SR11 = 255; 1076 reg->SR11 = 255;
908 } else { 1077 } else {
909 common_calc_clock (par->MCLK, 1, 1, 31, 0, 3, 135000, 270000, 1078 common_calc_clock(par->MCLK, 1, 1, 31, 0, 3, 135000, 270000,
910 &par->SR11, &par->SR10); 1079 &reg->SR11, &reg->SR10);
911 /* par->SR10 = 80; // MCLK == 286000 */ 1080 /* reg->SR10 = 80; // MCLK == 286000 */
912 /* par->SR11 = 125; */ 1081 /* reg->SR11 = 125; */
913 } 1082 }
914 1083
915 par->SR12 = (r << 6) | (n & 0x3f); 1084 reg->SR12 = (r << 6) | (n & 0x3f);
916 par->SR13 = m & 0xff; 1085 reg->SR13 = m & 0xff;
917 par->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; 1086 reg->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2;
918 1087
919 if (var->bits_per_pixel < 24) 1088 if (var->bits_per_pixel < 24)
920 par->MMPR0 -= 0x8000; 1089 reg->MMPR0 -= 0x8000;
921 else 1090 else
922 par->MMPR0 -= 0x4000; 1091 reg->MMPR0 -= 0x4000;
923 1092
924 if (timings.interlaced) 1093 if (timings.interlaced)
925 par->CR42 = 0x20; 1094 reg->CR42 = 0x20;
926 else 1095 else
927 par->CR42 = 0x00; 1096 reg->CR42 = 0x00;
928 1097
929 par->CR34 = 0x10; /* display fifo */ 1098 reg->CR34 = 0x10; /* display fifo */
930 1099
931 i = ((((timings.HTotal >> 3) - 5) & 0x100) >> 8) | 1100 i = ((((timings.HTotal >> 3) - 5) & 0x100) >> 8) |
932 ((((timings.HDisplay >> 3) - 1) & 0x100) >> 7) | 1101 ((((timings.HDisplay >> 3) - 1) & 0x100) >> 7) |
@@ -938,77 +1107,77 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
938 if ((timings.HSyncEnd >> 3) - (timings.HSyncStart >> 3) > 32) 1107 if ((timings.HSyncEnd >> 3) - (timings.HSyncStart >> 3) > 32)
939 i |= 0x20; 1108 i |= 0x20;
940 1109
941 j = (par->CRTC[0] + ((i & 0x01) << 8) + 1110 j = (reg->CRTC[0] + ((i & 0x01) << 8) +
942 par->CRTC[4] + ((i & 0x10) << 4) + 1) / 2; 1111 reg->CRTC[4] + ((i & 0x10) << 4) + 1) / 2;
943 1112
944 if (j - (par->CRTC[4] + ((i & 0x10) << 4)) < 4) { 1113 if (j - (reg->CRTC[4] + ((i & 0x10) << 4)) < 4) {
945 if (par->CRTC[4] + ((i & 0x10) << 4) + 4 <= 1114 if (reg->CRTC[4] + ((i & 0x10) << 4) + 4 <=
946 par->CRTC[0] + ((i & 0x01) << 8)) 1115 reg->CRTC[0] + ((i & 0x01) << 8))
947 j = par->CRTC[4] + ((i & 0x10) << 4) + 4; 1116 j = reg->CRTC[4] + ((i & 0x10) << 4) + 4;
948 else 1117 else
949 j = par->CRTC[0] + ((i & 0x01) << 8) + 1; 1118 j = reg->CRTC[0] + ((i & 0x01) << 8) + 1;
950 } 1119 }
951 1120
952 par->CR3B = j & 0xff; 1121 reg->CR3B = j & 0xff;
953 i |= (j & 0x100) >> 2; 1122 i |= (j & 0x100) >> 2;
954 par->CR3C = (par->CRTC[0] + ((i & 0x01) << 8)) / 2; 1123 reg->CR3C = (reg->CRTC[0] + ((i & 0x01) << 8)) / 2;
955 par->CR5D = i; 1124 reg->CR5D = i;
956 par->CR5E = (((timings.VTotal - 2) & 0x400) >> 10) | 1125 reg->CR5E = (((timings.VTotal - 2) & 0x400) >> 10) |
957 (((timings.VDisplay - 1) & 0x400) >> 9) | 1126 (((timings.VDisplay - 1) & 0x400) >> 9) |
958 (((timings.VSyncStart) & 0x400) >> 8) | 1127 (((timings.VSyncStart) & 0x400) >> 8) |
959 (((timings.VSyncStart) & 0x400) >> 6) | 0x40; 1128 (((timings.VSyncStart) & 0x400) >> 6) | 0x40;
960 width = (var->xres_virtual * ((var->bits_per_pixel+7) / 8)) >> 3; 1129 width = (var->xres_virtual * ((var->bits_per_pixel+7) / 8)) >> 3;
961 par->CR91 = par->CRTC[19] = 0xff & width; 1130 reg->CR91 = reg->CRTC[19] = 0xff & width;
962 par->CR51 = (0x300 & width) >> 4; 1131 reg->CR51 = (0x300 & width) >> 4;
963 par->CR90 = 0x80 | (width >> 8); 1132 reg->CR90 = 0x80 | (width >> 8);
964 par->MiscOutReg |= 0x0c; 1133 reg->MiscOutReg |= 0x0c;
965 1134
966 /* Set frame buffer description. */ 1135 /* Set frame buffer description. */
967 1136
968 if (var->bits_per_pixel <= 8) 1137 if (var->bits_per_pixel <= 8)
969 par->CR50 = 0; 1138 reg->CR50 = 0;
970 else if (var->bits_per_pixel <= 16) 1139 else if (var->bits_per_pixel <= 16)
971 par->CR50 = 0x10; 1140 reg->CR50 = 0x10;
972 else 1141 else
973 par->CR50 = 0x30; 1142 reg->CR50 = 0x30;
974 1143
975 if (var->xres_virtual <= 640) 1144 if (var->xres_virtual <= 640)
976 par->CR50 |= 0x40; 1145 reg->CR50 |= 0x40;
977 else if (var->xres_virtual == 800) 1146 else if (var->xres_virtual == 800)
978 par->CR50 |= 0x80; 1147 reg->CR50 |= 0x80;
979 else if (var->xres_virtual == 1024) 1148 else if (var->xres_virtual == 1024)
980 par->CR50 |= 0x00; 1149 reg->CR50 |= 0x00;
981 else if (var->xres_virtual == 1152) 1150 else if (var->xres_virtual == 1152)
982 par->CR50 |= 0x01; 1151 reg->CR50 |= 0x01;
983 else if (var->xres_virtual == 1280) 1152 else if (var->xres_virtual == 1280)
984 par->CR50 |= 0xc0; 1153 reg->CR50 |= 0xc0;
985 else if (var->xres_virtual == 1600) 1154 else if (var->xres_virtual == 1600)
986 par->CR50 |= 0x81; 1155 reg->CR50 |= 0x81;
987 else 1156 else
988 par->CR50 |= 0xc1; /* Use GBD */ 1157 reg->CR50 |= 0xc1; /* Use GBD */
989 1158
990 if( par->chip == S3_SAVAGE2000 ) 1159 if (par->chip == S3_SAVAGE2000)
991 par->CR33 = 0x08; 1160 reg->CR33 = 0x08;
992 else 1161 else
993 par->CR33 = 0x20; 1162 reg->CR33 = 0x20;
994 1163
995 par->CRTC[0x17] = 0xeb; 1164 reg->CRTC[0x17] = 0xeb;
996 1165
997 par->CR67 |= 1; 1166 reg->CR67 |= 1;
998 1167
999 vga_out8(0x3d4, 0x36, par); 1168 vga_out8(0x3d4, 0x36, par);
1000 par->CR36 = vga_in8 (0x3d5, par); 1169 reg->CR36 = vga_in8(0x3d5, par);
1001 vga_out8 (0x3d4, 0x68, par); 1170 vga_out8(0x3d4, 0x68, par);
1002 par->CR68 = vga_in8 (0x3d5, par); 1171 reg->CR68 = vga_in8(0x3d5, par);
1003 par->CR69 = 0; 1172 reg->CR69 = 0;
1004 vga_out8 (0x3d4, 0x6f, par); 1173 vga_out8(0x3d4, 0x6f, par);
1005 par->CR6F = vga_in8 (0x3d5, par); 1174 reg->CR6F = vga_in8(0x3d5, par);
1006 vga_out8 (0x3d4, 0x86, par); 1175 vga_out8(0x3d4, 0x86, par);
1007 par->CR86 = vga_in8 (0x3d5, par); 1176 reg->CR86 = vga_in8(0x3d5, par);
1008 vga_out8 (0x3d4, 0x88, par); 1177 vga_out8(0x3d4, 0x88, par);
1009 par->CR88 = vga_in8 (0x3d5, par) | 0x08; 1178 reg->CR88 = vga_in8(0x3d5, par) | 0x08;
1010 vga_out8 (0x3d4, 0xb0, par); 1179 vga_out8(0x3d4, 0xb0, par);
1011 par->CRB0 = vga_in8 (0x3d5, par) | 0x80; 1180 reg->CRB0 = vga_in8(0x3d5, par) | 0x80;
1012 1181
1013 return 0; 1182 return 0;
1014} 1183}
@@ -1037,11 +1206,11 @@ static int savagefb_setcolreg(unsigned regno,
1037 1206
1038 switch (info->var.bits_per_pixel) { 1207 switch (info->var.bits_per_pixel) {
1039 case 8: 1208 case 8:
1040 vga_out8 (0x3c8, regno, par); 1209 vga_out8(0x3c8, regno, par);
1041 1210
1042 vga_out8 (0x3c9, red >> 10, par); 1211 vga_out8(0x3c9, red >> 10, par);
1043 vga_out8 (0x3c9, green >> 10, par); 1212 vga_out8(0x3c9, green >> 10, par);
1044 vga_out8 (0x3c9, blue >> 10, par); 1213 vga_out8(0x3c9, blue >> 10, par);
1045 break; 1214 break;
1046 1215
1047 case 16: 1216 case 16:
@@ -1075,21 +1244,21 @@ static int savagefb_setcolreg(unsigned regno,
1075 return 0; 1244 return 0;
1076} 1245}
1077 1246
1078static void savagefb_set_par_int (struct savagefb_par *par) 1247static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *reg)
1079{ 1248{
1080 unsigned char tmp, cr3a, cr66, cr67; 1249 unsigned char tmp, cr3a, cr66, cr67;
1081 1250
1082 DBG ("savagefb_set_par_int"); 1251 DBG("savagefb_set_par_int");
1083 1252
1084 par->SavageWaitIdle (par); 1253 par->SavageWaitIdle(par);
1085 1254
1086 vga_out8 (0x3c2, 0x23, par); 1255 vga_out8(0x3c2, 0x23, par);
1087 1256
1088 vga_out16 (0x3d4, 0x4838, par); 1257 vga_out16(0x3d4, 0x4838, par);
1089 vga_out16 (0x3d4, 0xa539, par); 1258 vga_out16(0x3d4, 0xa539, par);
1090 vga_out16 (0x3c4, 0x0608, par); 1259 vga_out16(0x3c4, 0x0608, par);
1091 1260
1092 vgaHWProtect (par, 1); 1261 vgaHWProtect(par, 1);
1093 1262
1094 /* 1263 /*
1095 * Some Savage/MX and /IX systems go nuts when trying to exit the 1264 * Some Savage/MX and /IX systems go nuts when trying to exit the
@@ -1099,203 +1268,202 @@ static void savagefb_set_par_int (struct savagefb_par *par)
1099 */ 1268 */
1100 1269
1101 VerticalRetraceWait(par); 1270 VerticalRetraceWait(par);
1102 vga_out8 (0x3d4, 0x67, par); 1271 vga_out8(0x3d4, 0x67, par);
1103 cr67 = vga_in8 (0x3d5, par); 1272 cr67 = vga_in8(0x3d5, par);
1104 vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */ 1273 vga_out8(0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */
1105 1274
1106 vga_out8 (0x3d4, 0x23, par); 1275 vga_out8(0x3d4, 0x23, par);
1107 vga_out8 (0x3d5, 0x00, par); 1276 vga_out8(0x3d5, 0x00, par);
1108 vga_out8 (0x3d4, 0x26, par); 1277 vga_out8(0x3d4, 0x26, par);
1109 vga_out8 (0x3d5, 0x00, par); 1278 vga_out8(0x3d5, 0x00, par);
1110 1279
1111 /* restore extended regs */ 1280 /* restore extended regs */
1112 vga_out8 (0x3d4, 0x66, par); 1281 vga_out8(0x3d4, 0x66, par);
1113 vga_out8 (0x3d5, par->CR66, par); 1282 vga_out8(0x3d5, reg->CR66, par);
1114 vga_out8 (0x3d4, 0x3a, par); 1283 vga_out8(0x3d4, 0x3a, par);
1115 vga_out8 (0x3d5, par->CR3A, par); 1284 vga_out8(0x3d5, reg->CR3A, par);
1116 vga_out8 (0x3d4, 0x31, par); 1285 vga_out8(0x3d4, 0x31, par);
1117 vga_out8 (0x3d5, par->CR31, par); 1286 vga_out8(0x3d5, reg->CR31, par);
1118 vga_out8 (0x3d4, 0x32, par); 1287 vga_out8(0x3d4, 0x32, par);
1119 vga_out8 (0x3d5, par->CR32, par); 1288 vga_out8(0x3d5, reg->CR32, par);
1120 vga_out8 (0x3d4, 0x58, par); 1289 vga_out8(0x3d4, 0x58, par);
1121 vga_out8 (0x3d5, par->CR58, par); 1290 vga_out8(0x3d5, reg->CR58, par);
1122 vga_out8 (0x3d4, 0x53, par); 1291 vga_out8(0x3d4, 0x53, par);
1123 vga_out8 (0x3d5, par->CR53 & 0x7f, par); 1292 vga_out8(0x3d5, reg->CR53 & 0x7f, par);
1124 1293
1125 vga_out16 (0x3c4, 0x0608, par); 1294 vga_out16(0x3c4, 0x0608, par);
1126 1295
1127 /* Restore DCLK registers. */ 1296 /* Restore DCLK registers. */
1128 1297
1129 vga_out8 (0x3c4, 0x0e, par); 1298 vga_out8(0x3c4, 0x0e, par);
1130 vga_out8 (0x3c5, par->SR0E, par); 1299 vga_out8(0x3c5, reg->SR0E, par);
1131 vga_out8 (0x3c4, 0x0f, par); 1300 vga_out8(0x3c4, 0x0f, par);
1132 vga_out8 (0x3c5, par->SR0F, par); 1301 vga_out8(0x3c5, reg->SR0F, par);
1133 vga_out8 (0x3c4, 0x29, par); 1302 vga_out8(0x3c4, 0x29, par);
1134 vga_out8 (0x3c5, par->SR29, par); 1303 vga_out8(0x3c5, reg->SR29, par);
1135 vga_out8 (0x3c4, 0x15, par); 1304 vga_out8(0x3c4, 0x15, par);
1136 vga_out8 (0x3c5, par->SR15, par); 1305 vga_out8(0x3c5, reg->SR15, par);
1137 1306
1138 /* Restore flat panel expansion regsters. */ 1307 /* Restore flat panel expansion regsters. */
1139 if( par->chip == S3_SAVAGE_MX ) { 1308 if (par->chip == S3_SAVAGE_MX) {
1140 int i; 1309 int i;
1141 1310
1142 for( i = 0; i < 8; i++ ) { 1311 for (i = 0; i < 8; i++) {
1143 vga_out8 (0x3c4, 0x54+i, par); 1312 vga_out8(0x3c4, 0x54+i, par);
1144 vga_out8 (0x3c5, par->SR54[i], par); 1313 vga_out8(0x3c5, reg->SR54[i], par);
1145 } 1314 }
1146 } 1315 }
1147 1316
1148 vgaHWRestore (par); 1317 vgaHWRestore (par, reg);
1149 1318
1150 /* extended mode timing registers */ 1319 /* extended mode timing registers */
1151 vga_out8 (0x3d4, 0x53, par); 1320 vga_out8(0x3d4, 0x53, par);
1152 vga_out8 (0x3d5, par->CR53, par); 1321 vga_out8(0x3d5, reg->CR53, par);
1153 vga_out8 (0x3d4, 0x5d, par); 1322 vga_out8(0x3d4, 0x5d, par);
1154 vga_out8 (0x3d5, par->CR5D, par); 1323 vga_out8(0x3d5, reg->CR5D, par);
1155 vga_out8 (0x3d4, 0x5e, par); 1324 vga_out8(0x3d4, 0x5e, par);
1156 vga_out8 (0x3d5, par->CR5E, par); 1325 vga_out8(0x3d5, reg->CR5E, par);
1157 vga_out8 (0x3d4, 0x3b, par); 1326 vga_out8(0x3d4, 0x3b, par);
1158 vga_out8 (0x3d5, par->CR3B, par); 1327 vga_out8(0x3d5, reg->CR3B, par);
1159 vga_out8 (0x3d4, 0x3c, par); 1328 vga_out8(0x3d4, 0x3c, par);
1160 vga_out8 (0x3d5, par->CR3C, par); 1329 vga_out8(0x3d5, reg->CR3C, par);
1161 vga_out8 (0x3d4, 0x43, par); 1330 vga_out8(0x3d4, 0x43, par);
1162 vga_out8 (0x3d5, par->CR43, par); 1331 vga_out8(0x3d5, reg->CR43, par);
1163 vga_out8 (0x3d4, 0x65, par); 1332 vga_out8(0x3d4, 0x65, par);
1164 vga_out8 (0x3d5, par->CR65, par); 1333 vga_out8(0x3d5, reg->CR65, par);
1165 1334
1166 /* restore the desired video mode with cr67 */ 1335 /* restore the desired video mode with cr67 */
1167 vga_out8 (0x3d4, 0x67, par); 1336 vga_out8(0x3d4, 0x67, par);
1168 /* following part not present in X11 driver */ 1337 /* following part not present in X11 driver */
1169 cr67 = vga_in8 (0x3d5, par) & 0xf; 1338 cr67 = vga_in8(0x3d5, par) & 0xf;
1170 vga_out8 (0x3d5, 0x50 | cr67, par); 1339 vga_out8(0x3d5, 0x50 | cr67, par);
1171 udelay (10000); 1340 udelay(10000);
1172 vga_out8 (0x3d4, 0x67, par); 1341 vga_out8(0x3d4, 0x67, par);
1173 /* end of part */ 1342 /* end of part */
1174 vga_out8 (0x3d5, par->CR67 & ~0x0c, par); 1343 vga_out8(0x3d5, reg->CR67 & ~0x0c, par);
1175 1344
1176 /* other mode timing and extended regs */ 1345 /* other mode timing and extended regs */
1177 vga_out8 (0x3d4, 0x34, par); 1346 vga_out8(0x3d4, 0x34, par);
1178 vga_out8 (0x3d5, par->CR34, par); 1347 vga_out8(0x3d5, reg->CR34, par);
1179 vga_out8 (0x3d4, 0x40, par); 1348 vga_out8(0x3d4, 0x40, par);
1180 vga_out8 (0x3d5, par->CR40, par); 1349 vga_out8(0x3d5, reg->CR40, par);
1181 vga_out8 (0x3d4, 0x42, par); 1350 vga_out8(0x3d4, 0x42, par);
1182 vga_out8 (0x3d5, par->CR42, par); 1351 vga_out8(0x3d5, reg->CR42, par);
1183 vga_out8 (0x3d4, 0x45, par); 1352 vga_out8(0x3d4, 0x45, par);
1184 vga_out8 (0x3d5, par->CR45, par); 1353 vga_out8(0x3d5, reg->CR45, par);
1185 vga_out8 (0x3d4, 0x50, par); 1354 vga_out8(0x3d4, 0x50, par);
1186 vga_out8 (0x3d5, par->CR50, par); 1355 vga_out8(0x3d5, reg->CR50, par);
1187 vga_out8 (0x3d4, 0x51, par); 1356 vga_out8(0x3d4, 0x51, par);
1188 vga_out8 (0x3d5, par->CR51, par); 1357 vga_out8(0x3d5, reg->CR51, par);
1189 1358
1190 /* memory timings */ 1359 /* memory timings */
1191 vga_out8 (0x3d4, 0x36, par); 1360 vga_out8(0x3d4, 0x36, par);
1192 vga_out8 (0x3d5, par->CR36, par); 1361 vga_out8(0x3d5, reg->CR36, par);
1193 vga_out8 (0x3d4, 0x60, par); 1362 vga_out8(0x3d4, 0x60, par);
1194 vga_out8 (0x3d5, par->CR60, par); 1363 vga_out8(0x3d5, reg->CR60, par);
1195 vga_out8 (0x3d4, 0x68, par); 1364 vga_out8(0x3d4, 0x68, par);
1196 vga_out8 (0x3d5, par->CR68, par); 1365 vga_out8(0x3d5, reg->CR68, par);
1197 vga_out8 (0x3d4, 0x69, par); 1366 vga_out8(0x3d4, 0x69, par);
1198 vga_out8 (0x3d5, par->CR69, par); 1367 vga_out8(0x3d5, reg->CR69, par);
1199 vga_out8 (0x3d4, 0x6f, par); 1368 vga_out8(0x3d4, 0x6f, par);
1200 vga_out8 (0x3d5, par->CR6F, par); 1369 vga_out8(0x3d5, reg->CR6F, par);
1201 1370
1202 vga_out8 (0x3d4, 0x33, par); 1371 vga_out8(0x3d4, 0x33, par);
1203 vga_out8 (0x3d5, par->CR33, par); 1372 vga_out8(0x3d5, reg->CR33, par);
1204 vga_out8 (0x3d4, 0x86, par); 1373 vga_out8(0x3d4, 0x86, par);
1205 vga_out8 (0x3d5, par->CR86, par); 1374 vga_out8(0x3d5, reg->CR86, par);
1206 vga_out8 (0x3d4, 0x88, par); 1375 vga_out8(0x3d4, 0x88, par);
1207 vga_out8 (0x3d5, par->CR88, par); 1376 vga_out8(0x3d5, reg->CR88, par);
1208 vga_out8 (0x3d4, 0x90, par); 1377 vga_out8(0x3d4, 0x90, par);
1209 vga_out8 (0x3d5, par->CR90, par); 1378 vga_out8(0x3d5, reg->CR90, par);
1210 vga_out8 (0x3d4, 0x91, par); 1379 vga_out8(0x3d4, 0x91, par);
1211 vga_out8 (0x3d5, par->CR91, par); 1380 vga_out8(0x3d5, reg->CR91, par);
1212 1381
1213 if (par->chip == S3_SAVAGE4) { 1382 if (par->chip == S3_SAVAGE4) {
1214 vga_out8 (0x3d4, 0xb0, par); 1383 vga_out8(0x3d4, 0xb0, par);
1215 vga_out8 (0x3d5, par->CRB0, par); 1384 vga_out8(0x3d5, reg->CRB0, par);
1216 } 1385 }
1217 1386
1218 vga_out8 (0x3d4, 0x32, par); 1387 vga_out8(0x3d4, 0x32, par);
1219 vga_out8 (0x3d5, par->CR32, par); 1388 vga_out8(0x3d5, reg->CR32, par);
1220 1389
1221 /* unlock extended seq regs */ 1390 /* unlock extended seq regs */
1222 vga_out8 (0x3c4, 0x08, par); 1391 vga_out8(0x3c4, 0x08, par);
1223 vga_out8 (0x3c5, 0x06, par); 1392 vga_out8(0x3c5, 0x06, par);
1224 1393
1225 /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates 1394 /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates
1226 * that we should leave the default SR10 and SR11 values there. 1395 * that we should leave the default SR10 and SR11 values there.
1227 */ 1396 */
1228 if (par->SR10 != 255) { 1397 if (reg->SR10 != 255) {
1229 vga_out8 (0x3c4, 0x10, par); 1398 vga_out8(0x3c4, 0x10, par);
1230 vga_out8 (0x3c5, par->SR10, par); 1399 vga_out8(0x3c5, reg->SR10, par);
1231 vga_out8 (0x3c4, 0x11, par); 1400 vga_out8(0x3c4, 0x11, par);
1232 vga_out8 (0x3c5, par->SR11, par); 1401 vga_out8(0x3c5, reg->SR11, par);
1233 } 1402 }
1234 1403
1235 /* restore extended seq regs for dclk */ 1404 /* restore extended seq regs for dclk */
1236 vga_out8 (0x3c4, 0x0e, par); 1405 vga_out8(0x3c4, 0x0e, par);
1237 vga_out8 (0x3c5, par->SR0E, par); 1406 vga_out8(0x3c5, reg->SR0E, par);
1238 vga_out8 (0x3c4, 0x0f, par); 1407 vga_out8(0x3c4, 0x0f, par);
1239 vga_out8 (0x3c5, par->SR0F, par); 1408 vga_out8(0x3c5, reg->SR0F, par);
1240 vga_out8 (0x3c4, 0x12, par); 1409 vga_out8(0x3c4, 0x12, par);
1241 vga_out8 (0x3c5, par->SR12, par); 1410 vga_out8(0x3c5, reg->SR12, par);
1242 vga_out8 (0x3c4, 0x13, par); 1411 vga_out8(0x3c4, 0x13, par);
1243 vga_out8 (0x3c5, par->SR13, par); 1412 vga_out8(0x3c5, reg->SR13, par);
1244 vga_out8 (0x3c4, 0x29, par); 1413 vga_out8(0x3c4, 0x29, par);
1245 vga_out8 (0x3c5, par->SR29, par); 1414 vga_out8(0x3c5, reg->SR29, par);
1246 1415 vga_out8(0x3c4, 0x18, par);
1247 vga_out8 (0x3c4, 0x18, par); 1416 vga_out8(0x3c5, reg->SR18, par);
1248 vga_out8 (0x3c5, par->SR18, par);
1249 1417
1250 /* load new m, n pll values for dclk & mclk */ 1418 /* load new m, n pll values for dclk & mclk */
1251 vga_out8 (0x3c4, 0x15, par); 1419 vga_out8(0x3c4, 0x15, par);
1252 tmp = vga_in8 (0x3c5, par) & ~0x21; 1420 tmp = vga_in8(0x3c5, par) & ~0x21;
1253 1421
1254 vga_out8 (0x3c5, tmp | 0x03, par); 1422 vga_out8(0x3c5, tmp | 0x03, par);
1255 vga_out8 (0x3c5, tmp | 0x23, par); 1423 vga_out8(0x3c5, tmp | 0x23, par);
1256 vga_out8 (0x3c5, tmp | 0x03, par); 1424 vga_out8(0x3c5, tmp | 0x03, par);
1257 vga_out8 (0x3c5, par->SR15, par); 1425 vga_out8(0x3c5, reg->SR15, par);
1258 udelay (100); 1426 udelay(100);
1259 1427
1260 vga_out8 (0x3c4, 0x30, par); 1428 vga_out8(0x3c4, 0x30, par);
1261 vga_out8 (0x3c5, par->SR30, par); 1429 vga_out8(0x3c5, reg->SR30, par);
1262 vga_out8 (0x3c4, 0x08, par); 1430 vga_out8(0x3c4, 0x08, par);
1263 vga_out8 (0x3c5, par->SR08, par); 1431 vga_out8(0x3c5, reg->SR08, par);
1264 1432
1265 /* now write out cr67 in full, possibly starting STREAMS */ 1433 /* now write out cr67 in full, possibly starting STREAMS */
1266 VerticalRetraceWait(par); 1434 VerticalRetraceWait(par);
1267 vga_out8 (0x3d4, 0x67, par); 1435 vga_out8(0x3d4, 0x67, par);
1268 vga_out8 (0x3d5, par->CR67, par); 1436 vga_out8(0x3d5, reg->CR67, par);
1269 1437
1270 vga_out8 (0x3d4, 0x66, par); 1438 vga_out8(0x3d4, 0x66, par);
1271 cr66 = vga_in8 (0x3d5, par); 1439 cr66 = vga_in8(0x3d5, par);
1272 vga_out8 (0x3d5, cr66 | 0x80, par); 1440 vga_out8(0x3d5, cr66 | 0x80, par);
1273 vga_out8 (0x3d4, 0x3a, par); 1441 vga_out8(0x3d4, 0x3a, par);
1274 cr3a = vga_in8 (0x3d5, par); 1442 cr3a = vga_in8(0x3d5, par);
1275 vga_out8 (0x3d5, cr3a | 0x80, par); 1443 vga_out8(0x3d5, cr3a | 0x80, par);
1276 1444
1277 if (par->chip != S3_SAVAGE_MX) { 1445 if (par->chip != S3_SAVAGE_MX) {
1278 VerticalRetraceWait(par); 1446 VerticalRetraceWait(par);
1279 savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par); 1447 savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par);
1280 par->SavageWaitIdle (par); 1448 par->SavageWaitIdle(par);
1281 savage_out32 (MIU_CONTROL_REG, par->MMPR1, par); 1449 savage_out32(MIU_CONTROL_REG, reg->MMPR1, par);
1282 par->SavageWaitIdle (par); 1450 par->SavageWaitIdle(par);
1283 savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par); 1451 savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par);
1284 par->SavageWaitIdle (par); 1452 par->SavageWaitIdle(par);
1285 savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par); 1453 savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par);
1286 } 1454 }
1287 1455
1288 vga_out8 (0x3d4, 0x66, par); 1456 vga_out8(0x3d4, 0x66, par);
1289 vga_out8 (0x3d5, cr66, par); 1457 vga_out8(0x3d5, cr66, par);
1290 vga_out8 (0x3d4, 0x3a, par); 1458 vga_out8(0x3d4, 0x3a, par);
1291 vga_out8 (0x3d5, cr3a, par); 1459 vga_out8(0x3d5, cr3a, par);
1292 1460
1293 SavageSetup2DEngine (par); 1461 SavageSetup2DEngine(par);
1294 vgaHWProtect (par, 0); 1462 vgaHWProtect(par, 0);
1295} 1463}
1296 1464
1297static void savagefb_update_start (struct savagefb_par *par, 1465static void savagefb_update_start(struct savagefb_par *par,
1298 struct fb_var_screeninfo *var) 1466 struct fb_var_screeninfo *var)
1299{ 1467{
1300 int base; 1468 int base;
1301 1469
@@ -1305,8 +1473,8 @@ static void savagefb_update_start (struct savagefb_par *par,
1305 /* now program the start address registers */ 1473 /* now program the start address registers */
1306 vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par); 1474 vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
1307 vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par); 1475 vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
1308 vga_out8 (0x3d4, 0x69, par); 1476 vga_out8(0x3d4, 0x69, par);
1309 vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par); 1477 vga_out8(0x3d5, (base & 0x7f0000) >> 16, par);
1310} 1478}
1311 1479
1312 1480
@@ -1325,29 +1493,14 @@ static void savagefb_set_fix(struct fb_info *info)
1325 1493
1326} 1494}
1327 1495
1328#if defined(CONFIG_FB_SAVAGE_ACCEL) 1496static int savagefb_set_par(struct fb_info *info)
1329static void savagefb_set_clip(struct fb_info *info)
1330{
1331 struct savagefb_par *par = info->par;
1332 int cmd;
1333
1334 cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW;
1335 par->bci_ptr = 0;
1336 par->SavageWaitFifo(par,3);
1337 BCI_SEND(cmd);
1338 BCI_SEND(BCI_CLIP_TL(0, 0));
1339 BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff));
1340}
1341#endif
1342
1343static int savagefb_set_par (struct fb_info *info)
1344{ 1497{
1345 struct savagefb_par *par = info->par; 1498 struct savagefb_par *par = info->par;
1346 struct fb_var_screeninfo *var = &info->var; 1499 struct fb_var_screeninfo *var = &info->var;
1347 int err; 1500 int err;
1348 1501
1349 DBG("savagefb_set_par"); 1502 DBG("savagefb_set_par");
1350 err = savagefb_decode_var (var, par); 1503 err = savagefb_decode_var(var, par, &par->state);
1351 if (err) 1504 if (err)
1352 return err; 1505 return err;
1353 1506
@@ -1366,8 +1519,8 @@ static int savagefb_set_par (struct fb_info *info)
1366 par->maxClock = par->dacSpeedBpp; 1519 par->maxClock = par->dacSpeedBpp;
1367 par->minClock = 10000; 1520 par->minClock = 10000;
1368 1521
1369 savagefb_set_par_int (par); 1522 savagefb_set_par_int(par, &par->state);
1370 fb_set_cmap (&info->cmap, info); 1523 fb_set_cmap(&info->cmap, info);
1371 savagefb_set_fix(info); 1524 savagefb_set_fix(info);
1372 savagefb_set_clip(info); 1525 savagefb_set_clip(info);
1373 1526
@@ -1378,12 +1531,12 @@ static int savagefb_set_par (struct fb_info *info)
1378/* 1531/*
1379 * Pan or Wrap the Display 1532 * Pan or Wrap the Display
1380 */ 1533 */
1381static int savagefb_pan_display (struct fb_var_screeninfo *var, 1534static int savagefb_pan_display(struct fb_var_screeninfo *var,
1382 struct fb_info *info) 1535 struct fb_info *info)
1383{ 1536{
1384 struct savagefb_par *par = info->par; 1537 struct savagefb_par *par = info->par;
1385 1538
1386 savagefb_update_start (par, var); 1539 savagefb_update_start(par, var);
1387 return 0; 1540 return 0;
1388} 1541}
1389 1542
@@ -1440,6 +1593,22 @@ static int savagefb_blank(int blank, struct fb_info *info)
1440 return (blank == FB_BLANK_NORMAL) ? 1 : 0; 1593 return (blank == FB_BLANK_NORMAL) ? 1 : 0;
1441} 1594}
1442 1595
1596static void savagefb_save_state(struct fb_info *info)
1597{
1598 struct savagefb_par *par = info->par;
1599
1600 savage_get_default_par(par, &par->save);
1601}
1602
1603static void savagefb_restore_state(struct fb_info *info)
1604{
1605 struct savagefb_par *par = info->par;
1606
1607 savagefb_blank(FB_BLANK_POWERDOWN, info);
1608 savage_set_default_par(par, &par->save);
1609 savagefb_blank(FB_BLANK_UNBLANK, info);
1610}
1611
1443static struct fb_ops savagefb_ops = { 1612static struct fb_ops savagefb_ops = {
1444 .owner = THIS_MODULE, 1613 .owner = THIS_MODULE,
1445 .fb_check_var = savagefb_check_var, 1614 .fb_check_var = savagefb_check_var,
@@ -1447,6 +1616,8 @@ static struct fb_ops savagefb_ops = {
1447 .fb_setcolreg = savagefb_setcolreg, 1616 .fb_setcolreg = savagefb_setcolreg,
1448 .fb_pan_display = savagefb_pan_display, 1617 .fb_pan_display = savagefb_pan_display,
1449 .fb_blank = savagefb_blank, 1618 .fb_blank = savagefb_blank,
1619 .fb_save_state = savagefb_save_state,
1620 .fb_restore_state = savagefb_restore_state,
1450#if defined(CONFIG_FB_SAVAGE_ACCEL) 1621#if defined(CONFIG_FB_SAVAGE_ACCEL)
1451 .fb_fillrect = savagefb_fillrect, 1622 .fb_fillrect = savagefb_fillrect,
1452 .fb_copyarea = savagefb_copyarea, 1623 .fb_copyarea = savagefb_copyarea,
@@ -1479,59 +1650,59 @@ static struct fb_var_screeninfo __devinitdata savagefb_var800x600x8 = {
1479 .vmode = FB_VMODE_NONINTERLACED 1650 .vmode = FB_VMODE_NONINTERLACED
1480}; 1651};
1481 1652
1482static void savage_enable_mmio (struct savagefb_par *par) 1653static void savage_enable_mmio(struct savagefb_par *par)
1483{ 1654{
1484 unsigned char val; 1655 unsigned char val;
1485 1656
1486 DBG ("savage_enable_mmio\n"); 1657 DBG("savage_enable_mmio\n");
1487 1658
1488 val = vga_in8 (0x3c3, par); 1659 val = vga_in8(0x3c3, par);
1489 vga_out8 (0x3c3, val | 0x01, par); 1660 vga_out8(0x3c3, val | 0x01, par);
1490 val = vga_in8 (0x3cc, par); 1661 val = vga_in8(0x3cc, par);
1491 vga_out8 (0x3c2, val | 0x01, par); 1662 vga_out8(0x3c2, val | 0x01, par);
1492 1663
1493 if (par->chip >= S3_SAVAGE4) { 1664 if (par->chip >= S3_SAVAGE4) {
1494 vga_out8 (0x3d4, 0x40, par); 1665 vga_out8(0x3d4, 0x40, par);
1495 val = vga_in8 (0x3d5, par); 1666 val = vga_in8(0x3d5, par);
1496 vga_out8 (0x3d5, val | 1, par); 1667 vga_out8(0x3d5, val | 1, par);
1497 } 1668 }
1498} 1669}
1499 1670
1500 1671
1501static void savage_disable_mmio (struct savagefb_par *par) 1672static void savage_disable_mmio(struct savagefb_par *par)
1502{ 1673{
1503 unsigned char val; 1674 unsigned char val;
1504 1675
1505 DBG ("savage_disable_mmio\n"); 1676 DBG("savage_disable_mmio\n");
1506 1677
1507 if(par->chip >= S3_SAVAGE4 ) { 1678 if (par->chip >= S3_SAVAGE4) {
1508 vga_out8 (0x3d4, 0x40, par); 1679 vga_out8(0x3d4, 0x40, par);
1509 val = vga_in8 (0x3d5, par); 1680 val = vga_in8(0x3d5, par);
1510 vga_out8 (0x3d5, val | 1, par); 1681 vga_out8(0x3d5, val | 1, par);
1511 } 1682 }
1512} 1683}
1513 1684
1514 1685
1515static int __devinit savage_map_mmio (struct fb_info *info) 1686static int __devinit savage_map_mmio(struct fb_info *info)
1516{ 1687{
1517 struct savagefb_par *par = info->par; 1688 struct savagefb_par *par = info->par;
1518 DBG ("savage_map_mmio"); 1689 DBG("savage_map_mmio");
1519 1690
1520 if (S3_SAVAGE3D_SERIES (par->chip)) 1691 if (S3_SAVAGE3D_SERIES(par->chip))
1521 par->mmio.pbase = pci_resource_start (par->pcidev, 0) + 1692 par->mmio.pbase = pci_resource_start(par->pcidev, 0) +
1522 SAVAGE_NEWMMIO_REGBASE_S3; 1693 SAVAGE_NEWMMIO_REGBASE_S3;
1523 else 1694 else
1524 par->mmio.pbase = pci_resource_start (par->pcidev, 0) + 1695 par->mmio.pbase = pci_resource_start(par->pcidev, 0) +
1525 SAVAGE_NEWMMIO_REGBASE_S4; 1696 SAVAGE_NEWMMIO_REGBASE_S4;
1526 1697
1527 par->mmio.len = SAVAGE_NEWMMIO_REGSIZE; 1698 par->mmio.len = SAVAGE_NEWMMIO_REGSIZE;
1528 1699
1529 par->mmio.vbase = ioremap (par->mmio.pbase, par->mmio.len); 1700 par->mmio.vbase = ioremap(par->mmio.pbase, par->mmio.len);
1530 if (!par->mmio.vbase) { 1701 if (!par->mmio.vbase) {
1531 printk ("savagefb: unable to map memory mapped IO\n"); 1702 printk("savagefb: unable to map memory mapped IO\n");
1532 return -ENOMEM; 1703 return -ENOMEM;
1533 } else 1704 } else
1534 printk (KERN_INFO "savagefb: mapped io at %p\n", 1705 printk(KERN_INFO "savagefb: mapped io at %p\n",
1535 par->mmio.vbase); 1706 par->mmio.vbase);
1536 1707
1537 info->fix.mmio_start = par->mmio.pbase; 1708 info->fix.mmio_start = par->mmio.pbase;
@@ -1540,15 +1711,15 @@ static int __devinit savage_map_mmio (struct fb_info *info)
1540 par->bci_base = (u32 __iomem *)(par->mmio.vbase + BCI_BUFFER_OFFSET); 1711 par->bci_base = (u32 __iomem *)(par->mmio.vbase + BCI_BUFFER_OFFSET);
1541 par->bci_ptr = 0; 1712 par->bci_ptr = 0;
1542 1713
1543 savage_enable_mmio (par); 1714 savage_enable_mmio(par);
1544 1715
1545 return 0; 1716 return 0;
1546} 1717}
1547 1718
1548static void savage_unmap_mmio (struct fb_info *info) 1719static void savage_unmap_mmio(struct fb_info *info)
1549{ 1720{
1550 struct savagefb_par *par = info->par; 1721 struct savagefb_par *par = info->par;
1551 DBG ("savage_unmap_mmio"); 1722 DBG("savage_unmap_mmio");
1552 1723
1553 savage_disable_mmio(par); 1724 savage_disable_mmio(par);
1554 1725
@@ -1558,46 +1729,46 @@ static void savage_unmap_mmio (struct fb_info *info)
1558 } 1729 }
1559} 1730}
1560 1731
1561static int __devinit savage_map_video (struct fb_info *info, 1732static int __devinit savage_map_video(struct fb_info *info,
1562 int video_len) 1733 int video_len)
1563{ 1734{
1564 struct savagefb_par *par = info->par; 1735 struct savagefb_par *par = info->par;
1565 int resource; 1736 int resource;
1566 1737
1567 DBG("savage_map_video"); 1738 DBG("savage_map_video");
1568 1739
1569 if (S3_SAVAGE3D_SERIES (par->chip)) 1740 if (S3_SAVAGE3D_SERIES(par->chip))
1570 resource = 0; 1741 resource = 0;
1571 else 1742 else
1572 resource = 1; 1743 resource = 1;
1573 1744
1574 par->video.pbase = pci_resource_start (par->pcidev, resource); 1745 par->video.pbase = pci_resource_start(par->pcidev, resource);
1575 par->video.len = video_len; 1746 par->video.len = video_len;
1576 par->video.vbase = ioremap (par->video.pbase, par->video.len); 1747 par->video.vbase = ioremap(par->video.pbase, par->video.len);
1577 1748
1578 if (!par->video.vbase) { 1749 if (!par->video.vbase) {
1579 printk ("savagefb: unable to map screen memory\n"); 1750 printk("savagefb: unable to map screen memory\n");
1580 return -ENOMEM; 1751 return -ENOMEM;
1581 } else 1752 } else
1582 printk (KERN_INFO "savagefb: mapped framebuffer at %p, " 1753 printk(KERN_INFO "savagefb: mapped framebuffer at %p, "
1583 "pbase == %x\n", par->video.vbase, par->video.pbase); 1754 "pbase == %x\n", par->video.vbase, par->video.pbase);
1584 1755
1585 info->fix.smem_start = par->video.pbase; 1756 info->fix.smem_start = par->video.pbase;
1586 info->fix.smem_len = par->video.len - par->cob_size; 1757 info->fix.smem_len = par->video.len - par->cob_size;
1587 info->screen_base = par->video.vbase; 1758 info->screen_base = par->video.vbase;
1588 1759
1589#ifdef CONFIG_MTRR 1760#ifdef CONFIG_MTRR
1590 par->video.mtrr = mtrr_add (par->video.pbase, video_len, 1761 par->video.mtrr = mtrr_add(par->video.pbase, video_len,
1591 MTRR_TYPE_WRCOMB, 1); 1762 MTRR_TYPE_WRCOMB, 1);
1592#endif 1763#endif
1593 1764
1594 /* Clear framebuffer, it's all white in memory after boot */ 1765 /* Clear framebuffer, it's all white in memory after boot */
1595 memset_io (par->video.vbase, 0, par->video.len); 1766 memset_io(par->video.vbase, 0, par->video.len);
1596 1767
1597 return 0; 1768 return 0;
1598} 1769}
1599 1770
1600static void savage_unmap_video (struct fb_info *info) 1771static void savage_unmap_video(struct fb_info *info)
1601{ 1772{
1602 struct savagefb_par *par = info->par; 1773 struct savagefb_par *par = info->par;
1603 1774
@@ -1605,16 +1776,16 @@ static void savage_unmap_video (struct fb_info *info)
1605 1776
1606 if (par->video.vbase) { 1777 if (par->video.vbase) {
1607#ifdef CONFIG_MTRR 1778#ifdef CONFIG_MTRR
1608 mtrr_del (par->video.mtrr, par->video.pbase, par->video.len); 1779 mtrr_del(par->video.mtrr, par->video.pbase, par->video.len);
1609#endif 1780#endif
1610 1781
1611 iounmap (par->video.vbase); 1782 iounmap(par->video.vbase);
1612 par->video.vbase = NULL; 1783 par->video.vbase = NULL;
1613 info->screen_base = NULL; 1784 info->screen_base = NULL;
1614 } 1785 }
1615} 1786}
1616 1787
1617static int savage_init_hw (struct savagefb_par *par) 1788static int savage_init_hw(struct savagefb_par *par)
1618{ 1789{
1619 unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp; 1790 unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp;
1620 1791
@@ -1656,7 +1827,7 @@ static int savage_init_hw (struct savagefb_par *par)
1656 1827
1657 switch (par->chip) { 1828 switch (par->chip) {
1658 case S3_SAVAGE3D: 1829 case S3_SAVAGE3D:
1659 videoRam = RamSavage3D[ (config1 & 0xC0) >> 6 ] * 1024; 1830 videoRam = RamSavage3D[(config1 & 0xC0) >> 6 ] * 1024;
1660 break; 1831 break;
1661 1832
1662 case S3_SAVAGE4: 1833 case S3_SAVAGE4:
@@ -1667,22 +1838,22 @@ static int savage_init_hw (struct savagefb_par *par)
1667 * can do it different... 1838 * can do it different...
1668 */ 1839 */
1669 vga_out8(0x3d4, 0x68, par); /* memory control 1 */ 1840 vga_out8(0x3d4, 0x68, par); /* memory control 1 */
1670 if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) ) 1841 if ((vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6))
1671 RamSavage4[1] = 8; 1842 RamSavage4[1] = 8;
1672 1843
1673 /*FALLTHROUGH*/ 1844 /*FALLTHROUGH*/
1674 1845
1675 case S3_SAVAGE2000: 1846 case S3_SAVAGE2000:
1676 videoRam = RamSavage4[ (config1 & 0xE0) >> 5 ] * 1024; 1847 videoRam = RamSavage4[(config1 & 0xE0) >> 5] * 1024;
1677 break; 1848 break;
1678 1849
1679 case S3_SAVAGE_MX: 1850 case S3_SAVAGE_MX:
1680 case S3_SUPERSAVAGE: 1851 case S3_SUPERSAVAGE:
1681 videoRam = RamSavageMX[ (config1 & 0x0E) >> 1 ] * 1024; 1852 videoRam = RamSavageMX[(config1 & 0x0E) >> 1] * 1024;
1682 break; 1853 break;
1683 1854
1684 case S3_PROSAVAGE: 1855 case S3_PROSAVAGE:
1685 videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ] * 1024; 1856 videoRam = RamSavageNB[(config1 & 0xE0) >> 5] * 1024;
1686 break; 1857 break;
1687 1858
1688 default: 1859 default:
@@ -1693,31 +1864,31 @@ static int savage_init_hw (struct savagefb_par *par)
1693 1864
1694 videoRambytes = videoRam * 1024; 1865 videoRambytes = videoRam * 1024;
1695 1866
1696 printk (KERN_INFO "savagefb: probed videoram: %dk\n", videoRam); 1867 printk(KERN_INFO "savagefb: probed videoram: %dk\n", videoRam);
1697 1868
1698 /* reset graphics engine to avoid memory corruption */ 1869 /* reset graphics engine to avoid memory corruption */
1699 vga_out8 (0x3d4, 0x66, par); 1870 vga_out8(0x3d4, 0x66, par);
1700 cr66 = vga_in8 (0x3d5, par); 1871 cr66 = vga_in8(0x3d5, par);
1701 vga_out8 (0x3d5, cr66 | 0x02, par); 1872 vga_out8(0x3d5, cr66 | 0x02, par);
1702 udelay (10000); 1873 udelay(10000);
1703 1874
1704 vga_out8 (0x3d4, 0x66, par); 1875 vga_out8(0x3d4, 0x66, par);
1705 vga_out8 (0x3d5, cr66 & ~0x02, par); /* clear reset flag */ 1876 vga_out8(0x3d5, cr66 & ~0x02, par); /* clear reset flag */
1706 udelay (10000); 1877 udelay(10000);
1707 1878
1708 1879
1709 /* 1880 /*
1710 * reset memory interface, 3D engine, AGP master, PCI master, 1881 * reset memory interface, 3D engine, AGP master, PCI master,
1711 * master engine unit, motion compensation/LPB 1882 * master engine unit, motion compensation/LPB
1712 */ 1883 */
1713 vga_out8 (0x3d4, 0x3f, par); 1884 vga_out8(0x3d4, 0x3f, par);
1714 cr3f = vga_in8 (0x3d5, par); 1885 cr3f = vga_in8(0x3d5, par);
1715 vga_out8 (0x3d5, cr3f | 0x08, par); 1886 vga_out8(0x3d5, cr3f | 0x08, par);
1716 udelay (10000); 1887 udelay(10000);
1717 1888
1718 vga_out8 (0x3d4, 0x3f, par); 1889 vga_out8(0x3d4, 0x3f, par);
1719 vga_out8 (0x3d5, cr3f & ~0x08, par); /* clear reset flags */ 1890 vga_out8(0x3d5, cr3f & ~0x08, par); /* clear reset flags */
1720 udelay (10000); 1891 udelay(10000);
1721 1892
1722 /* Savage ramdac speeds */ 1893 /* Savage ramdac speeds */
1723 par->numClocks = 4; 1894 par->numClocks = 4;
@@ -1740,7 +1911,7 @@ static int savage_init_hw (struct savagefb_par *par)
1740 n1 = n & 0x1f; 1911 n1 = n & 0x1f;
1741 n2 = (n >> 5) & 0x03; 1912 n2 = (n >> 5) & 0x03;
1742 par->MCLK = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100; 1913 par->MCLK = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100;
1743 printk (KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n", 1914 printk(KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n",
1744 par->MCLK); 1915 par->MCLK);
1745 1916
1746 /* check for DVI/flat panel */ 1917 /* check for DVI/flat panel */
@@ -1769,12 +1940,12 @@ static int savage_init_hw (struct savagefb_par *par)
1769 /* Check LCD panel parrmation */ 1940 /* Check LCD panel parrmation */
1770 1941
1771 if (par->display_type == DISP_LCD) { 1942 if (par->display_type == DISP_LCD) {
1772 unsigned char cr6b = VGArCR( 0x6b, par); 1943 unsigned char cr6b = VGArCR(0x6b, par);
1773 1944
1774 int panelX = (VGArSEQ (0x61, par) + 1945 int panelX = (VGArSEQ(0x61, par) +
1775 ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8; 1946 ((VGArSEQ(0x66, par) & 0x02) << 7) + 1) * 8;
1776 int panelY = (VGArSEQ (0x69, par) + 1947 int panelY = (VGArSEQ(0x69, par) +
1777 ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1); 1948 ((VGArSEQ(0x6e, par) & 0x70) << 4) + 1);
1778 1949
1779 char * sTechnology = "Unknown"; 1950 char * sTechnology = "Unknown";
1780 1951
@@ -1796,26 +1967,26 @@ static int savage_init_hw (struct savagefb_par *par)
1796 ActiveDUO = 0x80 1967 ActiveDUO = 0x80
1797 }; 1968 };
1798 1969
1799 if ((VGArSEQ (0x39, par) & 0x03) == 0) { 1970 if ((VGArSEQ(0x39, par) & 0x03) == 0) {
1800 sTechnology = "TFT"; 1971 sTechnology = "TFT";
1801 } else if ((VGArSEQ (0x30, par) & 0x01) == 0) { 1972 } else if ((VGArSEQ(0x30, par) & 0x01) == 0) {
1802 sTechnology = "DSTN"; 1973 sTechnology = "DSTN";
1803 } else { 1974 } else {
1804 sTechnology = "STN"; 1975 sTechnology = "STN";
1805 } 1976 }
1806 1977
1807 printk (KERN_INFO "savagefb: %dx%d %s LCD panel detected %s\n", 1978 printk(KERN_INFO "savagefb: %dx%d %s LCD panel detected %s\n",
1808 panelX, panelY, sTechnology, 1979 panelX, panelY, sTechnology,
1809 cr6b & ActiveLCD ? "and active" : "but not active"); 1980 cr6b & ActiveLCD ? "and active" : "but not active");
1810 1981
1811 if( cr6b & ActiveLCD ) { 1982 if (cr6b & ActiveLCD) {
1812 /* 1983 /*
1813 * If the LCD is active and panel expansion is enabled, 1984 * If the LCD is active and panel expansion is enabled,
1814 * we probably want to kill the HW cursor. 1985 * we probably want to kill the HW cursor.
1815 */ 1986 */
1816 1987
1817 printk (KERN_INFO "savagefb: Limiting video mode to " 1988 printk(KERN_INFO "savagefb: Limiting video mode to "
1818 "%dx%d\n", panelX, panelY ); 1989 "%dx%d\n", panelX, panelY);
1819 1990
1820 par->SavagePanelWidth = panelX; 1991 par->SavagePanelWidth = panelX;
1821 par->SavagePanelHeight = panelY; 1992 par->SavagePanelHeight = panelY;
@@ -1824,9 +1995,10 @@ static int savage_init_hw (struct savagefb_par *par)
1824 par->display_type = DISP_CRT; 1995 par->display_type = DISP_CRT;
1825 } 1996 }
1826 1997
1827 savage_get_default_par (par); 1998 savage_get_default_par(par, &par->state);
1999 par->save = par->state;
1828 2000
1829 if( S3_SAVAGE4_SERIES(par->chip) ) { 2001 if (S3_SAVAGE4_SERIES(par->chip)) {
1830 /* 2002 /*
1831 * The Savage4 and ProSavage have COB coherency bugs which 2003 * The Savage4 and ProSavage have COB coherency bugs which
1832 * render the buffer useless. We disable it. 2004 * render the buffer useless. We disable it.
@@ -1845,9 +2017,9 @@ static int savage_init_hw (struct savagefb_par *par)
1845 return videoRambytes; 2017 return videoRambytes;
1846} 2018}
1847 2019
1848static int __devinit savage_init_fb_info (struct fb_info *info, 2020static int __devinit savage_init_fb_info(struct fb_info *info,
1849 struct pci_dev *dev, 2021 struct pci_dev *dev,
1850 const struct pci_device_id *id) 2022 const struct pci_device_id *id)
1851{ 2023{
1852 struct savagefb_par *par = info->par; 2024 struct savagefb_par *par = info->par;
1853 int err = 0; 2025 int err = 0;
@@ -1863,63 +2035,63 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1863 switch (info->fix.accel) { 2035 switch (info->fix.accel) {
1864 case FB_ACCEL_SUPERSAVAGE: 2036 case FB_ACCEL_SUPERSAVAGE:
1865 par->chip = S3_SUPERSAVAGE; 2037 par->chip = S3_SUPERSAVAGE;
1866 snprintf (info->fix.id, 16, "SuperSavage"); 2038 snprintf(info->fix.id, 16, "SuperSavage");
1867 break; 2039 break;
1868 case FB_ACCEL_SAVAGE4: 2040 case FB_ACCEL_SAVAGE4:
1869 par->chip = S3_SAVAGE4; 2041 par->chip = S3_SAVAGE4;
1870 snprintf (info->fix.id, 16, "Savage4"); 2042 snprintf(info->fix.id, 16, "Savage4");
1871 break; 2043 break;
1872 case FB_ACCEL_SAVAGE3D: 2044 case FB_ACCEL_SAVAGE3D:
1873 par->chip = S3_SAVAGE3D; 2045 par->chip = S3_SAVAGE3D;
1874 snprintf (info->fix.id, 16, "Savage3D"); 2046 snprintf(info->fix.id, 16, "Savage3D");
1875 break; 2047 break;
1876 case FB_ACCEL_SAVAGE3D_MV: 2048 case FB_ACCEL_SAVAGE3D_MV:
1877 par->chip = S3_SAVAGE3D; 2049 par->chip = S3_SAVAGE3D;
1878 snprintf (info->fix.id, 16, "Savage3D-MV"); 2050 snprintf(info->fix.id, 16, "Savage3D-MV");
1879 break; 2051 break;
1880 case FB_ACCEL_SAVAGE2000: 2052 case FB_ACCEL_SAVAGE2000:
1881 par->chip = S3_SAVAGE2000; 2053 par->chip = S3_SAVAGE2000;
1882 snprintf (info->fix.id, 16, "Savage2000"); 2054 snprintf(info->fix.id, 16, "Savage2000");
1883 break; 2055 break;
1884 case FB_ACCEL_SAVAGE_MX_MV: 2056 case FB_ACCEL_SAVAGE_MX_MV:
1885 par->chip = S3_SAVAGE_MX; 2057 par->chip = S3_SAVAGE_MX;
1886 snprintf (info->fix.id, 16, "Savage/MX-MV"); 2058 snprintf(info->fix.id, 16, "Savage/MX-MV");
1887 break; 2059 break;
1888 case FB_ACCEL_SAVAGE_MX: 2060 case FB_ACCEL_SAVAGE_MX:
1889 par->chip = S3_SAVAGE_MX; 2061 par->chip = S3_SAVAGE_MX;
1890 snprintf (info->fix.id, 16, "Savage/MX"); 2062 snprintf(info->fix.id, 16, "Savage/MX");
1891 break; 2063 break;
1892 case FB_ACCEL_SAVAGE_IX_MV: 2064 case FB_ACCEL_SAVAGE_IX_MV:
1893 par->chip = S3_SAVAGE_MX; 2065 par->chip = S3_SAVAGE_MX;
1894 snprintf (info->fix.id, 16, "Savage/IX-MV"); 2066 snprintf(info->fix.id, 16, "Savage/IX-MV");
1895 break; 2067 break;
1896 case FB_ACCEL_SAVAGE_IX: 2068 case FB_ACCEL_SAVAGE_IX:
1897 par->chip = S3_SAVAGE_MX; 2069 par->chip = S3_SAVAGE_MX;
1898 snprintf (info->fix.id, 16, "Savage/IX"); 2070 snprintf(info->fix.id, 16, "Savage/IX");
1899 break; 2071 break;
1900 case FB_ACCEL_PROSAVAGE_PM: 2072 case FB_ACCEL_PROSAVAGE_PM:
1901 par->chip = S3_PROSAVAGE; 2073 par->chip = S3_PROSAVAGE;
1902 snprintf (info->fix.id, 16, "ProSavagePM"); 2074 snprintf(info->fix.id, 16, "ProSavagePM");
1903 break; 2075 break;
1904 case FB_ACCEL_PROSAVAGE_KM: 2076 case FB_ACCEL_PROSAVAGE_KM:
1905 par->chip = S3_PROSAVAGE; 2077 par->chip = S3_PROSAVAGE;
1906 snprintf (info->fix.id, 16, "ProSavageKM"); 2078 snprintf(info->fix.id, 16, "ProSavageKM");
1907 break; 2079 break;
1908 case FB_ACCEL_S3TWISTER_P: 2080 case FB_ACCEL_S3TWISTER_P:
1909 par->chip = S3_PROSAVAGE; 2081 par->chip = S3_PROSAVAGE;
1910 snprintf (info->fix.id, 16, "TwisterP"); 2082 snprintf(info->fix.id, 16, "TwisterP");
1911 break; 2083 break;
1912 case FB_ACCEL_S3TWISTER_K: 2084 case FB_ACCEL_S3TWISTER_K:
1913 par->chip = S3_PROSAVAGE; 2085 par->chip = S3_PROSAVAGE;
1914 snprintf (info->fix.id, 16, "TwisterK"); 2086 snprintf(info->fix.id, 16, "TwisterK");
1915 break; 2087 break;
1916 case FB_ACCEL_PROSAVAGE_DDR: 2088 case FB_ACCEL_PROSAVAGE_DDR:
1917 par->chip = S3_PROSAVAGE; 2089 par->chip = S3_PROSAVAGE;
1918 snprintf (info->fix.id, 16, "ProSavageDDR"); 2090 snprintf(info->fix.id, 16, "ProSavageDDR");
1919 break; 2091 break;
1920 case FB_ACCEL_PROSAVAGE_DDRK: 2092 case FB_ACCEL_PROSAVAGE_DDRK:
1921 par->chip = S3_PROSAVAGE; 2093 par->chip = S3_PROSAVAGE;
1922 snprintf (info->fix.id, 16, "ProSavage8"); 2094 snprintf(info->fix.id, 16, "ProSavage8");
1923 break; 2095 break;
1924 } 2096 }
1925 2097
@@ -1960,7 +2132,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1960 info->pixmap.buf_align = 4; 2132 info->pixmap.buf_align = 4;
1961 info->pixmap.access_align = 32; 2133 info->pixmap.access_align = 32;
1962 2134
1963 err = fb_alloc_cmap (&info->cmap, NR_PALETTE, 0); 2135 err = fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
1964 if (!err) 2136 if (!err)
1965 info->flags |= FBINFO_HWACCEL_COPYAREA | 2137 info->flags |= FBINFO_HWACCEL_COPYAREA |
1966 FBINFO_HWACCEL_FILLRECT | 2138 FBINFO_HWACCEL_FILLRECT |
@@ -1972,8 +2144,8 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1972 2144
1973/* --------------------------------------------------------------------- */ 2145/* --------------------------------------------------------------------- */
1974 2146
1975static int __devinit savagefb_probe (struct pci_dev* dev, 2147static int __devinit savagefb_probe(struct pci_dev* dev,
1976 const struct pci_device_id* id) 2148 const struct pci_device_id* id)
1977{ 2149{
1978 struct fb_info *info; 2150 struct fb_info *info;
1979 struct savagefb_par *par; 2151 struct savagefb_par *par;
@@ -2085,12 +2257,12 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
2085 fb_destroy_modedb(info->monspecs.modedb); 2257 fb_destroy_modedb(info->monspecs.modedb);
2086 info->monspecs.modedb = NULL; 2258 info->monspecs.modedb = NULL;
2087 2259
2088 err = register_framebuffer (info); 2260 err = register_framebuffer(info);
2089 if (err < 0) 2261 if (err < 0)
2090 goto failed; 2262 goto failed;
2091 2263
2092 printk (KERN_INFO "fb: S3 %s frame buffer device\n", 2264 printk(KERN_INFO "fb: S3 %s frame buffer device\n",
2093 info->fix.id); 2265 info->fix.id);
2094 2266
2095 /* 2267 /*
2096 * Our driver data 2268 * Our driver data
@@ -2103,10 +2275,10 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
2103#ifdef CONFIG_FB_SAVAGE_I2C 2275#ifdef CONFIG_FB_SAVAGE_I2C
2104 savagefb_delete_i2c_busses(info); 2276 savagefb_delete_i2c_busses(info);
2105#endif 2277#endif
2106 fb_alloc_cmap (&info->cmap, 0, 0); 2278 fb_alloc_cmap(&info->cmap, 0, 0);
2107 savage_unmap_video(info); 2279 savage_unmap_video(info);
2108 failed_video: 2280 failed_video:
2109 savage_unmap_mmio (info); 2281 savage_unmap_mmio(info);
2110 failed_mmio: 2282 failed_mmio:
2111 kfree(info->pixmap.addr); 2283 kfree(info->pixmap.addr);
2112 failed_init: 2284 failed_init:
@@ -2117,7 +2289,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
2117 return err; 2289 return err;
2118} 2290}
2119 2291
2120static void __devexit savagefb_remove (struct pci_dev *dev) 2292static void __devexit savagefb_remove(struct pci_dev *dev)
2121{ 2293{
2122 struct fb_info *info = pci_get_drvdata(dev); 2294 struct fb_info *info = pci_get_drvdata(dev);
2123 2295
@@ -2129,16 +2301,16 @@ static void __devexit savagefb_remove (struct pci_dev *dev)
2129 * we will be leaving hooks that could cause 2301 * we will be leaving hooks that could cause
2130 * oopsen laying around. 2302 * oopsen laying around.
2131 */ 2303 */
2132 if (unregister_framebuffer (info)) 2304 if (unregister_framebuffer(info))
2133 printk (KERN_WARNING "savagefb: danger danger! " 2305 printk(KERN_WARNING "savagefb: danger danger! "
2134 "Oopsen imminent!\n"); 2306 "Oopsen imminent!\n");
2135 2307
2136#ifdef CONFIG_FB_SAVAGE_I2C 2308#ifdef CONFIG_FB_SAVAGE_I2C
2137 savagefb_delete_i2c_busses(info); 2309 savagefb_delete_i2c_busses(info);
2138#endif 2310#endif
2139 fb_alloc_cmap (&info->cmap, 0, 0); 2311 fb_alloc_cmap(&info->cmap, 0, 0);
2140 savage_unmap_video (info); 2312 savage_unmap_video(info);
2141 savage_unmap_mmio (info); 2313 savage_unmap_mmio(info);
2142 kfree(info->pixmap.addr); 2314 kfree(info->pixmap.addr);
2143 pci_release_regions(dev); 2315 pci_release_regions(dev);
2144 framebuffer_release(info); 2316 framebuffer_release(info);
@@ -2151,24 +2323,24 @@ static void __devexit savagefb_remove (struct pci_dev *dev)
2151 } 2323 }
2152} 2324}
2153 2325
2154static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) 2326static int savagefb_suspend(struct pci_dev *dev, pm_message_t mesg)
2155{ 2327{
2156 struct fb_info *info = pci_get_drvdata(dev); 2328 struct fb_info *info = pci_get_drvdata(dev);
2157 struct savagefb_par *par = info->par; 2329 struct savagefb_par *par = info->par;
2158 2330
2159 DBG("savagefb_suspend"); 2331 DBG("savagefb_suspend");
2160 2332
2161 2333 if (mesg.event == PM_EVENT_PRETHAW)
2162 par->pm_state = state.event; 2334 mesg.event = PM_EVENT_FREEZE;
2335 par->pm_state = mesg.event;
2336 dev->dev.power.power_state = mesg;
2163 2337
2164 /* 2338 /*
2165 * For PM_EVENT_FREEZE, do not power down so the console 2339 * For PM_EVENT_FREEZE, do not power down so the console
2166 * can remain active. 2340 * can remain active.
2167 */ 2341 */
2168 if (state.event == PM_EVENT_FREEZE) { 2342 if (mesg.event == PM_EVENT_FREEZE)
2169 dev->dev.power.power_state = state;
2170 return 0; 2343 return 0;
2171 }
2172 2344
2173 acquire_console_sem(); 2345 acquire_console_sem();
2174 fb_set_suspend(info, 1); 2346 fb_set_suspend(info, 1);
@@ -2177,16 +2349,17 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state)
2177 info->fbops->fb_sync(info); 2349 info->fbops->fb_sync(info);
2178 2350
2179 savagefb_blank(FB_BLANK_POWERDOWN, info); 2351 savagefb_blank(FB_BLANK_POWERDOWN, info);
2352 savage_set_default_par(par, &par->save);
2180 savage_disable_mmio(par); 2353 savage_disable_mmio(par);
2181 pci_save_state(dev); 2354 pci_save_state(dev);
2182 pci_disable_device(dev); 2355 pci_disable_device(dev);
2183 pci_set_power_state(dev, pci_choose_state(dev, state)); 2356 pci_set_power_state(dev, pci_choose_state(dev, mesg));
2184 release_console_sem(); 2357 release_console_sem();
2185 2358
2186 return 0; 2359 return 0;
2187} 2360}
2188 2361
2189static int savagefb_resume (struct pci_dev* dev) 2362static int savagefb_resume(struct pci_dev* dev)
2190{ 2363{
2191 struct fb_info *info = pci_get_drvdata(dev); 2364 struct fb_info *info = pci_get_drvdata(dev);
2192 struct savagefb_par *par = info->par; 2365 struct savagefb_par *par = info->par;
@@ -2210,15 +2383,15 @@ static int savagefb_resume (struct pci_dev* dev)
2210 pci_set_power_state(dev, PCI_D0); 2383 pci_set_power_state(dev, PCI_D0);
2211 pci_restore_state(dev); 2384 pci_restore_state(dev);
2212 2385
2213 if(pci_enable_device(dev)) 2386 if (pci_enable_device(dev))
2214 DBG("err"); 2387 DBG("err");
2215 2388
2216 pci_set_master(dev); 2389 pci_set_master(dev);
2217 savage_enable_mmio(par); 2390 savage_enable_mmio(par);
2218 savage_init_hw(par); 2391 savage_init_hw(par);
2219 savagefb_set_par (info); 2392 savagefb_set_par(info);
2393 fb_set_suspend(info, 0);
2220 savagefb_blank(FB_BLANK_UNBLANK, info); 2394 savagefb_blank(FB_BLANK_UNBLANK, info);
2221 fb_set_suspend (info, 0);
2222 release_console_sem(); 2395 release_console_sem();
2223 2396
2224 return 0; 2397 return 0;
@@ -2311,10 +2484,10 @@ static struct pci_driver savagefb_driver = {
2311 2484
2312/* **************************** exit-time only **************************** */ 2485/* **************************** exit-time only **************************** */
2313 2486
2314static void __exit savage_done (void) 2487static void __exit savage_done(void)
2315{ 2488{
2316 DBG("savage_done"); 2489 DBG("savage_done");
2317 pci_unregister_driver (&savagefb_driver); 2490 pci_unregister_driver(&savagefb_driver);
2318} 2491}
2319 2492
2320 2493
@@ -2345,7 +2518,7 @@ static int __init savagefb_init(void)
2345 return -ENODEV; 2518 return -ENODEV;
2346 2519
2347 savagefb_setup(option); 2520 savagefb_setup(option);
2348 return pci_register_driver (&savagefb_driver); 2521 return pci_register_driver(&savagefb_driver);
2349 2522
2350} 2523}
2351 2524
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 2e6df1fcb2b9..ebb6756aea08 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -9,7 +9,6 @@
9 * more details. 9 * more details.
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/module.h> 12#include <linux/module.h>
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/mm.h> 14#include <linux/mm.h>
@@ -23,6 +22,8 @@
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/mtrr.h> 23#include <asm/mtrr.h>
25 24
25#include <setup_arch.h>
26
26#define INCLUDE_TIMING_TABLE_DATA 27#define INCLUDE_TIMING_TABLE_DATA
27#define DBE_REG_BASE par->regs 28#define DBE_REG_BASE par->regs
28#include <video/sgivw.h> 29#include <video/sgivw.h>
@@ -42,10 +43,6 @@ struct sgivw_par {
42 * The default can be overridden if the driver is compiled as a module 43 * The default can be overridden if the driver is compiled as a module
43 */ 44 */
44 45
45/* set by arch/i386/kernel/setup.c */
46extern unsigned long sgivwfb_mem_phys;
47extern unsigned long sgivwfb_mem_size;
48
49static int ypan = 0; 46static int ypan = 0;
50static int ywrap = 0; 47static int ywrap = 0;
51 48
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 634c0a9d219b..7ecab87cef02 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -73,7 +73,6 @@
73#ifdef SIS_CP 73#ifdef SIS_CP
74#undef SIS_CP 74#undef SIS_CP
75#endif 75#endif
76#include <linux/config.h>
77#include <linux/version.h> 76#include <linux/version.h>
78#include <linux/types.h> 77#include <linux/types.h>
79#include <asm/io.h> 78#include <asm/io.h>
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index c3e070a6effd..f13faddc6181 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -8043,8 +8043,8 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
8043 SiS_SetCH700x(SiS_Pr,0x01,0x28); 8043 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8044 8044
8045 /* Set video bandwidth 8045 /* Set video bandwidth
8046 High bandwith Luma composite video filter(S0=1) 8046 High bandwidth Luma composite video filter(S0=1)
8047 low bandwith Luma S-video filter (S2-1=00) 8047 low bandwidth Luma S-video filter (S2-1=00)
8048 disable peak filter in S-video channel (S3=0) 8048 disable peak filter in S-video channel (S3=0)
8049 high bandwidth Chroma Filter (S5-4=11) 8049 high bandwidth Chroma Filter (S5-4=11)
8050 =00110001=0x31 8050 =00110001=0x31
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index f475b21a85cf..bc321dc57e92 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -67,7 +67,6 @@
67#ifdef SIS_CP 67#ifdef SIS_CP
68#undef SIS_CP 68#undef SIS_CP
69#endif 69#endif
70#include <linux/config.h>
71#include <linux/version.h> 70#include <linux/version.h>
72#include <linux/types.h> 71#include <linux/types.h>
73#include <asm/io.h> 72#include <asm/io.h>
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index cc856d90903c..09f5d758b6c0 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -30,7 +30,6 @@
30#include "vgatypes.h" 30#include "vgatypes.h"
31#include "vstruct.h" 31#include "vstruct.h"
32 32
33#include <linux/config.h>
34#include <linux/version.h> 33#include <linux/version.h>
35#include <linux/types.h> 34#include <linux/types.h>
36#include <linux/fb.h> 35#include <linux/fb.h>
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index 841ca3190cd4..f59568020eb2 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -90,7 +90,6 @@
90/**********************************************************************/ 90/**********************************************************************/
91 91
92#ifdef SIS_LINUX_KERNEL 92#ifdef SIS_LINUX_KERNEL
93#include <linux/config.h>
94#include <linux/version.h> 93#include <linux/version.h>
95 94
96#ifdef CONFIG_FB_SIS_300 95#ifdef CONFIG_FB_SIS_300
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index 0b6e625d7331..a259446ca7fe 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -24,7 +24,6 @@
24#ifndef _SIS_H_ 24#ifndef _SIS_H_
25#define _SIS_H_ 25#define _SIS_H_
26 26
27#include <linux/config.h>
28#include <linux/version.h> 27#include <linux/version.h>
29 28
30#include "osdef.h" 29#include "osdef.h"
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
index bab933e6c6a6..3b7ce032e2ed 100644
--- a/drivers/video/sis/sis_accel.c
+++ b/drivers/video/sis/sis_accel.c
@@ -28,7 +28,6 @@
28 * for more information and updates) 28 * for more information and updates)
29 */ 29 */
30 30
31#include <linux/config.h>
32#include <linux/version.h> 31#include <linux/version.h>
33#include <linux/module.h> 32#include <linux/module.h>
34#include <linux/kernel.h> 33#include <linux/kernel.h>
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 8adf5bf91eee..895ebda7d9e3 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -33,7 +33,6 @@
33 * 33 *
34 */ 34 */
35 35
36#include <linux/config.h>
37#include <linux/version.h> 36#include <linux/version.h>
38#include <linux/module.h> 37#include <linux/module.h>
39#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 38#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
@@ -45,7 +44,13 @@
45#include <linux/errno.h> 44#include <linux/errno.h>
46#include <linux/string.h> 45#include <linux/string.h>
47#include <linux/mm.h> 46#include <linux/mm.h>
47
48#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
48#include <linux/tty.h> 49#include <linux/tty.h>
50#else
51#include <linux/screen_info.h>
52#endif
53
49#include <linux/slab.h> 54#include <linux/slab.h>
50#include <linux/fb.h> 55#include <linux/fb.h>
51#include <linux/selection.h> 56#include <linux/selection.h>
@@ -275,7 +280,7 @@ sisfb_search_mode(char *name, BOOLEAN quiet)
275static void __devinit 280static void __devinit
276sisfb_get_vga_mode_from_kernel(void) 281sisfb_get_vga_mode_from_kernel(void)
277{ 282{
278#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT) 283#ifdef CONFIG_X86
279 char mymode[32]; 284 char mymode[32];
280 int mydepth = screen_info.lfb_depth; 285 int mydepth = screen_info.lfb_depth;
281 286
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 9b707771d757..bb96cb65fdaa 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -47,7 +47,6 @@
47#include <linux/errno.h> 47#include <linux/errno.h>
48#include <linux/string.h> 48#include <linux/string.h>
49#include <linux/mm.h> 49#include <linux/mm.h>
50#include <linux/tty.h>
51#include <linux/slab.h> 50#include <linux/slab.h>
52#include <linux/delay.h> 51#include <linux/delay.h>
53#include <linux/fb.h> 52#include <linux/fb.h>
@@ -906,11 +905,6 @@ static void __exit xxxfb_exit(void)
906} 905}
907#endif 906#endif
908 907
909MODULE_LICENSE("GPL");
910module_init(xxxfb_init);
911module_exit(xxxfb_exit);
912
913
914 /* 908 /*
915 * Setup 909 * Setup
916 */ 910 */
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index c44de90ca12e..dad54e73147b 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -82,7 +82,6 @@
82 * Includes 82 * Includes
83 */ 83 */
84 84
85#include <linux/config.h>
86#include <linux/string.h> 85#include <linux/string.h>
87#include <linux/kernel.h> 86#include <linux/kernel.h>
88#include <linux/module.h> 87#include <linux/module.h>
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 4a292aae6eb2..3e16e2d9d55d 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -54,7 +54,6 @@
54#undef DEBUG_STIFB_REGS /* debug sti register accesses */ 54#undef DEBUG_STIFB_REGS /* debug sti register accesses */
55 55
56 56
57#include <linux/config.h>
58#include <linux/module.h> 57#include <linux/module.h>
59#include <linux/kernel.h> 58#include <linux/kernel.h>
60#include <linux/errno.h> 59#include <linux/errno.h>
diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c
index 9b36b9df535f..f80356dfa8e8 100644
--- a/drivers/video/sun3fb.c
+++ b/drivers/video/sun3fb.c
@@ -25,13 +25,11 @@
25 * more details. 25 * more details.
26 */ 26 */
27 27
28#include <linux/config.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/errno.h> 30#include <linux/errno.h>
32#include <linux/string.h> 31#include <linux/string.h>
33#include <linux/mm.h> 32#include <linux/mm.h>
34#include <linux/tty.h>
35#include <linux/slab.h> 33#include <linux/slab.h>
36#include <linux/vmalloc.h> 34#include <linux/vmalloc.h>
37#include <linux/delay.h> 35#include <linux/delay.h>
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 95b918229d9b..6990ab11cd06 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -1,6 +1,6 @@
1/* tcx.c: TCX frame buffer driver 1/* tcx.c: TCX frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) 6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,8 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20 20
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/sbus.h> 22#include <asm/prom.h>
23#include <asm/oplib.h> 23#include <asm/of_device.h>
24#include <asm/fbio.h> 24#include <asm/fbio.h>
25 25
26#include "sbuslib.h" 26#include "sbuslib.h"
@@ -77,32 +77,32 @@ static struct fb_ops tcx_ops = {
77 77
78/* The contents are unknown */ 78/* The contents are unknown */
79struct tcx_tec { 79struct tcx_tec {
80 volatile u32 tec_matrix; 80 u32 tec_matrix;
81 volatile u32 tec_clip; 81 u32 tec_clip;
82 volatile u32 tec_vdc; 82 u32 tec_vdc;
83}; 83};
84 84
85struct tcx_thc { 85struct tcx_thc {
86 volatile u32 thc_rev; 86 u32 thc_rev;
87 u32 thc_pad0[511]; 87 u32 thc_pad0[511];
88 volatile u32 thc_hs; /* hsync timing */ 88 u32 thc_hs; /* hsync timing */
89 volatile u32 thc_hsdvs; 89 u32 thc_hsdvs;
90 volatile u32 thc_hd; 90 u32 thc_hd;
91 volatile u32 thc_vs; /* vsync timing */ 91 u32 thc_vs; /* vsync timing */
92 volatile u32 thc_vd; 92 u32 thc_vd;
93 volatile u32 thc_refresh; 93 u32 thc_refresh;
94 volatile u32 thc_misc; 94 u32 thc_misc;
95 u32 thc_pad1[56]; 95 u32 thc_pad1[56];
96 volatile u32 thc_cursxy; /* cursor x,y position (16 bits each) */ 96 u32 thc_cursxy; /* cursor x,y position (16 bits each) */
97 volatile u32 thc_cursmask[32]; /* cursor mask bits */ 97 u32 thc_cursmask[32]; /* cursor mask bits */
98 volatile u32 thc_cursbits[32]; /* what to show where mask enabled */ 98 u32 thc_cursbits[32]; /* what to show where mask enabled */
99}; 99};
100 100
101struct bt_regs { 101struct bt_regs {
102 volatile u32 addr; 102 u32 addr;
103 volatile u32 color_map; 103 u32 color_map;
104 volatile u32 control; 104 u32 control;
105 volatile u32 cursor; 105 u32 cursor;
106}; 106};
107 107
108#define TCX_MMAP_ENTRIES 14 108#define TCX_MMAP_ENTRIES 14
@@ -112,24 +112,23 @@ struct tcx_par {
112 struct bt_regs __iomem *bt; 112 struct bt_regs __iomem *bt;
113 struct tcx_thc __iomem *thc; 113 struct tcx_thc __iomem *thc;
114 struct tcx_tec __iomem *tec; 114 struct tcx_tec __iomem *tec;
115 volatile u32 __iomem *cplane; 115 u32 __iomem *cplane;
116 116
117 u32 flags; 117 u32 flags;
118#define TCX_FLAG_BLANKED 0x00000001 118#define TCX_FLAG_BLANKED 0x00000001
119 119
120 unsigned long physbase; 120 unsigned long physbase;
121 unsigned long which_io;
121 unsigned long fbsize; 122 unsigned long fbsize;
122 123
123 struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES]; 124 struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES];
124 int lowdepth; 125 int lowdepth;
125
126 struct sbus_dev *sdev;
127}; 126};
128 127
129/* Reset control plane so that WID is 8-bit plane. */ 128/* Reset control plane so that WID is 8-bit plane. */
130static void __tcx_set_control_plane (struct tcx_par *par) 129static void __tcx_set_control_plane (struct tcx_par *par)
131{ 130{
132 volatile u32 __iomem *p, *pend; 131 u32 __iomem *p, *pend;
133 132
134 if (par->lowdepth) 133 if (par->lowdepth)
135 return; 134 return;
@@ -307,8 +306,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
307 306
308 return sbusfb_mmap_helper(par->mmap_map, 307 return sbusfb_mmap_helper(par->mmap_map,
309 par->physbase, par->fbsize, 308 par->physbase, par->fbsize,
310 par->sdev->reg_addrs[0].which_io, 309 par->which_io, vma);
311 vma);
312} 310}
313 311
314static int tcx_ioctl(struct fb_info *info, unsigned int cmd, 312static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
@@ -350,48 +348,71 @@ tcx_init_fix(struct fb_info *info, int linebytes)
350struct all_info { 348struct all_info {
351 struct fb_info info; 349 struct fb_info info;
352 struct tcx_par par; 350 struct tcx_par par;
353 struct list_head list;
354}; 351};
355static LIST_HEAD(tcx_list);
356 352
357static void tcx_init_one(struct sbus_dev *sdev) 353static void tcx_unmap_regs(struct all_info *all)
358{ 354{
359 struct all_info *all; 355 if (all->par.tec)
360 int linebytes, i; 356 of_iounmap(all->par.tec, sizeof(struct tcx_tec));
357 if (all->par.thc)
358 of_iounmap(all->par.thc, sizeof(struct tcx_thc));
359 if (all->par.bt)
360 of_iounmap(all->par.bt, sizeof(struct bt_regs));
361 if (all->par.cplane)
362 of_iounmap(all->par.cplane, all->par.fbsize * sizeof(u32));
363 if (all->info.screen_base)
364 of_iounmap(all->info.screen_base, all->par.fbsize);
365}
361 366
362 all = kmalloc(sizeof(*all), GFP_KERNEL); 367static int __devinit tcx_init_one(struct of_device *op)
363 if (!all) { 368{
364 printk(KERN_ERR "tcx: Cannot allocate memory.\n"); 369 struct device_node *dp = op->node;
365 return; 370 struct all_info *all;
366 } 371 int linebytes, i, err;
367 memset(all, 0, sizeof(*all));
368 372
369 INIT_LIST_HEAD(&all->list); 373 all = kzalloc(sizeof(*all), GFP_KERNEL);
374 if (!all)
375 return -ENOMEM;
370 376
371 spin_lock_init(&all->par.lock); 377 spin_lock_init(&all->par.lock);
372 all->par.sdev = sdev;
373 378
374 all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit"); 379 all->par.lowdepth =
380 (of_find_property(dp, "tcx-8-bit", NULL) != NULL);
375 381
376 sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); 382 sbusfb_fill_var(&all->info.var, dp->node, 8);
377 all->info.var.red.length = 8; 383 all->info.var.red.length = 8;
378 all->info.var.green.length = 8; 384 all->info.var.green.length = 8;
379 all->info.var.blue.length = 8; 385 all->info.var.blue.length = 8;
380 386
381 linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 387 linebytes = of_getintprop_default(dp, "linebytes",
382 all->info.var.xres); 388 all->info.var.xres);
383 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 389 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
384 390
385 all->par.tec = sbus_ioremap(&sdev->resource[7], 0, 391 all->par.tec = of_ioremap(&op->resource[7], 0,
386 sizeof(struct tcx_tec), "tcx tec"); 392 sizeof(struct tcx_tec), "tcx tec");
387 all->par.thc = sbus_ioremap(&sdev->resource[9], 0, 393 all->par.thc = of_ioremap(&op->resource[9], 0,
388 sizeof(struct tcx_thc), "tcx thc"); 394 sizeof(struct tcx_thc), "tcx thc");
389 all->par.bt = sbus_ioremap(&sdev->resource[8], 0, 395 all->par.bt = of_ioremap(&op->resource[8], 0,
390 sizeof(struct bt_regs), "tcx dac"); 396 sizeof(struct bt_regs), "tcx dac");
397 all->info.screen_base = of_ioremap(&op->resource[0], 0,
398 all->par.fbsize, "tcx ram");
399 if (!all->par.tec || !all->par.thc ||
400 !all->par.bt || !all->info.screen_base) {
401 tcx_unmap_regs(all);
402 kfree(all);
403 return -ENOMEM;
404 }
405
391 memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map)); 406 memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map));
392 if (!all->par.lowdepth) { 407 if (!all->par.lowdepth) {
393 all->par.cplane = sbus_ioremap(&sdev->resource[4], 0, 408 all->par.cplane = of_ioremap(&op->resource[4], 0,
394 all->par.fbsize * sizeof(u32), "tcx cplane"); 409 all->par.fbsize * sizeof(u32),
410 "tcx cplane");
411 if (!all->par.cplane) {
412 tcx_unmap_regs(all);
413 kfree(all);
414 return -ENOMEM;
415 }
395 } else { 416 } else {
396 all->par.mmap_map[1].size = SBUS_MMAP_EMPTY; 417 all->par.mmap_map[1].size = SBUS_MMAP_EMPTY;
397 all->par.mmap_map[4].size = SBUS_MMAP_EMPTY; 418 all->par.mmap_map[4].size = SBUS_MMAP_EMPTY;
@@ -400,6 +421,8 @@ static void tcx_init_one(struct sbus_dev *sdev)
400 } 421 }
401 422
402 all->par.physbase = 0; 423 all->par.physbase = 0;
424 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
425
403 for (i = 0; i < TCX_MMAP_ENTRIES; i++) { 426 for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
404 int j; 427 int j;
405 428
@@ -416,18 +439,11 @@ static void tcx_init_one(struct sbus_dev *sdev)
416 j = i; 439 j = i;
417 break; 440 break;
418 }; 441 };
419 all->par.mmap_map[i].poff = sdev->reg_addrs[j].phys_addr; 442 all->par.mmap_map[i].poff = op->resource[j].start;
420 } 443 }
421 444
422 all->info.flags = FBINFO_DEFAULT; 445 all->info.flags = FBINFO_DEFAULT;
423 all->info.fbops = &tcx_ops; 446 all->info.fbops = &tcx_ops;
424#ifdef CONFIG_SPARC32
425 all->info.screen_base = (char __iomem *)
426 prom_getintdefault(sdev->prom_node, "address", 0);
427#endif
428 if (!all->info.screen_base)
429 all->info.screen_base = sbus_ioremap(&sdev->resource[0], 0,
430 all->par.fbsize, "tcx ram");
431 all->info.par = &all->par; 447 all->info.par = &all->par;
432 448
433 /* Initialize brooktree DAC. */ 449 /* Initialize brooktree DAC. */
@@ -445,72 +461,88 @@ static void tcx_init_one(struct sbus_dev *sdev)
445 tcx_blank(FB_BLANK_UNBLANK, &all->info); 461 tcx_blank(FB_BLANK_UNBLANK, &all->info);
446 462
447 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 463 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
448 printk(KERN_ERR "tcx: Could not allocate color map.\n"); 464 tcx_unmap_regs(all);
449 kfree(all); 465 kfree(all);
450 return; 466 return -ENOMEM;
451 } 467 }
452 468
453 fb_set_cmap(&all->info.cmap, &all->info); 469 fb_set_cmap(&all->info.cmap, &all->info);
454 tcx_init_fix(&all->info, linebytes); 470 tcx_init_fix(&all->info, linebytes);
455 471
456 if (register_framebuffer(&all->info) < 0) { 472 err = register_framebuffer(&all->info);
457 printk(KERN_ERR "tcx: Could not register framebuffer.\n"); 473 if (err < 0) {
458 fb_dealloc_cmap(&all->info.cmap); 474 fb_dealloc_cmap(&all->info.cmap);
475 tcx_unmap_regs(all);
459 kfree(all); 476 kfree(all);
460 return; 477 return err;
461 } 478 }
462 479
463 list_add(&all->list, &tcx_list); 480 dev_set_drvdata(&op->dev, all);
464 481
465 printk("tcx: %s at %lx:%lx, %s\n", 482 printk("%s: TCX at %lx:%lx, %s\n",
466 sdev->prom_name, 483 dp->full_name,
467 (long) sdev->reg_addrs[0].which_io, 484 all->par.which_io,
468 (long) sdev->reg_addrs[0].phys_addr, 485 op->resource[0].start,
469 all->par.lowdepth ? "8-bit only" : "24-bit depth"); 486 all->par.lowdepth ? "8-bit only" : "24-bit depth");
487
488 return 0;
470} 489}
471 490
472int __init tcx_init(void) 491static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match)
473{ 492{
474 struct sbus_bus *sbus; 493 struct of_device *op = to_of_device(&dev->dev);
475 struct sbus_dev *sdev;
476 494
477 if (fb_get_options("tcxfb", NULL)) 495 return tcx_init_one(op);
478 return -ENODEV; 496}
479 497
480 for_all_sbusdev(sdev, sbus) { 498static int __devexit tcx_remove(struct of_device *dev)
481 if (!strcmp(sdev->prom_name, "SUNW,tcx")) 499{
482 tcx_init_one(sdev); 500 struct all_info *all = dev_get_drvdata(&dev->dev);
483 } 501
502 unregister_framebuffer(&all->info);
503 fb_dealloc_cmap(&all->info.cmap);
504
505 tcx_unmap_regs(all);
506
507 kfree(all);
508
509 dev_set_drvdata(&dev->dev, NULL);
484 510
485 return 0; 511 return 0;
486} 512}
487 513
488void __exit tcx_exit(void) 514static struct of_device_id tcx_match[] = {
489{ 515 {
490 struct list_head *pos, *tmp; 516 .name = "SUNW,tcx",
517 },
518 {},
519};
520MODULE_DEVICE_TABLE(of, tcx_match);
491 521
492 list_for_each_safe(pos, tmp, &tcx_list) { 522static struct of_platform_driver tcx_driver = {
493 struct all_info *all = list_entry(pos, typeof(*all), list); 523 .name = "tcx",
524 .match_table = tcx_match,
525 .probe = tcx_probe,
526 .remove = __devexit_p(tcx_remove),
527};
494 528
495 unregister_framebuffer(&all->info); 529int __init tcx_init(void)
496 fb_dealloc_cmap(&all->info.cmap); 530{
497 kfree(all); 531 if (fb_get_options("tcxfb", NULL))
498 } 532 return -ENODEV;
533
534 return of_register_driver(&tcx_driver, &of_bus_type);
499} 535}
500 536
501int __init 537void __exit tcx_exit(void)
502tcx_setup(char *arg)
503{ 538{
504 /* No cmdline options yet... */ 539 of_unregister_driver(&tcx_driver);
505 return 0;
506} 540}
507 541
508module_init(tcx_init); 542module_init(tcx_init);
509
510#ifdef MODULE
511module_exit(tcx_exit); 543module_exit(tcx_exit);
512#endif
513 544
514MODULE_DESCRIPTION("framebuffer driver for TCX chipsets"); 545MODULE_DESCRIPTION("framebuffer driver for TCX chipsets");
515MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 546MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
547MODULE_VERSION("2.0");
516MODULE_LICENSE("GPL"); 548MODULE_LICENSE("GPL");
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 5e5328d682db..689ce0270b81 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -58,13 +58,11 @@
58 * 58 *
59 */ 59 */
60 60
61#include <linux/config.h>
62#include <linux/module.h> 61#include <linux/module.h>
63#include <linux/kernel.h> 62#include <linux/kernel.h>
64#include <linux/errno.h> 63#include <linux/errno.h>
65#include <linux/string.h> 64#include <linux/string.h>
66#include <linux/mm.h> 65#include <linux/mm.h>
67#include <linux/tty.h>
68#include <linux/slab.h> 66#include <linux/slab.h>
69#include <linux/delay.h> 67#include <linux/delay.h>
70#include <linux/interrupt.h> 68#include <linux/interrupt.h>
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 7398bd48ba6c..94fde625a6c0 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -17,7 +17,6 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/tty.h>
21#include <linux/slab.h> 20#include <linux/slab.h>
22#include <linux/delay.h> 21#include <linux/delay.h>
23#include <linux/init.h> 22#include <linux/init.h>
@@ -26,7 +25,6 @@
26#include <linux/selection.h> 25#include <linux/selection.h>
27#include <asm/io.h> 26#include <asm/io.h>
28#include <video/tgafb.h> 27#include <video/tgafb.h>
29#include <linux/selection.h>
30 28
31/* 29/*
32 * Local functions. 30 * Local functions.
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 9ac2d3171187..14175cdb9c9c 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -15,7 +15,6 @@
15 * TGUI acceleration 15 * TGUI acceleration
16 */ 16 */
17 17
18#include <linux/config.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/fb.h> 19#include <linux/fb.h>
21#include <linux/init.h> 20#include <linux/init.h>
@@ -551,7 +550,7 @@ static inline void enable_mmio(void)
551#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) 550#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
552 551
553/* Return flat panel's maximum x resolution */ 552/* Return flat panel's maximum x resolution */
554static int __init get_nativex(void) 553static int __devinit get_nativex(void)
555{ 554{
556 int x,y,tmp; 555 int x,y,tmp;
557 556
@@ -658,7 +657,7 @@ static void set_number_of_lines(int lines)
658 * If we see that FP is active we assume we have one. 657 * If we see that FP is active we assume we have one.
659 * Otherwise we have a CRT display.User can override. 658 * Otherwise we have a CRT display.User can override.
660 */ 659 */
661static unsigned int __init get_displaytype(void) 660static unsigned int __devinit get_displaytype(void)
662{ 661{
663 if (fp) 662 if (fp)
664 return DISPLAY_FP; 663 return DISPLAY_FP;
@@ -668,7 +667,7 @@ static unsigned int __init get_displaytype(void)
668} 667}
669 668
670/* Try detecting the video memory size */ 669/* Try detecting the video memory size */
671static unsigned int __init get_memsize(void) 670static unsigned int __devinit get_memsize(void)
672{ 671{
673 unsigned char tmp, tmp2; 672 unsigned char tmp, tmp2;
674 unsigned int k; 673 unsigned int k;
diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
index d904da44e1aa..07389ba01eff 100644
--- a/drivers/video/tx3912fb.c
+++ b/drivers/video/tx3912fb.c
@@ -14,7 +14,6 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/tty.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/init.h> 19#include <linux/init.h>
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 2bdeb4baa952..47f27924a7d7 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -39,13 +39,11 @@
39 * more details. 39 * more details.
40 */ 40 */
41 41
42#include <linux/config.h>
43#include <linux/module.h> 42#include <linux/module.h>
44#include <linux/kernel.h> 43#include <linux/kernel.h>
45#include <linux/errno.h> 44#include <linux/errno.h>
46#include <linux/string.h> 45#include <linux/string.h>
47#include <linux/mm.h> 46#include <linux/mm.h>
48#include <linux/tty.h>
49#include <linux/slab.h> 47#include <linux/slab.h>
50#include <linux/vmalloc.h> 48#include <linux/vmalloc.h>
51#include <linux/delay.h> 49#include <linux/delay.h>
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index b0b9acfdd430..2196448396ec 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -13,13 +13,13 @@
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/tty.h>
17#include <linux/slab.h> 16#include <linux/slab.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
19#include <linux/fb.h> 18#include <linux/fb.h>
20#include <linux/ioport.h> 19#include <linux/ioport.h>
21#include <linux/init.h> 20#include <linux/init.h>
22#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/screen_info.h>
23 23
24#include <video/vga.h> 24#include <video/vga.h>
25#include <asm/io.h> 25#include <asm/io.h>
@@ -51,7 +51,7 @@ static int inverse = 0;
51static int mtrr = 0; /* disable mtrr */ 51static int mtrr = 0; /* disable mtrr */
52static int vram_remap __initdata = 0; /* Set amount of memory to be used */ 52static int vram_remap __initdata = 0; /* Set amount of memory to be used */
53static int vram_total __initdata = 0; /* Set total amount of memory */ 53static int vram_total __initdata = 0; /* Set total amount of memory */
54static int pmi_setpal = 0; /* pmi for palette changes ??? */ 54static int pmi_setpal = 1; /* pmi for palette changes ??? */
55static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ 55static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */
56static unsigned short *pmi_base = NULL; 56static unsigned short *pmi_base = NULL;
57static void (*pmi_start)(void); 57static void (*pmi_start)(void);
@@ -80,15 +80,30 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
80 return 0; 80 return 0;
81} 81}
82 82
83static void vesa_setpalette(int regno, unsigned red, unsigned green, 83static int vesa_setpalette(int regno, unsigned red, unsigned green,
84 unsigned blue) 84 unsigned blue)
85{ 85{
86 int shift = 16 - depth; 86 int shift = 16 - depth;
87 int err = -EINVAL;
88
89/*
90 * Try VGA registers first...
91 */
92 if (vga_compat) {
93 outb_p(regno, dac_reg);
94 outb_p(red >> shift, dac_val);
95 outb_p(green >> shift, dac_val);
96 outb_p(blue >> shift, dac_val);
97 err = 0;
98 }
87 99
88#ifdef __i386__ 100#ifdef __i386__
89 struct { u_char blue, green, red, pad; } entry; 101/*
102 * Fallback to the PMI....
103 */
104 if (err && pmi_setpal) {
105 struct { u_char blue, green, red, pad; } entry;
90 106
91 if (pmi_setpal) {
92 entry.red = red >> shift; 107 entry.red = red >> shift;
93 entry.green = green >> shift; 108 entry.green = green >> shift;
94 entry.blue = blue >> shift; 109 entry.blue = blue >> shift;
@@ -102,26 +117,19 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green,
102 "d" (regno), /* EDX */ 117 "d" (regno), /* EDX */
103 "D" (&entry), /* EDI */ 118 "D" (&entry), /* EDI */
104 "S" (&pmi_pal)); /* ESI */ 119 "S" (&pmi_pal)); /* ESI */
105 return; 120 err = 0;
106 } 121 }
107#endif 122#endif
108 123
109/* 124 return err;
110 * without protected mode interface and if VGA compatible,
111 * try VGA registers...
112 */
113 if (vga_compat) {
114 outb_p(regno, dac_reg);
115 outb_p(red >> shift, dac_val);
116 outb_p(green >> shift, dac_val);
117 outb_p(blue >> shift, dac_val);
118 }
119} 125}
120 126
121static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, 127static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
122 unsigned blue, unsigned transp, 128 unsigned blue, unsigned transp,
123 struct fb_info *info) 129 struct fb_info *info)
124{ 130{
131 int err = 0;
132
125 /* 133 /*
126 * Set a single color register. The values supplied are 134 * Set a single color register. The values supplied are
127 * already rounded down to the hardware's capabilities 135 * already rounded down to the hardware's capabilities
@@ -133,7 +141,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
133 return 1; 141 return 1;
134 142
135 if (info->var.bits_per_pixel == 8) 143 if (info->var.bits_per_pixel == 8)
136 vesa_setpalette(regno,red,green,blue); 144 err = vesa_setpalette(regno,red,green,blue);
137 else if (regno < 16) { 145 else if (regno < 16) {
138 switch (info->var.bits_per_pixel) { 146 switch (info->var.bits_per_pixel) {
139 case 16: 147 case 16:
@@ -164,7 +172,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
164 } 172 }
165 } 173 }
166 174
167 return 0; 175 return err;
168} 176}
169 177
170static struct fb_ops vesafb_ops = { 178static struct fb_ops vesafb_ops = {
@@ -460,9 +468,7 @@ static struct platform_driver vesafb_driver = {
460 }, 468 },
461}; 469};
462 470
463static struct platform_device vesafb_device = { 471static struct platform_device *vesafb_device;
464 .name = "vesafb",
465};
466 472
467static int __init vesafb_init(void) 473static int __init vesafb_init(void)
468{ 474{
@@ -475,10 +481,19 @@ static int __init vesafb_init(void)
475 ret = platform_driver_register(&vesafb_driver); 481 ret = platform_driver_register(&vesafb_driver);
476 482
477 if (!ret) { 483 if (!ret) {
478 ret = platform_device_register(&vesafb_device); 484 vesafb_device = platform_device_alloc("vesafb", 0);
479 if (ret) 485
486 if (vesafb_device)
487 ret = platform_device_add(vesafb_device);
488 else
489 ret = -ENOMEM;
490
491 if (ret) {
492 platform_device_put(vesafb_device);
480 platform_driver_unregister(&vesafb_driver); 493 platform_driver_unregister(&vesafb_driver);
494 }
481 } 495 }
496
482 return ret; 497 return ret;
483} 498}
484module_init(vesafb_init); 499module_init(vesafb_init);
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 77eed1fd9943..a9b99b01bd8e 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -15,7 +15,6 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/tty.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/vmalloc.h> 19#include <linux/vmalloc.h>
21#include <linux/delay.h> 20#include <linux/delay.h>
@@ -398,12 +397,6 @@ static int __init vfb_setup(char *options)
398 * Initialisation 397 * Initialisation
399 */ 398 */
400 399
401static void vfb_platform_release(struct device *device)
402{
403 // This is called when the reference count goes to zero.
404 dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
405}
406
407static int __init vfb_probe(struct platform_device *dev) 400static int __init vfb_probe(struct platform_device *dev)
408{ 401{
409 struct fb_info *info; 402 struct fb_info *info;
@@ -482,13 +475,7 @@ static struct platform_driver vfb_driver = {
482 }, 475 },
483}; 476};
484 477
485static struct platform_device vfb_device = { 478static struct platform_device *vfb_device;
486 .name = "vfb",
487 .id = 0,
488 .dev = {
489 .release = vfb_platform_release,
490 }
491};
492 479
493static int __init vfb_init(void) 480static int __init vfb_init(void)
494{ 481{
@@ -508,10 +495,19 @@ static int __init vfb_init(void)
508 ret = platform_driver_register(&vfb_driver); 495 ret = platform_driver_register(&vfb_driver);
509 496
510 if (!ret) { 497 if (!ret) {
511 ret = platform_device_register(&vfb_device); 498 vfb_device = platform_device_alloc("vfb", 0);
512 if (ret) 499
500 if (vfb_device)
501 ret = platform_device_add(vfb_device);
502 else
503 ret = -ENOMEM;
504
505 if (ret) {
506 platform_device_put(vfb_device);
513 platform_driver_unregister(&vfb_driver); 507 platform_driver_unregister(&vfb_driver);
508 }
514 } 509 }
510
515 return ret; 511 return ret;
516} 512}
517 513
@@ -520,7 +516,7 @@ module_init(vfb_init);
520#ifdef MODULE 516#ifdef MODULE
521static void __exit vfb_exit(void) 517static void __exit vfb_exit(void)
522{ 518{
523 platform_device_unregister(&vfb_device); 519 platform_device_unregister(vfb_device);
524 platform_driver_unregister(&vfb_driver); 520 platform_driver_unregister(&vfb_driver);
525} 521}
526 522
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 4fd2a272e03d..43d5a6d9c4a6 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -15,13 +15,13 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/tty.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/delay.h> 19#include <linux/delay.h>
21#include <linux/fb.h> 20#include <linux/fb.h>
22#include <linux/ioport.h> 21#include <linux/ioport.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/screen_info.h>
25 25
26#include <asm/io.h> 26#include <asm/io.h>
27#include <video/vga.h> 27#include <video/vga.h>
@@ -1334,9 +1334,8 @@ static int vga16fb_setup(char *options)
1334} 1334}
1335#endif 1335#endif
1336 1336
1337static int __init vga16fb_probe(struct device *device) 1337static int __init vga16fb_probe(struct platform_device *dev)
1338{ 1338{
1339 struct platform_device *dev = to_platform_device(device);
1340 struct fb_info *info; 1339 struct fb_info *info;
1341 struct vga16fb_par *par; 1340 struct vga16fb_par *par;
1342 int i; 1341 int i;
@@ -1403,7 +1402,7 @@ static int __init vga16fb_probe(struct device *device)
1403 1402
1404 printk(KERN_INFO "fb%d: %s frame buffer device\n", 1403 printk(KERN_INFO "fb%d: %s frame buffer device\n",
1405 info->node, info->fix.id); 1404 info->node, info->fix.id);
1406 dev_set_drvdata(device, info); 1405 platform_set_drvdata(dev, info);
1407 1406
1408 return 0; 1407 return 0;
1409 1408
@@ -1417,9 +1416,9 @@ static int __init vga16fb_probe(struct device *device)
1417 return ret; 1416 return ret;
1418} 1417}
1419 1418
1420static int vga16fb_remove(struct device *device) 1419static int vga16fb_remove(struct platform_device *dev)
1421{ 1420{
1422 struct fb_info *info = dev_get_drvdata(device); 1421 struct fb_info *info = platform_get_drvdata(dev);
1423 1422
1424 if (info) { 1423 if (info) {
1425 unregister_framebuffer(info); 1424 unregister_framebuffer(info);
@@ -1432,16 +1431,15 @@ static int vga16fb_remove(struct device *device)
1432 return 0; 1431 return 0;
1433} 1432}
1434 1433
1435static struct device_driver vga16fb_driver = { 1434static struct platform_driver vga16fb_driver = {
1436 .name = "vga16fb",
1437 .bus = &platform_bus_type,
1438 .probe = vga16fb_probe, 1435 .probe = vga16fb_probe,
1439 .remove = vga16fb_remove, 1436 .remove = vga16fb_remove,
1437 .driver = {
1438 .name = "vga16fb",
1439 },
1440}; 1440};
1441 1441
1442static struct platform_device vga16fb_device = { 1442static struct platform_device *vga16fb_device;
1443 .name = "vga16fb",
1444};
1445 1443
1446static int __init vga16fb_init(void) 1444static int __init vga16fb_init(void)
1447{ 1445{
@@ -1454,12 +1452,20 @@ static int __init vga16fb_init(void)
1454 1452
1455 vga16fb_setup(option); 1453 vga16fb_setup(option);
1456#endif 1454#endif
1457 ret = driver_register(&vga16fb_driver); 1455 ret = platform_driver_register(&vga16fb_driver);
1458 1456
1459 if (!ret) { 1457 if (!ret) {
1460 ret = platform_device_register(&vga16fb_device); 1458 vga16fb_device = platform_device_alloc("vga16fb", 0);
1461 if (ret) 1459
1462 driver_unregister(&vga16fb_driver); 1460 if (vga16fb_device)
1461 ret = platform_device_add(vga16fb_device);
1462 else
1463 ret = -ENOMEM;
1464
1465 if (ret) {
1466 platform_device_put(vga16fb_device);
1467 platform_driver_unregister(&vga16fb_driver);
1468 }
1463 } 1469 }
1464 1470
1465 return ret; 1471 return ret;
@@ -1467,8 +1473,8 @@ static int __init vga16fb_init(void)
1467 1473
1468static void __exit vga16fb_exit(void) 1474static void __exit vga16fb_exit(void)
1469{ 1475{
1470 platform_device_unregister(&vga16fb_device); 1476 platform_device_unregister(vga16fb_device);
1471 driver_unregister(&vga16fb_driver); 1477 platform_driver_unregister(&vga16fb_driver);
1472} 1478}
1473 1479
1474MODULE_LICENSE("GPL"); 1480MODULE_LICENSE("GPL");
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index 15179ec62339..d94efafc77b5 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -13,7 +13,6 @@
13 * archive for more details. 13 * archive for more details.
14 * 14 *
15 */ 15 */
16#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
19#include <linux/fb.h> 18#include <linux/fb.h>
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index 5ea2345dab99..64378959dd7b 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -39,7 +39,6 @@
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <linux/string.h> 40#include <linux/string.h>
41#include <linux/mm.h> 41#include <linux/mm.h>
42#include <linux/tty.h>
43#include <linux/slab.h> 42#include <linux/slab.h>
44#include <linux/delay.h> 43#include <linux/delay.h>
45#include <linux/zorro.h> 44#include <linux/zorro.h>