aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig38
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/aty/aty128fb.c3
-rw-r--r--drivers/video/aty/atyfb_base.c4
-rw-r--r--drivers/video/aty/radeon_base.c18
-rw-r--r--drivers/video/aty/radeon_pm.c146
-rw-r--r--drivers/video/aty/radeonfb.h6
-rw-r--r--drivers/video/backlight/Kconfig4
-rw-r--r--drivers/video/console/mdacon.c4
-rw-r--r--drivers/video/fb_notify.c46
-rw-r--r--drivers/video/fbmem.c54
-rw-r--r--drivers/video/nvidia/nvidia.c9
-rw-r--r--drivers/video/offb.c307
-rw-r--r--drivers/video/riva/fbdev.c7
14 files changed, 393 insertions, 254 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6533b0f39231..c40b9b8b1e7e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -86,9 +86,11 @@ config FB_MACMODES
86 default n 86 default n
87 87
88config FB_BACKLIGHT 88config FB_BACKLIGHT
89 bool 89 bool
90 depends on FB 90 depends on FB
91 default n 91 select BACKLIGHT_LCD_SUPPORT
92 select BACKLIGHT_CLASS_DEVICE
93 default n
92 94
93config FB_MODE_HELPERS 95config FB_MODE_HELPERS
94 bool "Enable Video Mode Handling Helpers" 96 bool "Enable Video Mode Handling Helpers"
@@ -420,7 +422,7 @@ config FB_OF
420 422
421config FB_CONTROL 423config FB_CONTROL
422 bool "Apple \"control\" display support" 424 bool "Apple \"control\" display support"
423 depends on (FB = y) && PPC_PMAC 425 depends on (FB = y) && PPC_PMAC && PPC32
424 select FB_CFB_FILLRECT 426 select FB_CFB_FILLRECT
425 select FB_CFB_COPYAREA 427 select FB_CFB_COPYAREA
426 select FB_CFB_IMAGEBLIT 428 select FB_CFB_IMAGEBLIT
@@ -431,7 +433,7 @@ config FB_CONTROL
431 433
432config FB_PLATINUM 434config FB_PLATINUM
433 bool "Apple \"platinum\" display support" 435 bool "Apple \"platinum\" display support"
434 depends on (FB = y) && PPC_PMAC 436 depends on (FB = y) && PPC_PMAC && PPC32
435 select FB_CFB_FILLRECT 437 select FB_CFB_FILLRECT
436 select FB_CFB_COPYAREA 438 select FB_CFB_COPYAREA
437 select FB_CFB_IMAGEBLIT 439 select FB_CFB_IMAGEBLIT
@@ -442,7 +444,7 @@ config FB_PLATINUM
442 444
443config FB_VALKYRIE 445config FB_VALKYRIE
444 bool "Apple \"valkyrie\" display support" 446 bool "Apple \"valkyrie\" display support"
445 depends on (FB = y) && (MAC || PPC_PMAC) 447 depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
446 select FB_CFB_FILLRECT 448 select FB_CFB_FILLRECT
447 select FB_CFB_COPYAREA 449 select FB_CFB_COPYAREA
448 select FB_CFB_IMAGEBLIT 450 select FB_CFB_IMAGEBLIT
@@ -453,7 +455,7 @@ config FB_VALKYRIE
453 455
454config FB_CT65550 456config FB_CT65550
455 bool "Chips 65550 display support" 457 bool "Chips 65550 display support"
456 depends on (FB = y) && PPC 458 depends on (FB = y) && PPC32
457 select FB_CFB_FILLRECT 459 select FB_CFB_FILLRECT
458 select FB_CFB_COPYAREA 460 select FB_CFB_COPYAREA
459 select FB_CFB_IMAGEBLIT 461 select FB_CFB_IMAGEBLIT
@@ -721,10 +723,8 @@ config FB_NVIDIA_I2C
721 723
722config FB_NVIDIA_BACKLIGHT 724config FB_NVIDIA_BACKLIGHT
723 bool "Support for backlight control" 725 bool "Support for backlight control"
724 depends on FB_NVIDIA && PPC_PMAC 726 depends on FB_NVIDIA && PMAC_BACKLIGHT
725 select FB_BACKLIGHT 727 select FB_BACKLIGHT
726 select BACKLIGHT_LCD_SUPPORT
727 select BACKLIGHT_CLASS_DEVICE
728 default y 728 default y
729 help 729 help
730 Say Y here if you want to control the backlight of your display. 730 Say Y here if you want to control the backlight of your display.
@@ -769,10 +769,8 @@ config FB_RIVA_DEBUG
769 769
770config FB_RIVA_BACKLIGHT 770config FB_RIVA_BACKLIGHT
771 bool "Support for backlight control" 771 bool "Support for backlight control"
772 depends on FB_RIVA && PPC_PMAC 772 depends on FB_RIVA && PMAC_BACKLIGHT
773 select FB_BACKLIGHT 773 select FB_BACKLIGHT
774 select BACKLIGHT_LCD_SUPPORT
775 select BACKLIGHT_CLASS_DEVICE
776 default y 774 default y
777 help 775 help
778 Say Y here if you want to control the backlight of your display. 776 Say Y here if you want to control the backlight of your display.
@@ -1025,10 +1023,8 @@ config FB_RADEON_I2C
1025 1023
1026config FB_RADEON_BACKLIGHT 1024config FB_RADEON_BACKLIGHT
1027 bool "Support for backlight control" 1025 bool "Support for backlight control"
1028 depends on FB_RADEON && PPC_PMAC 1026 depends on FB_RADEON && PMAC_BACKLIGHT
1029 select FB_BACKLIGHT 1027 select FB_BACKLIGHT
1030 select BACKLIGHT_LCD_SUPPORT
1031 select BACKLIGHT_CLASS_DEVICE
1032 default y 1028 default y
1033 help 1029 help
1034 Say Y here if you want to control the backlight of your display. 1030 Say Y here if you want to control the backlight of your display.
@@ -1059,10 +1055,8 @@ config FB_ATY128
1059 1055
1060config FB_ATY128_BACKLIGHT 1056config FB_ATY128_BACKLIGHT
1061 bool "Support for backlight control" 1057 bool "Support for backlight control"
1062 depends on FB_ATY128 && PPC_PMAC 1058 depends on FB_ATY128 && PMAC_BACKLIGHT
1063 select FB_BACKLIGHT 1059 select FB_BACKLIGHT
1064 select BACKLIGHT_LCD_SUPPORT
1065 select BACKLIGHT_CLASS_DEVICE
1066 default y 1060 default y
1067 help 1061 help
1068 Say Y here if you want to control the backlight of your display. 1062 Say Y here if you want to control the backlight of your display.
@@ -1111,10 +1105,8 @@ config FB_ATY_GX
1111 1105
1112config FB_ATY_BACKLIGHT 1106config FB_ATY_BACKLIGHT
1113 bool "Support for backlight control" 1107 bool "Support for backlight control"
1114 depends on FB_ATY && PPC_PMAC 1108 depends on FB_ATY && PMAC_BACKLIGHT
1115 select FB_BACKLIGHT 1109 select FB_BACKLIGHT
1116 select BACKLIGHT_LCD_SUPPORT
1117 select BACKLIGHT_CLASS_DEVICE
1118 default y 1110 default y
1119 help 1111 help
1120 Say Y here if you want to control the backlight of your display. 1112 Say Y here if you want to control the backlight of your display.
@@ -1620,7 +1612,7 @@ if FB || SGI_NEWPORT_CONSOLE
1620 source "drivers/video/logo/Kconfig" 1612 source "drivers/video/logo/Kconfig"
1621endif 1613endif
1622 1614
1623if FB && SYSFS 1615if SYSFS
1624 source "drivers/video/backlight/Kconfig" 1616 source "drivers/video/backlight/Kconfig"
1625endif 1617endif
1626 1618
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 95563c9c6b9c..481c6c9695f8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-y += fb_notify.o
7obj-$(CONFIG_FB) += fb.o 8obj-$(CONFIG_FB) += fb.o
8fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ 9fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
9 modedb.o fbcvt.o 10 modedb.o fbcvt.o
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index c64a717e2d4b..8b08121b390b 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -455,7 +455,10 @@ static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
455static void wait_for_fifo(u16 entries, struct aty128fb_par *par); 455static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
456static void wait_for_idle(struct aty128fb_par *par); 456static void wait_for_idle(struct aty128fb_par *par);
457static u32 depth_to_dst(u32 depth); 457static u32 depth_to_dst(u32 depth);
458
459#ifdef CONFIG_FB_ATY128_BACKLIGHT
458static void aty128_bl_set_power(struct fb_info *info, int power); 460static void aty128_bl_set_power(struct fb_info *info, int power);
461#endif
459 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)) | \
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 1507d19f481f..053ff63365b7 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2812,7 +2812,7 @@ static int atyfb_blank(int blank, struct fb_info *info)
2812 if (par->lock_blank || par->asleep) 2812 if (par->lock_blank || par->asleep)
2813 return 0; 2813 return 0;
2814 2814
2815#ifdef CONFIG_PMAC_BACKLIGHT 2815#ifdef CONFIG_FB_ATY_BACKLIGHT
2816 if (machine_is(powermac) && blank > FB_BLANK_NORMAL) 2816 if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
2817 aty_bl_set_power(info, FB_BLANK_POWERDOWN); 2817 aty_bl_set_power(info, FB_BLANK_POWERDOWN);
2818#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2818#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
@@ -2844,7 +2844,7 @@ static int atyfb_blank(int blank, struct fb_info *info)
2844 } 2844 }
2845 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2845 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2846 2846
2847#ifdef CONFIG_PMAC_BACKLIGHT 2847#ifdef CONFIG_FB_ATY_BACKLIGHT
2848 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) 2848 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
2849 aty_bl_set_power(info, FB_BLANK_UNBLANK); 2849 aty_bl_set_power(info, FB_BLANK_UNBLANK);
2850#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2850#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 8d85fc58142e..8e3400d5dd21 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -266,6 +266,8 @@ static int force_measure_pll = 0;
266#ifdef CONFIG_MTRR 266#ifdef CONFIG_MTRR
267static int nomtrr = 0; 267static int nomtrr = 0;
268#endif 268#endif
269static int force_sleep;
270static int ignore_devlist;
269 271
270/* 272/*
271 * prototypes 273 * prototypes
@@ -2327,9 +2329,9 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
2327 /* -2 is special: means ON on mobility chips and do not 2329 /* -2 is special: means ON on mobility chips and do not
2328 * change on others 2330 * change on others
2329 */ 2331 */
2330 radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1); 2332 radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep);
2331 } else 2333 } else
2332 radeonfb_pm_init(rinfo, default_dynclk); 2334 radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep);
2333 2335
2334 pci_set_drvdata(pdev, info); 2336 pci_set_drvdata(pdev, info);
2335 2337
@@ -2477,6 +2479,12 @@ static int __init radeonfb_setup (char *options)
2477 force_measure_pll = 1; 2479 force_measure_pll = 1;
2478 } else if (!strncmp(this_opt, "ignore_edid", 11)) { 2480 } else if (!strncmp(this_opt, "ignore_edid", 11)) {
2479 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
2480 } else 2488 } else
2481 mode_option = this_opt; 2489 mode_option = this_opt;
2482 } 2490 }
@@ -2532,3 +2540,9 @@ module_param(panel_yres, int, 0);
2532MODULE_PARM_DESC(panel_yres, "int: set panel yres"); 2540MODULE_PARM_DESC(panel_yres, "int: set panel yres");
2533module_param(mode_option, charp, 0); 2541module_param(mode_option, charp, 0);
2534MODULE_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_pm.c b/drivers/video/aty/radeon_pm.c
index c7091761cef4..f31e606a2ded 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));
@@ -2713,7 +2814,7 @@ static void radeonfb_early_resume(void *data)
2713 2814
2714#endif /* CONFIG_PM */ 2815#endif /* CONFIG_PM */
2715 2816
2716void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) 2817void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep)
2717{ 2818{
2718 /* Find PM registers in config space if any*/ 2819 /* Find PM registers in config space if any*/
2719 rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); 2820 rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
@@ -2729,22 +2830,13 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
2729 } 2830 }
2730 2831
2731#if defined(CONFIG_PM) 2832#if defined(CONFIG_PM)
2833#if defined(CONFIG_PPC_PMAC)
2732 /* Check if we can power manage on suspend/resume. We can do 2834 /* 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 2835 * 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 2836 * "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 2837 * BIOS does tho. Right now, all this PM stuff is pmac-only for that
2736 * reason. --BenH 2838 * reason. --BenH
2737 */ 2839 */
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) { 2840 if (machine_is(powermac) && rinfo->of_node) {
2749 if (rinfo->is_mobility && rinfo->pm_reg && 2841 if (rinfo->is_mobility && rinfo->pm_reg &&
2750 rinfo->family <= CHIP_FAMILY_RV250) 2842 rinfo->family <= CHIP_FAMILY_RV250)
@@ -2790,6 +2882,18 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
2790 } 2882 }
2791#endif /* defined(CONFIG_PPC_PMAC) */ 2883#endif /* defined(CONFIG_PPC_PMAC) */
2792#endif /* defined(CONFIG_PM) */ 2884#endif /* defined(CONFIG_PM) */
2885
2886 if (ignore_devlist)
2887 printk(KERN_DEBUG
2888 "radeonfb: skipping test for device workarounds\n");
2889 else
2890 radeon_apply_workarounds(rinfo);
2891
2892 if (force_sleep) {
2893 printk(KERN_DEBUG
2894 "radeonfb: forcefully enabling D2 sleep mode\n");
2895 rinfo->pm_mode |= radeon_pm_d2;
2896 }
2793} 2897}
2794 2898
2795void radeonfb_pm_exit(struct radeonfb_info *rinfo) 2899void radeonfb_pm_exit(struct radeonfb_info *rinfo)
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 38657b2d10eb..d5ff224a6258 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -273,6 +273,8 @@ enum radeon_pm_mode {
273 radeon_pm_off = 0x00000002, /* Can resume from D3 cold */ 273 radeon_pm_off = 0x00000002, /* Can resume from D3 cold */
274}; 274};
275 275
276typedef void (*reinit_function_ptr)(struct radeonfb_info *rinfo);
277
276struct radeonfb_info { 278struct radeonfb_info {
277 struct fb_info *info; 279 struct fb_info *info;
278 280
@@ -338,7 +340,7 @@ struct radeonfb_info {
338 int dynclk; 340 int dynclk;
339 int no_schedule; 341 int no_schedule;
340 enum radeon_pm_mode pm_mode; 342 enum radeon_pm_mode pm_mode;
341 void (*reinit_func)(struct radeonfb_info *rinfo); 343 reinit_function_ptr reinit_func;
342 344
343 /* Lock on register access */ 345 /* Lock on register access */
344 spinlock_t reg_lock; 346 spinlock_t reg_lock;
@@ -600,7 +602,7 @@ extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8
600/* PM Functions */ 602/* PM Functions */
601extern 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);
602extern int radeonfb_pci_resume(struct pci_dev *pdev); 604extern int radeonfb_pci_resume(struct pci_dev *pdev);
603extern 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);
604extern void radeonfb_pm_exit(struct radeonfb_info *rinfo); 606extern void radeonfb_pm_exit(struct radeonfb_info *rinfo);
605 607
606/* Monitor probe functions */ 608/* Monitor probe functions */
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 022f9d3473f5..02f15297a021 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT
10 10
11config BACKLIGHT_CLASS_DEVICE 11config BACKLIGHT_CLASS_DEVICE
12 tristate "Lowlevel Backlight controls" 12 tristate "Lowlevel Backlight controls"
13 depends on BACKLIGHT_LCD_SUPPORT && FB 13 depends on BACKLIGHT_LCD_SUPPORT
14 default m 14 default m
15 help 15 help
16 This framework adds support for low-level control of the LCD 16 This framework adds support for low-level control of the LCD
@@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE
26 26
27config LCD_CLASS_DEVICE 27config LCD_CLASS_DEVICE
28 tristate "Lowlevel LCD controls" 28 tristate "Lowlevel LCD controls"
29 depends on BACKLIGHT_LCD_SUPPORT && FB 29 depends on BACKLIGHT_LCD_SUPPORT
30 default m 30 default m
31 help 31 help
32 This framework adds support for low-level control of LCD. 32 This framework adds support for low-level control of LCD.
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 52ed12b12acc..eb4d03fa5391 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -197,7 +197,7 @@ static int __init mdacon_setup(char *str)
197__setup("mdacon=", mdacon_setup); 197__setup("mdacon=", mdacon_setup);
198#endif 198#endif
199 199
200static int __init mda_detect(void) 200static int mda_detect(void)
201{ 201{
202 int count=0; 202 int count=0;
203 u16 *p, p_save; 203 u16 *p, p_save;
@@ -282,7 +282,7 @@ static int __init mda_detect(void)
282 return 1; 282 return 1;
283} 283}
284 284
285static void __init mda_initialize(void) 285static void mda_initialize(void)
286{ 286{
287 write_mda_b(97, 0x00); /* horizontal total */ 287 write_mda_b(97, 0x00); /* horizontal total */
288 write_mda_b(80, 0x01); /* horizontal displayed */ 288 write_mda_b(80, 0x01); /* horizontal displayed */
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/fbmem.c b/drivers/video/fbmem.c
index 4fc9df426c1a..17961e3ecaa0 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -52,7 +52,6 @@
52 52
53#define FBPIXMAPSIZE (1024 * 8) 53#define FBPIXMAPSIZE (1024 * 8)
54 54
55static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
56struct fb_info *registered_fb[FB_MAX]; 55struct fb_info *registered_fb[FB_MAX];
57int num_registered_fb; 56int num_registered_fb;
58 57
@@ -791,8 +790,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
791 790
792 event.info = info; 791 event.info = info;
793 event.data = &mode1; 792 event.data = &mode1;
794 ret = blocking_notifier_call_chain(&fb_notifier_list, 793 ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event);
795 FB_EVENT_MODE_DELETE, &event);
796 } 794 }
797 795
798 if (!ret) 796 if (!ret)
@@ -837,8 +835,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
837 835
838 info->flags &= ~FBINFO_MISC_USEREVENT; 836 info->flags &= ~FBINFO_MISC_USEREVENT;
839 event.info = info; 837 event.info = info;
840 blocking_notifier_call_chain(&fb_notifier_list, 838 fb_notifier_call_chain(evnt, &event);
841 evnt, &event);
842 } 839 }
843 } 840 }
844 } 841 }
@@ -861,8 +858,7 @@ fb_blank(struct fb_info *info, int blank)
861 858
862 event.info = info; 859 event.info = info;
863 event.data = &blank; 860 event.data = &blank;
864 blocking_notifier_call_chain(&fb_notifier_list, 861 fb_notifier_call_chain(FB_EVENT_BLANK, &event);
865 FB_EVENT_BLANK, &event);
866 } 862 }
867 863
868 return ret; 864 return ret;
@@ -933,8 +929,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
933 con2fb.framebuffer = -1; 929 con2fb.framebuffer = -1;
934 event.info = info; 930 event.info = info;
935 event.data = &con2fb; 931 event.data = &con2fb;
936 blocking_notifier_call_chain(&fb_notifier_list, 932 fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
937 FB_EVENT_GET_CONSOLE_MAP, &event);
938 return copy_to_user(argp, &con2fb, 933 return copy_to_user(argp, &con2fb,
939 sizeof(con2fb)) ? -EFAULT : 0; 934 sizeof(con2fb)) ? -EFAULT : 0;
940 case FBIOPUT_CON2FBMAP: 935 case FBIOPUT_CON2FBMAP:
@@ -952,9 +947,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
952 return -EINVAL; 947 return -EINVAL;
953 event.info = info; 948 event.info = info;
954 event.data = &con2fb; 949 event.data = &con2fb;
955 return blocking_notifier_call_chain(&fb_notifier_list, 950 return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
956 FB_EVENT_SET_CONSOLE_MAP, 951 &event);
957 &event);
958 case FBIOBLANK: 952 case FBIOBLANK:
959 acquire_console_sem(); 953 acquire_console_sem();
960 info->flags |= FBINFO_MISC_USEREVENT; 954 info->flags |= FBINFO_MISC_USEREVENT;
@@ -1330,8 +1324,7 @@ register_framebuffer(struct fb_info *fb_info)
1330 registered_fb[i] = fb_info; 1324 registered_fb[i] = fb_info;
1331 1325
1332 event.info = fb_info; 1326 event.info = fb_info;
1333 blocking_notifier_call_chain(&fb_notifier_list, 1327 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
1334 FB_EVENT_FB_REGISTERED, &event);
1335 return 0; 1328 return 0;
1336} 1329}
1337 1330
@@ -1365,30 +1358,11 @@ unregister_framebuffer(struct fb_info *fb_info)
1365 fb_cleanup_class_device(fb_info); 1358 fb_cleanup_class_device(fb_info);
1366 class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); 1359 class_device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1367 event.info = fb_info; 1360 event.info = fb_info;
1368 blocking_notifier_call_chain(&fb_notifier_list, 1361 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1369 FB_EVENT_FB_UNREGISTERED, &event);
1370 return 0; 1362 return 0;
1371} 1363}
1372 1364
1373/** 1365/**
1374 * fb_register_client - register a client notifier
1375 * @nb: notifier block to callback on events
1376 */
1377int fb_register_client(struct notifier_block *nb)
1378{
1379 return blocking_notifier_chain_register(&fb_notifier_list, nb);
1380}
1381
1382/**
1383 * fb_unregister_client - unregister a client notifier
1384 * @nb: notifier block to callback on events
1385 */
1386int fb_unregister_client(struct notifier_block *nb)
1387{
1388 return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
1389}
1390
1391/**
1392 * fb_set_suspend - low level driver signals suspend 1366 * fb_set_suspend - low level driver signals suspend
1393 * @info: framebuffer affected 1367 * @info: framebuffer affected
1394 * @state: 0 = resuming, !=0 = suspending 1368 * @state: 0 = resuming, !=0 = suspending
@@ -1403,13 +1377,11 @@ void fb_set_suspend(struct fb_info *info, int state)
1403 1377
1404 event.info = info; 1378 event.info = info;
1405 if (state) { 1379 if (state) {
1406 blocking_notifier_call_chain(&fb_notifier_list, 1380 fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);
1407 FB_EVENT_SUSPEND, &event);
1408 info->state = FBINFO_STATE_SUSPENDED; 1381 info->state = FBINFO_STATE_SUSPENDED;
1409 } else { 1382 } else {
1410 info->state = FBINFO_STATE_RUNNING; 1383 info->state = FBINFO_STATE_RUNNING;
1411 blocking_notifier_call_chain(&fb_notifier_list, 1384 fb_notifier_call_chain(FB_EVENT_RESUME, &event);
1412 FB_EVENT_RESUME, &event);
1413 } 1385 }
1414} 1386}
1415 1387
@@ -1480,9 +1452,7 @@ int fb_new_modelist(struct fb_info *info)
1480 1452
1481 if (!list_empty(&info->modelist)) { 1453 if (!list_empty(&info->modelist)) {
1482 event.info = info; 1454 event.info = info;
1483 err = blocking_notifier_call_chain(&fb_notifier_list, 1455 err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
1484 FB_EVENT_NEW_MODELIST,
1485 &event);
1486 } 1456 }
1487 1457
1488 return err; 1458 return err;
@@ -1594,8 +1564,6 @@ EXPORT_SYMBOL(fb_blank);
1594EXPORT_SYMBOL(fb_pan_display); 1564EXPORT_SYMBOL(fb_pan_display);
1595EXPORT_SYMBOL(fb_get_buffer_offset); 1565EXPORT_SYMBOL(fb_get_buffer_offset);
1596EXPORT_SYMBOL(fb_set_suspend); 1566EXPORT_SYMBOL(fb_set_suspend);
1597EXPORT_SYMBOL(fb_register_client);
1598EXPORT_SYMBOL(fb_unregister_client);
1599EXPORT_SYMBOL(fb_get_options); 1567EXPORT_SYMBOL(fb_get_options);
1600 1568
1601MODULE_LICENSE("GPL"); 1569MODULE_LICENSE("GPL");
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 9f2066f0745a..d4f850117874 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -34,10 +34,6 @@
34#include "nv_proto.h" 34#include "nv_proto.h"
35#include "nv_dma.h" 35#include "nv_dma.h"
36 36
37#ifndef CONFIG_PCI /* sanity check */
38#error This driver requires PCI support.
39#endif
40
41#undef CONFIG_FB_NVIDIA_DEBUG 37#undef CONFIG_FB_NVIDIA_DEBUG
42#ifdef CONFIG_FB_NVIDIA_DEBUG 38#ifdef CONFIG_FB_NVIDIA_DEBUG
43#define NVTRACE printk 39#define NVTRACE printk
@@ -1303,20 +1299,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1303 1299
1304 nvidia_save_vga(par, &par->SavedReg); 1300 nvidia_save_vga(par, &par->SavedReg);
1305 1301
1302 pci_set_drvdata(pd, info);
1303 nvidia_bl_init(par);
1306 if (register_framebuffer(info) < 0) { 1304 if (register_framebuffer(info) < 0) {
1307 printk(KERN_ERR PFX "error registering nVidia framebuffer\n"); 1305 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1308 goto err_out_iounmap_fb; 1306 goto err_out_iounmap_fb;
1309 } 1307 }
1310 1308
1311 pci_set_drvdata(pd, info);
1312 1309
1313 printk(KERN_INFO PFX 1310 printk(KERN_INFO PFX
1314 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n", 1311 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1315 info->fix.id, 1312 info->fix.id,
1316 par->FbMapSize / (1024 * 1024), info->fix.smem_start); 1313 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1317 1314
1318 nvidia_bl_init(par);
1319
1320 NVTRACE_LEAVE(); 1315 NVTRACE_LEAVE();
1321 return 0; 1316 return 0;
1322 1317
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index ce5f3031b99b..0013311e0564 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -62,8 +62,6 @@ struct offb_par default_par;
62 * Interface used by the world 62 * Interface used by the world
63 */ 63 */
64 64
65int offb_init(void);
66
67static 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,
68 u_int transp, struct fb_info *info); 66 u_int transp, struct fb_info *info);
69static int offb_blank(int blank, struct fb_info *info); 67static int offb_blank(int blank, struct fb_info *info);
@@ -72,11 +70,6 @@ static int offb_blank(int blank, struct fb_info *info);
72extern boot_infos_t *boot_infos; 70extern boot_infos_t *boot_infos;
73#endif 71#endif
74 72
75static void offb_init_nodriver(struct device_node *);
76static void offb_init_fb(const char *name, const char *full_name,
77 int width, int height, int depth, int pitch,
78 unsigned long address, struct device_node *dp);
79
80static struct fb_ops offb_ops = { 73static struct fb_ops offb_ops = {
81 .owner = THIS_MODULE, 74 .owner = THIS_MODULE,
82 .fb_setcolreg = offb_setcolreg, 75 .fb_setcolreg = offb_setcolreg,
@@ -229,123 +222,17 @@ static int offb_blank(int blank, struct fb_info *info)
229 return 0; 222 return 0;
230} 223}
231 224
232 /*
233 * Initialisation
234 */
235 225
236int __init offb_init(void) 226static void __iomem *offb_map_reg(struct device_node *np, int index,
227 unsigned long offset, unsigned long size)
237{ 228{
238 struct device_node *dp = NULL, *boot_disp = NULL; 229 struct resource r;
239
240 if (fb_get_options("offb", NULL))
241 return -ENODEV;
242 230
243 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { 231 if (of_address_to_resource(np, index, &r))
244 if (get_property(dp, "linux,opened", NULL) && 232 return 0;
245 get_property(dp, "linux,boot-display", NULL)) { 233 if ((r.start + offset + size) > r.end)
246 boot_disp = dp; 234 return 0;
247 offb_init_nodriver(dp); 235 return ioremap(r.start + offset, size);
248 }
249 }
250 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
251 if (get_property(dp, "linux,opened", NULL) &&
252 dp != boot_disp)
253 offb_init_nodriver(dp);
254 }
255
256 return 0;
257}
258
259
260static void __init offb_init_nodriver(struct device_node *dp)
261{
262 unsigned int len;
263 int i, width = 640, height = 480, depth = 8, pitch = 640;
264 unsigned int flags, rsize, addr_prop = 0;
265 unsigned long max_size = 0;
266 u64 rstart, address = OF_BAD_ADDR;
267 u32 *pp, *addrp, *up;
268 u64 asize;
269
270 pp = (u32 *)get_property(dp, "linux,bootx-depth", &len);
271 if (pp == NULL)
272 pp = (u32 *)get_property(dp, "depth", &len);
273 if (pp && len == sizeof(u32))
274 depth = *pp;
275
276 pp = (u32 *)get_property(dp, "linux,bootx-width", &len);
277 if (pp == NULL)
278 pp = (u32 *)get_property(dp, "width", &len);
279 if (pp && len == sizeof(u32))
280 width = *pp;
281
282 pp = (u32 *)get_property(dp, "linux,bootx-height", &len);
283 if (pp == NULL)
284 pp = (u32 *)get_property(dp, "height", &len);
285 if (pp && len == sizeof(u32))
286 height = *pp;
287
288 pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len);
289 if (pp == NULL)
290 pp = (u32 *)get_property(dp, "linebytes", &len);
291 if (pp && len == sizeof(u32))
292 pitch = *pp;
293 else
294 pitch = width * ((depth + 7) / 8);
295
296 rsize = (unsigned long)pitch * (unsigned long)height;
297
298 /* Ok, now we try to figure out the address of the framebuffer.
299 *
300 * Unfortunately, Open Firmware doesn't provide a standard way to do
301 * so. All we can do is a dodgy heuristic that happens to work in
302 * practice. On most machines, the "address" property contains what
303 * we need, though not on Matrox cards found in IBM machines. What I've
304 * found that appears to give good results is to go through the PCI
305 * ranges and pick one that is both big enough and if possible encloses
306 * the "address" property. If none match, we pick the biggest
307 */
308 up = (u32 *)get_property(dp, "linux,bootx-addr", &len);
309 if (up == NULL)
310 up = (u32 *)get_property(dp, "address", &len);
311 if (up && len == sizeof(u32))
312 addr_prop = *up;
313
314 for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
315 != NULL; i++) {
316 int match_addrp = 0;
317
318 if (!(flags & IORESOURCE_MEM))
319 continue;
320 if (asize < rsize)
321 continue;
322 rstart = of_translate_address(dp, addrp);
323 if (rstart == OF_BAD_ADDR)
324 continue;
325 if (addr_prop && (rstart <= addr_prop) &&
326 ((rstart + asize) >= (addr_prop + rsize)))
327 match_addrp = 1;
328 if (match_addrp) {
329 address = addr_prop;
330 break;
331 }
332 if (rsize > max_size) {
333 max_size = rsize;
334 address = OF_BAD_ADDR;
335 }
336
337 if (address == OF_BAD_ADDR)
338 address = rstart;
339 }
340 if (address == OF_BAD_ADDR && addr_prop)
341 address = (u64)addr_prop;
342 if (address != OF_BAD_ADDR) {
343 /* kludge for valkyrie */
344 if (strcmp(dp->name, "valkyrie") == 0)
345 address += 0x1000;
346 offb_init_fb(dp->name, dp->full_name, width, height, depth,
347 pitch, address, dp);
348 }
349} 236}
350 237
351static 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,
@@ -402,45 +289,39 @@ static void __init offb_init_fb(const char *name, const char *full_name,
402 289
403 par->cmap_type = cmap_unknown; 290 par->cmap_type = cmap_unknown;
404 if (depth == 8) { 291 if (depth == 8) {
405
406 /* Palette hacks disabled for now */ 292 /* Palette hacks disabled for now */
407#if 0
408 if (dp && !strncmp(name, "ATY,Rage128", 11)) { 293 if (dp && !strncmp(name, "ATY,Rage128", 11)) {
409 unsigned long regbase = dp->addrs[2].address; 294 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
410 par->cmap_adr = ioremap(regbase, 0x1FFF); 295 if (par->cmap_adr)
411 par->cmap_type = cmap_r128; 296 par->cmap_type = cmap_r128;
412 } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12) 297 } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
413 || !strncmp(name, "ATY,RageM3p12A", 14))) { 298 || !strncmp(name, "ATY,RageM3p12A", 14))) {
414 unsigned long regbase = 299 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
415 dp->parent->addrs[2].address; 300 if (par->cmap_adr)
416 par->cmap_adr = ioremap(regbase, 0x1FFF); 301 par->cmap_type = cmap_M3A;
417 par->cmap_type = cmap_M3A;
418 } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) { 302 } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
419 unsigned long regbase = 303 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
420 dp->parent->addrs[2].address; 304 if (par->cmap_adr)
421 par->cmap_adr = ioremap(regbase, 0x1FFF); 305 par->cmap_type = cmap_M3B;
422 par->cmap_type = cmap_M3B;
423 } else if (dp && !strncmp(name, "ATY,Rage6", 9)) { 306 } else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
424 unsigned long regbase = dp->addrs[1].address; 307 par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
425 par->cmap_adr = ioremap(regbase, 0x1FFF); 308 if (par->cmap_adr)
426 par->cmap_type = cmap_radeon; 309 par->cmap_type = cmap_radeon;
427 } else if (!strncmp(name, "ATY,", 4)) { 310 } else if (!strncmp(name, "ATY,", 4)) {
428 unsigned long base = address & 0xff000000UL; 311 unsigned long base = address & 0xff000000UL;
429 par->cmap_adr = 312 par->cmap_adr =
430 ioremap(base + 0x7ff000, 0x1000) + 0xcc0; 313 ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
431 par->cmap_data = par->cmap_adr + 1; 314 par->cmap_data = par->cmap_adr + 1;
432 par->cmap_type = cmap_m64; 315 par->cmap_type = cmap_m64;
433 } else if (device_is_compatible(dp, "pci1014,b7")) { 316 } else if (dp && device_is_compatible(dp, "pci1014,b7")) {
434 unsigned long regbase = dp->addrs[0].address; 317 par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
435 par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); 318 if (par->cmap_adr)
436 par->cmap_type = cmap_gxt2000; 319 par->cmap_type = cmap_gxt2000;
437 } 320 }
438#endif 321 fix->visual = (par->cmap_type != cmap_unknown) ?
439 fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR 322 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
440 : FB_VISUAL_STATIC_PSEUDOCOLOR;
441 } else 323 } else
442 fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR 324 fix->visual = FB_VISUAL_TRUECOLOR;
443 : */ FB_VISUAL_TRUECOLOR;
444 325
445 var->xoffset = var->yoffset = 0; 326 var->xoffset = var->yoffset = 0;
446 switch (depth) { 327 switch (depth) {
@@ -520,5 +401,139 @@ static void __init offb_init_fb(const char *name, const char *full_name,
520 info->node, full_name); 401 info->node, full_name);
521} 402}
522 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 u32 *pp, *addrp, *up;
413 u64 asize;
414
415 pp = (u32 *)get_property(dp, "linux,bootx-depth", &len);
416 if (pp == NULL)
417 pp = (u32 *)get_property(dp, "depth", &len);
418 if (pp && len == sizeof(u32))
419 depth = *pp;
420
421 pp = (u32 *)get_property(dp, "linux,bootx-width", &len);
422 if (pp == NULL)
423 pp = (u32 *)get_property(dp, "width", &len);
424 if (pp && len == sizeof(u32))
425 width = *pp;
426
427 pp = (u32 *)get_property(dp, "linux,bootx-height", &len);
428 if (pp == NULL)
429 pp = (u32 *)get_property(dp, "height", &len);
430 if (pp && len == sizeof(u32))
431 height = *pp;
432
433 pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len);
434 if (pp == NULL)
435 pp = (u32 *)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 = (u32 *)get_property(dp, "linux,bootx-addr", &len);
454 if (up == NULL)
455 up = (u32 *)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
523module_init(offb_init); 538module_init(offb_init);
524MODULE_LICENSE("GPL"); 539MODULE_LICENSE("GPL");
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 33dddbae5420..76fc9d355eb7 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -2132,6 +2132,9 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
2132 2132
2133 fb_destroy_modedb(info->monspecs.modedb); 2133 fb_destroy_modedb(info->monspecs.modedb);
2134 info->monspecs.modedb = NULL; 2134 info->monspecs.modedb = NULL;
2135
2136 pci_set_drvdata(pd, info);
2137 riva_bl_init(info->par);
2135 ret = register_framebuffer(info); 2138 ret = register_framebuffer(info);
2136 if (ret < 0) { 2139 if (ret < 0) {
2137 printk(KERN_ERR PFX 2140 printk(KERN_ERR PFX
@@ -2139,8 +2142,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
2139 goto err_iounmap_screen_base; 2142 goto err_iounmap_screen_base;
2140 } 2143 }
2141 2144
2142 pci_set_drvdata(pd, info);
2143
2144 printk(KERN_INFO PFX 2145 printk(KERN_INFO PFX
2145 "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n", 2146 "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
2146 info->fix.id, 2147 info->fix.id,
@@ -2148,8 +2149,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
2148 info->fix.smem_len / (1024 * 1024), 2149 info->fix.smem_len / (1024 * 1024),
2149 info->fix.smem_start); 2150 info->fix.smem_start);
2150 2151
2151 riva_bl_init(info->par);
2152
2153 NVTRACE_LEAVE(); 2152 NVTRACE_LEAVE();
2154 return 0; 2153 return 0;
2155 2154