diff options
author | Adrian Bunk <bunk@stusta.de> | 2007-02-12 03:54:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 12:48:41 -0500 |
commit | e019630e78e3482c2386d18cbdc7a4c54f7a809c (patch) | |
tree | 4b4bac38f1b501bac9a54ce8f08a1a6f1b26123f /drivers | |
parent | a268422de8bf1b4c0cb97987b6c329c9f6a3da4b (diff) |
[PATCH] remove broken video drivers
Remove some video drivers that:
- had already been marked as BROKEN in 2.6.0 three years ago and
- are still marked as BROKEN.
These are the following drivers:
- FB_CYBER
- FB_VIRGE
- FB_RETINAZ3
- FB_SUN3
Drivers that had been marked as BROKEN for such a long time seem to be
unlikely to be revived in the forseeable future.
But if anyone wants to ever revive any of these drivers, the code is
still present in the older kernel releases.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Acked-By: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: James Simmons <jsimmons@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/Kconfig | 46 | ||||
-rw-r--r-- | drivers/video/Makefile | 4 | ||||
-rw-r--r-- | drivers/video/cyberfb.c | 2295 | ||||
-rw-r--r-- | drivers/video/cyberfb.h | 415 | ||||
-rw-r--r-- | drivers/video/retz3fb.c | 1588 | ||||
-rw-r--r-- | drivers/video/retz3fb.h | 286 | ||||
-rw-r--r-- | drivers/video/sun3fb.c | 702 | ||||
-rw-r--r-- | drivers/video/virgefb.c | 2526 | ||||
-rw-r--r-- | drivers/video/virgefb.h | 288 |
9 files changed, 3 insertions, 8147 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3ab06317264..3546484fa50 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -354,42 +354,6 @@ config FB_AMIGA_AGA | |||
354 | and CD32. If you intend to run Linux on any of these systems, say Y; | 354 | and CD32. If you intend to run Linux on any of these systems, say Y; |
355 | otherwise say N. | 355 | otherwise say N. |
356 | 356 | ||
357 | config FB_CYBER | ||
358 | tristate "Amiga CyberVision 64 support" | ||
359 | depends on FB && ZORRO && BROKEN | ||
360 | select FB_CFB_FILLRECT | ||
361 | select FB_CFB_COPYAREA | ||
362 | select FB_CFB_IMAGEBLIT | ||
363 | help | ||
364 | This enables support for the Cybervision 64 graphics card from | ||
365 | Phase5. Please note that its use is not all that intuitive (i.e. if | ||
366 | you have any questions, be sure to ask!). Say N unless you have a | ||
367 | Cybervision 64 or plan to get one before you next recompile the | ||
368 | kernel. Please note that this driver DOES NOT support the | ||
369 | Cybervision 64/3D card, as they use incompatible video chips. | ||
370 | |||
371 | config FB_VIRGE | ||
372 | bool "Amiga CyberVision 64/3D support " | ||
373 | depends on (FB = y) && ZORRO && BROKEN | ||
374 | select FB_CFB_FILLRECT | ||
375 | select FB_CFB_COPYAREA | ||
376 | select FB_CFB_IMAGEBLIT | ||
377 | help | ||
378 | This enables support for the Cybervision 64/3D graphics card from | ||
379 | Phase5. Please note that its use is not all that intuitive (i.e. if | ||
380 | you have any questions, be sure to ask!). Say N unless you have a | ||
381 | Cybervision 64/3D or plan to get one before you next recompile the | ||
382 | kernel. Please note that this driver DOES NOT support the older | ||
383 | Cybervision 64 card, as they use incompatible video chips. | ||
384 | |||
385 | config FB_RETINAZ3 | ||
386 | tristate "Amiga Retina Z3 support" | ||
387 | depends on (FB = y) && ZORRO && BROKEN | ||
388 | help | ||
389 | This enables support for the Retina Z3 graphics card. Say N unless | ||
390 | you have a Retina Z3 or plan to get one before you next recompile | ||
391 | the kernel. | ||
392 | |||
393 | config FB_FM2 | 357 | config FB_FM2 |
394 | bool "Amiga FrameMaster II/Rainbow II support" | 358 | bool "Amiga FrameMaster II/Rainbow II support" |
395 | depends on (FB = y) && ZORRO | 359 | depends on (FB = y) && ZORRO |
@@ -625,10 +589,6 @@ config FB_GBE_MEM | |||
625 | This is the amount of memory reserved for the framebuffer, | 589 | This is the amount of memory reserved for the framebuffer, |
626 | which can be any value between 1MB and 8MB. | 590 | which can be any value between 1MB and 8MB. |
627 | 591 | ||
628 | config FB_SUN3 | ||
629 | bool "Sun3 framebuffer support" | ||
630 | depends on (FB = y) && (SUN3 || SUN3X) && BROKEN | ||
631 | |||
632 | config FB_SBUS | 592 | config FB_SBUS |
633 | bool "SBUS and UPA framebuffers" | 593 | bool "SBUS and UPA framebuffers" |
634 | depends on (FB = y) && SPARC | 594 | depends on (FB = y) && SPARC |
@@ -637,7 +597,7 @@ config FB_SBUS | |||
637 | 597 | ||
638 | config FB_BW2 | 598 | config FB_BW2 |
639 | bool "BWtwo support" | 599 | bool "BWtwo support" |
640 | depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) | 600 | depends on (FB = y) && (SPARC && FB_SBUS) |
641 | select FB_CFB_FILLRECT | 601 | select FB_CFB_FILLRECT |
642 | select FB_CFB_COPYAREA | 602 | select FB_CFB_COPYAREA |
643 | select FB_CFB_IMAGEBLIT | 603 | select FB_CFB_IMAGEBLIT |
@@ -646,7 +606,7 @@ config FB_BW2 | |||
646 | 606 | ||
647 | config FB_CG3 | 607 | config FB_CG3 |
648 | bool "CGthree support" | 608 | bool "CGthree support" |
649 | depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) | 609 | depends on (FB = y) && (SPARC && FB_SBUS) |
650 | select FB_CFB_FILLRECT | 610 | select FB_CFB_FILLRECT |
651 | select FB_CFB_COPYAREA | 611 | select FB_CFB_COPYAREA |
652 | select FB_CFB_IMAGEBLIT | 612 | select FB_CFB_IMAGEBLIT |
@@ -655,7 +615,7 @@ config FB_CG3 | |||
655 | 615 | ||
656 | config FB_CG6 | 616 | config FB_CG6 |
657 | bool "CGsix (GX,TurboGX) support" | 617 | bool "CGsix (GX,TurboGX) support" |
658 | depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) | 618 | depends on (FB = y) && (SPARC && FB_SBUS) |
659 | select FB_CFB_COPYAREA | 619 | select FB_CFB_COPYAREA |
660 | select FB_CFB_IMAGEBLIT | 620 | select FB_CFB_IMAGEBLIT |
661 | help | 621 | help |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index d4e2b152160..363b630abfb 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -22,11 +22,9 @@ obj-$(CONFIG_FB_MACMODES) += macmodes.o | |||
22 | obj-$(CONFIG_FB_DDC) += fb_ddc.o | 22 | obj-$(CONFIG_FB_DDC) += fb_ddc.o |
23 | 23 | ||
24 | # Hardware specific drivers go first | 24 | # Hardware specific drivers go first |
25 | obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o | ||
26 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o | 25 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o |
27 | obj-$(CONFIG_FB_ARC) += arcfb.o | 26 | obj-$(CONFIG_FB_ARC) += arcfb.o |
28 | obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o | 27 | obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o |
29 | obj-$(CONFIG_FB_CYBER) += cyberfb.o | ||
30 | obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o | 28 | obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o |
31 | obj-$(CONFIG_FB_PM2) += pm2fb.o | 29 | obj-$(CONFIG_FB_PM2) += pm2fb.o |
32 | obj-$(CONFIG_FB_PM3) += pm3fb.o | 30 | obj-$(CONFIG_FB_PM3) += pm3fb.o |
@@ -44,7 +42,6 @@ obj-$(CONFIG_FB_GEODE) += geode/ | |||
44 | obj-$(CONFIG_FB_MBX) += mbx/ | 42 | obj-$(CONFIG_FB_MBX) += mbx/ |
45 | obj-$(CONFIG_FB_I810) += vgastate.o | 43 | obj-$(CONFIG_FB_I810) += vgastate.o |
46 | obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o | 44 | obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o |
47 | obj-$(CONFIG_FB_VIRGE) += virgefb.o | ||
48 | obj-$(CONFIG_FB_3DFX) += tdfxfb.o | 45 | obj-$(CONFIG_FB_3DFX) += tdfxfb.o |
49 | obj-$(CONFIG_FB_CONTROL) += controlfb.o | 46 | obj-$(CONFIG_FB_CONTROL) += controlfb.o |
50 | obj-$(CONFIG_FB_PLATINUM) += platinumfb.o | 47 | obj-$(CONFIG_FB_PLATINUM) += platinumfb.o |
@@ -77,7 +74,6 @@ obj-$(CONFIG_FB_TGA) += tgafb.o | |||
77 | obj-$(CONFIG_FB_HP300) += hpfb.o | 74 | obj-$(CONFIG_FB_HP300) += hpfb.o |
78 | obj-$(CONFIG_FB_G364) += g364fb.o | 75 | obj-$(CONFIG_FB_G364) += g364fb.o |
79 | obj-$(CONFIG_FB_SA1100) += sa1100fb.o | 76 | obj-$(CONFIG_FB_SA1100) += sa1100fb.o |
80 | obj-$(CONFIG_FB_SUN3) += sun3fb.o | ||
81 | obj-$(CONFIG_FB_HIT) += hitfb.o | 77 | obj-$(CONFIG_FB_HIT) += hitfb.o |
82 | obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o | 78 | obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o |
83 | obj-$(CONFIG_FB_PVR2) += pvr2fb.o | 79 | obj-$(CONFIG_FB_PVR2) += pvr2fb.o |
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c deleted file mode 100644 index 0b8d5b12115..00000000000 --- a/drivers/video/cyberfb.c +++ /dev/null | |||
@@ -1,2295 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/cyberfb.c -- CyberVision64 frame buffer device | ||
3 | * $Id: cyberfb.c,v 1.6 1998/09/11 04:54:58 abair Exp $ | ||
4 | * | ||
5 | * Copyright (C) 1998 Alan Bair | ||
6 | * | ||
7 | * This file is based on two CyberVision64 frame buffer device drivers | ||
8 | * | ||
9 | * The second CyberVision64 frame buffer device (cvision.c cvision_core.c): | ||
10 | * | ||
11 | * Copyright (c) 1997 Antonio Santos | ||
12 | * | ||
13 | * Released as a patch to 2.1.35, but never included in the source tree. | ||
14 | * This is based on work from the NetBSD CyberVision64 frame buffer driver | ||
15 | * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c): | ||
16 | * Permission to use the source of this driver was obtained from the | ||
17 | * author Michael Teske by Alan Bair. | ||
18 | * | ||
19 | * Copyright (c) 1995 Michael Teske | ||
20 | * | ||
21 | * The first CyberVision64 frame buffer device (cyberfb.c): | ||
22 | * | ||
23 | * Copyright (C) 1996 Martin Apel | ||
24 | * Geert Uytterhoeven | ||
25 | * | ||
26 | * Which is based on the Amiga frame buffer device (amifb.c): | ||
27 | * | ||
28 | * Copyright (C) 1995 Geert Uytterhoeven | ||
29 | * | ||
30 | * | ||
31 | * History: | ||
32 | * - 22 Dec 95: Original version by Martin Apel | ||
33 | * - 05 Jan 96: Geert: integration into the current source tree | ||
34 | * - 01 Aug 98: Alan: Merge in code from cvision.c and cvision_core.c | ||
35 | * $Log: cyberfb.c,v $ | ||
36 | * Revision 1.6 1998/09/11 04:54:58 abair | ||
37 | * Update for 2.1.120 change in include file location. | ||
38 | * Clean up for public release. | ||
39 | * | ||
40 | * Revision 1.5 1998/09/03 04:27:13 abair | ||
41 | * Move cv64_load_video_mode to cyber_set_video so a new video mode is install | ||
42 | * with each change of the 'var' data. | ||
43 | * | ||
44 | * Revision 1.4 1998/09/01 00:31:17 abair | ||
45 | * Put in a set of default 8,16,24 bpp modes and map cyber8,16 to them. | ||
46 | * Update operations with 'par' to handle a more complete set of parameter | ||
47 | * values for encode/decode process. | ||
48 | * | ||
49 | * Revision 1.3 1998/08/31 21:31:33 abair | ||
50 | * Swap 800x490 for 640x480 video mode and more cleanup. | ||
51 | * Abandon idea to resurrect "custom" mode setting via kernel opts, | ||
52 | * instead work on making use of fbset program to do this. | ||
53 | * | ||
54 | * Revision 1.2 1998/08/31 06:17:08 abair | ||
55 | * Make updates for changes in cyberfb.c released in 2.1.119 | ||
56 | * and do some cleanup of the code. | ||
57 | * | ||
58 | * Revision 1.1 1998/08/29 18:38:31 abair | ||
59 | * Initial revision | ||
60 | * | ||
61 | * Revision 1.3 1998/08/17 06:21:53 abair | ||
62 | * Remove more redundant code after merging in cvision_core.c | ||
63 | * Set blanking by colormap to pale red to detect this vs trying to | ||
64 | * use video blanking. More formating to Linux code style. | ||
65 | * | ||
66 | * Revision 1.2 1998/08/15 17:51:37 abair | ||
67 | * Added cvision_core.c code from 2.1.35 patches. | ||
68 | * Changed to compile correctly and switch to using initialization | ||
69 | * code. Added debugging and dropping of duplicate code. | ||
70 | * | ||
71 | * | ||
72 | * | ||
73 | * This file is subject to the terms and conditions of the GNU General Public | ||
74 | * License. See the file COPYING in the main directory of this archive | ||
75 | * for more details. | ||
76 | */ | ||
77 | |||
78 | |||
79 | #include <linux/module.h> | ||
80 | #include <linux/kernel.h> | ||
81 | #include <linux/errno.h> | ||
82 | #include <linux/string.h> | ||
83 | #include <linux/mm.h> | ||
84 | #include <linux/slab.h> | ||
85 | #include <linux/delay.h> | ||
86 | #include <linux/zorro.h> | ||
87 | #include <linux/fb.h> | ||
88 | #include <linux/init.h> | ||
89 | #include <asm/uaccess.h> | ||
90 | #include <asm/system.h> | ||
91 | #include <asm/irq.h> | ||
92 | #include <asm/pgtable.h> | ||
93 | #include <asm/amigahw.h> | ||
94 | #include <asm/io.h> | ||
95 | |||
96 | #include "cyberfb.h" | ||
97 | #include <video/fbcon.h> | ||
98 | #include <video/fbcon-cfb8.h> | ||
99 | #include <video/fbcon-cfb16.h> | ||
100 | |||
101 | /*#define CYBERFBDEBUG*/ | ||
102 | #ifdef CYBERFBDEBUG | ||
103 | #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) | ||
104 | static void cv64_dump(void); | ||
105 | #else | ||
106 | #define DPRINTK(fmt, args...) | ||
107 | #endif | ||
108 | |||
109 | #define wb_64(regs,reg,dat) (*(((volatile unsigned char *)regs) + reg) = dat) | ||
110 | #define rb_64(regs, reg) (*(((volatile unsigned char *)regs) + reg)) | ||
111 | |||
112 | struct cyberfb_par { | ||
113 | struct fb_var_screeninfo var; | ||
114 | __u32 type; | ||
115 | __u32 type_aux; | ||
116 | __u32 visual; | ||
117 | __u32 line_length; | ||
118 | }; | ||
119 | |||
120 | static struct cyberfb_par current_par; | ||
121 | |||
122 | static int current_par_valid = 0; | ||
123 | |||
124 | static struct display disp; | ||
125 | static struct fb_info fb_info; | ||
126 | |||
127 | |||
128 | /* | ||
129 | * Frame Buffer Name | ||
130 | */ | ||
131 | |||
132 | static char cyberfb_name[16] = "Cybervision"; | ||
133 | |||
134 | |||
135 | /* | ||
136 | * CyberVision Graphics Board | ||
137 | */ | ||
138 | |||
139 | static unsigned char Cyber_colour_table [256][3]; | ||
140 | static unsigned long CyberSize; | ||
141 | static volatile unsigned char *CyberBase; | ||
142 | static volatile unsigned char *CyberMem; | ||
143 | static volatile unsigned char *CyberRegs; | ||
144 | static unsigned long CyberMem_phys; | ||
145 | static unsigned long CyberRegs_phys; | ||
146 | |||
147 | /* | ||
148 | * Predefined Video Modes | ||
149 | */ | ||
150 | |||
151 | static struct { | ||
152 | const char *name; | ||
153 | struct fb_var_screeninfo var; | ||
154 | } cyberfb_predefined[] __initdata = { | ||
155 | { "640x480-8", { /* Default 8 BPP mode (cyber8) */ | ||
156 | 640, 480, 640, 480, 0, 0, 8, 0, | ||
157 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
158 | 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2, | ||
159 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
160 | FB_VMODE_NONINTERLACED | ||
161 | }}, | ||
162 | { "640x480-16", { /* Default 16 BPP mode (cyber16) */ | ||
163 | 640, 480, 640, 480, 0, 0, 16, 0, | ||
164 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
165 | 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2, | ||
166 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
167 | FB_VMODE_NONINTERLACED | ||
168 | }}, | ||
169 | { "640x480-24", { /* Default 24 BPP mode */ | ||
170 | 640, 480, 640, 480, 0, 0, 24, 0, | ||
171 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
172 | 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2, | ||
173 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
174 | FB_VMODE_NONINTERLACED | ||
175 | }}, | ||
176 | { "800x490-8", { /* Cybervision 8 bpp */ | ||
177 | /* NO Acceleration */ | ||
178 | 800, 490, 800, 490, 0, 0, 8, 0, | ||
179 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
180 | 0, 0, -1, -1, FB_ACCEL_NONE, 33333, 80, 24, 23, 1, 56, 8, | ||
181 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
182 | FB_VMODE_NONINTERLACED | ||
183 | }}, | ||
184 | /* I can't test these with my monitor, but I suspect they will | ||
185 | * be OK, since Antonio Santos indicated he had tested them in | ||
186 | * his system. | ||
187 | */ | ||
188 | { "800x600-8", { /* Cybervision 8 bpp */ | ||
189 | 800, 600, 800, 600, 0, 0, 8, 0, | ||
190 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
191 | 0, 0, -1, -1, FB_ACCELF_TEXT, 27778, 64, 24, 22, 1, 72, 2, | ||
192 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
193 | FB_VMODE_NONINTERLACED | ||
194 | }}, | ||
195 | { "1024x768-8", { /* Cybervision 8 bpp */ | ||
196 | 1024, 768, 1024, 768, 0, 0, 8, 0, | ||
197 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
198 | 0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 224, 72, 60, 12, 168, 4, | ||
199 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
200 | FB_VMODE_NONINTERLACED | ||
201 | }}, | ||
202 | { "1152x886-8", { /* Cybervision 8 bpp */ | ||
203 | 1152, 886, 1152, 886, 0, 0, 8, 0, | ||
204 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
205 | 0, 0, -1, -1, FB_ACCELF_TEXT, 15873, 184, 40, 24, 1, 56, 16, | ||
206 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
207 | FB_VMODE_NONINTERLACED | ||
208 | }}, | ||
209 | { "1280x1024-8", { /* Cybervision 8 bpp */ | ||
210 | 1280, 1024, 1280, 1024, 0, 0, 8, 0, | ||
211 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
212 | 0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 256, 48, 50, 12, 72, 4, | ||
213 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
214 | FB_VMODE_INTERLACED | ||
215 | }} | ||
216 | }; | ||
217 | |||
218 | #define NUM_TOTAL_MODES ARRAY_SIZE(cyberfb_predefined) | ||
219 | |||
220 | static int Cyberfb_inverse = 0; | ||
221 | |||
222 | /* | ||
223 | * Some default modes | ||
224 | */ | ||
225 | |||
226 | #define CYBER8_DEFMODE (0) | ||
227 | #define CYBER16_DEFMODE (1) | ||
228 | |||
229 | static struct fb_var_screeninfo cyberfb_default; | ||
230 | static int cyberfb_usermode __initdata = 0; | ||
231 | |||
232 | /* | ||
233 | * Interface used by the world | ||
234 | */ | ||
235 | |||
236 | int cyberfb_setup(char *options); | ||
237 | |||
238 | static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
239 | struct fb_info *info); | ||
240 | static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, | ||
241 | struct fb_info *info); | ||
242 | static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, | ||
243 | struct fb_info *info); | ||
244 | static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
245 | struct fb_info *info); | ||
246 | static int cyberfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
247 | u_int transp, struct fb_info *info); | ||
248 | static int cyberfb_blank(int blank, struct fb_info *info); | ||
249 | |||
250 | /* | ||
251 | * Interface to the low level console driver | ||
252 | */ | ||
253 | |||
254 | int cyberfb_init(void); | ||
255 | static int Cyberfb_switch(int con, struct fb_info *info); | ||
256 | static int Cyberfb_updatevar(int con, struct fb_info *info); | ||
257 | |||
258 | /* | ||
259 | * Text console acceleration | ||
260 | */ | ||
261 | |||
262 | #ifdef FBCON_HAS_CFB8 | ||
263 | static struct display_switch fbcon_cyber8; | ||
264 | #endif | ||
265 | |||
266 | /* | ||
267 | * Accelerated Functions used by the low level console driver | ||
268 | */ | ||
269 | |||
270 | static void Cyber_WaitQueue(u_short fifo); | ||
271 | static void Cyber_WaitBlit(void); | ||
272 | static void Cyber_BitBLT(u_short curx, u_short cury, u_short destx, | ||
273 | u_short desty, u_short width, u_short height, | ||
274 | u_short mode); | ||
275 | static void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height, | ||
276 | u_short mode, u_short color); | ||
277 | #if 0 | ||
278 | static void Cyber_MoveCursor(u_short x, u_short y); | ||
279 | #endif | ||
280 | |||
281 | /* | ||
282 | * Hardware Specific Routines | ||
283 | */ | ||
284 | |||
285 | static int Cyber_init(void); | ||
286 | static int Cyber_encode_fix(struct fb_fix_screeninfo *fix, | ||
287 | struct cyberfb_par *par); | ||
288 | static int Cyber_decode_var(struct fb_var_screeninfo *var, | ||
289 | struct cyberfb_par *par); | ||
290 | static int Cyber_encode_var(struct fb_var_screeninfo *var, | ||
291 | struct cyberfb_par *par); | ||
292 | static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
293 | u_int *transp, struct fb_info *info); | ||
294 | |||
295 | /* | ||
296 | * Internal routines | ||
297 | */ | ||
298 | |||
299 | static void cyberfb_get_par(struct cyberfb_par *par); | ||
300 | static void cyberfb_set_par(struct cyberfb_par *par); | ||
301 | static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); | ||
302 | static void cyberfb_set_disp(int con, struct fb_info *info); | ||
303 | static int get_video_mode(const char *name); | ||
304 | |||
305 | /* For cvision_core.c */ | ||
306 | static unsigned short cv64_compute_clock(unsigned long); | ||
307 | static int cv_has_4mb (volatile unsigned char *); | ||
308 | static void cv64_board_init (void); | ||
309 | static void cv64_load_video_mode (struct fb_var_screeninfo *); | ||
310 | |||
311 | |||
312 | /* -------------------- Hardware specific routines ------------------------- */ | ||
313 | |||
314 | |||
315 | /* | ||
316 | * Initialization | ||
317 | * | ||
318 | * Set the default video mode for this chipset. If a video mode was | ||
319 | * specified on the command line, it will override the default mode. | ||
320 | */ | ||
321 | |||
322 | static int Cyber_init(void) | ||
323 | { | ||
324 | volatile unsigned char *regs = CyberRegs; | ||
325 | volatile unsigned long *CursorBase; | ||
326 | int i; | ||
327 | DPRINTK("ENTER\n"); | ||
328 | |||
329 | /* Init local cmap as greyscale levels */ | ||
330 | for (i = 0; i < 256; i++) { | ||
331 | Cyber_colour_table [i][0] = i; | ||
332 | Cyber_colour_table [i][1] = i; | ||
333 | Cyber_colour_table [i][2] = i; | ||
334 | } | ||
335 | |||
336 | /* Initialize the board and determine fbmem size */ | ||
337 | cv64_board_init(); | ||
338 | #ifdef CYBERFBDEBUG | ||
339 | DPRINTK("Register state after initing board\n"); | ||
340 | cv64_dump(); | ||
341 | #endif | ||
342 | /* Clear framebuffer memory */ | ||
343 | DPRINTK("Clear framebuffer memory\n"); | ||
344 | memset ((char *)CyberMem, 0, CyberSize); | ||
345 | |||
346 | /* Disable hardware cursor */ | ||
347 | DPRINTK("Disable HW cursor\n"); | ||
348 | wb_64(regs, S3_CRTC_ADR, S3_REG_LOCK2); | ||
349 | wb_64(regs, S3_CRTC_DATA, 0xa0); | ||
350 | wb_64(regs, S3_CRTC_ADR, S3_HGC_MODE); | ||
351 | wb_64(regs, S3_CRTC_DATA, 0x00); | ||
352 | wb_64(regs, S3_CRTC_ADR, S3_HWGC_DX); | ||
353 | wb_64(regs, S3_CRTC_DATA, 0x00); | ||
354 | wb_64(regs, S3_CRTC_ADR, S3_HWGC_DY); | ||
355 | wb_64(regs, S3_CRTC_DATA, 0x00); | ||
356 | |||
357 | /* Initialize hardware cursor */ | ||
358 | DPRINTK("Init HW cursor\n"); | ||
359 | CursorBase = (u_long *)((char *)(CyberMem) + CyberSize - 0x400); | ||
360 | for (i=0; i < 8; i++) | ||
361 | { | ||
362 | *(CursorBase +(i*4)) = 0xffffff00; | ||
363 | *(CursorBase+1+(i*4)) = 0xffff0000; | ||
364 | *(CursorBase+2+(i*4)) = 0xffff0000; | ||
365 | *(CursorBase+3+(i*4)) = 0xffff0000; | ||
366 | } | ||
367 | for (i=8; i < 64; i++) | ||
368 | { | ||
369 | *(CursorBase +(i*4)) = 0xffff0000; | ||
370 | *(CursorBase+1+(i*4)) = 0xffff0000; | ||
371 | *(CursorBase+2+(i*4)) = 0xffff0000; | ||
372 | *(CursorBase+3+(i*4)) = 0xffff0000; | ||
373 | } | ||
374 | |||
375 | cyberfb_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, NULL /* unused */); | ||
376 | cyberfb_setcolreg (254, 0, 0, 0, 0, NULL /* unused */); | ||
377 | |||
378 | DPRINTK("EXIT\n"); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | |||
383 | /* | ||
384 | * This function should fill in the `fix' structure based on the | ||
385 | * values in the `par' structure. | ||
386 | */ | ||
387 | |||
388 | static int Cyber_encode_fix(struct fb_fix_screeninfo *fix, | ||
389 | struct cyberfb_par *par) | ||
390 | { | ||
391 | DPRINTK("ENTER\n"); | ||
392 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | ||
393 | strcpy(fix->id, cyberfb_name); | ||
394 | fix->smem_start = CyberMem_phys; | ||
395 | fix->smem_len = CyberSize; | ||
396 | fix->mmio_start = CyberRegs_phys; | ||
397 | fix->mmio_len = 0x10000; | ||
398 | |||
399 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
400 | fix->type_aux = 0; | ||
401 | if (par->var.bits_per_pixel == 15 || par->var.bits_per_pixel == 16 || | ||
402 | par->var.bits_per_pixel == 24 || par->var.bits_per_pixel == 32) { | ||
403 | fix->visual = FB_VISUAL_DIRECTCOLOR; | ||
404 | } else { | ||
405 | fix->visual = FB_VISUAL_PSEUDOCOLOR; | ||
406 | } | ||
407 | |||
408 | fix->xpanstep = 0; | ||
409 | fix->ypanstep = 0; | ||
410 | fix->ywrapstep = 0; | ||
411 | fix->line_length = 0; | ||
412 | fix->accel = FB_ACCEL_S3_TRIO64; | ||
413 | |||
414 | DPRINTK("EXIT\n"); | ||
415 | return(0); | ||
416 | } | ||
417 | |||
418 | |||
419 | /* | ||
420 | * Fill the `par' structure based on the values in `var'. | ||
421 | * TODO: Verify and adjust values, return -EINVAL if bad. | ||
422 | */ | ||
423 | |||
424 | static int Cyber_decode_var(struct fb_var_screeninfo *var, | ||
425 | struct cyberfb_par *par) | ||
426 | { | ||
427 | DPRINTK("ENTER\n"); | ||
428 | par->var.xres = var->xres; | ||
429 | par->var.yres = var->yres; | ||
430 | par->var.xres_virtual = var->xres_virtual; | ||
431 | par->var.yres_virtual = var->yres_virtual; | ||
432 | par->var.xoffset = var->xoffset; | ||
433 | par->var.yoffset = var->yoffset; | ||
434 | par->var.bits_per_pixel = var->bits_per_pixel; | ||
435 | par->var.grayscale = var->grayscale; | ||
436 | par->var.red = var->red; | ||
437 | par->var.green = var->green; | ||
438 | par->var.blue = var->blue; | ||
439 | par->var.transp = var->transp; | ||
440 | par->var.nonstd = var->nonstd; | ||
441 | par->var.activate = var->activate; | ||
442 | par->var.height = var->height; | ||
443 | par->var.width = var->width; | ||
444 | if (var->accel_flags & FB_ACCELF_TEXT) { | ||
445 | par->var.accel_flags = FB_ACCELF_TEXT; | ||
446 | } else { | ||
447 | par->var.accel_flags = 0; | ||
448 | } | ||
449 | par->var.pixclock = var->pixclock; | ||
450 | par->var.left_margin = var->left_margin; | ||
451 | par->var.right_margin = var->right_margin; | ||
452 | par->var.upper_margin = var->upper_margin; | ||
453 | par->var.lower_margin = var->lower_margin; | ||
454 | par->var.hsync_len = var->hsync_len; | ||
455 | par->var.vsync_len = var->vsync_len; | ||
456 | par->var.sync = var->sync; | ||
457 | par->var.vmode = var->vmode; | ||
458 | DPRINTK("EXIT\n"); | ||
459 | return(0); | ||
460 | } | ||
461 | |||
462 | /* | ||
463 | * Fill the `var' structure based on the values in `par' and maybe | ||
464 | * other values read out of the hardware. | ||
465 | */ | ||
466 | |||
467 | static int Cyber_encode_var(struct fb_var_screeninfo *var, | ||
468 | struct cyberfb_par *par) | ||
469 | { | ||
470 | DPRINTK("ENTER\n"); | ||
471 | var->xres = par->var.xres; | ||
472 | var->yres = par->var.yres; | ||
473 | var->xres_virtual = par->var.xres_virtual; | ||
474 | var->yres_virtual = par->var.yres_virtual; | ||
475 | var->xoffset = par->var.xoffset; | ||
476 | var->yoffset = par->var.yoffset; | ||
477 | |||
478 | var->bits_per_pixel = par->var.bits_per_pixel; | ||
479 | var->grayscale = par->var.grayscale; | ||
480 | |||
481 | var->red = par->var.red; | ||
482 | var->green = par->var.green; | ||
483 | var->blue = par->var.blue; | ||
484 | var->transp = par->var.transp; | ||
485 | |||
486 | var->nonstd = par->var.nonstd; | ||
487 | var->activate = par->var.activate; | ||
488 | |||
489 | var->height = par->var.height; | ||
490 | var->width = par->var.width; | ||
491 | |||
492 | var->accel_flags = par->var.accel_flags; | ||
493 | |||
494 | var->pixclock = par->var.pixclock; | ||
495 | var->left_margin = par->var.left_margin; | ||
496 | var->right_margin = par->var.right_margin; | ||
497 | var->upper_margin = par->var.upper_margin; | ||
498 | var->lower_margin = par->var.lower_margin; | ||
499 | var->hsync_len = par->var.hsync_len; | ||
500 | var->vsync_len = par->var.vsync_len; | ||
501 | var->sync = par->var.sync; | ||
502 | var->vmode = par->var.vmode; | ||
503 | |||
504 | DPRINTK("EXIT\n"); | ||
505 | return(0); | ||
506 | } | ||
507 | |||
508 | |||
509 | /* | ||
510 | * Set a single color register. Return != 0 for invalid regno. | ||
511 | */ | ||
512 | |||
513 | static int cyberfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
514 | u_int transp, struct fb_info *info) | ||
515 | { | ||
516 | volatile unsigned char *regs = CyberRegs; | ||
517 | |||
518 | /*DPRINTK("ENTER\n");*/ | ||
519 | if (regno > 255) { | ||
520 | DPRINTK("EXIT - Register # > 255\n"); | ||
521 | return (1); | ||
522 | } | ||
523 | |||
524 | wb_64(regs, 0x3c8, (unsigned char) regno); | ||
525 | |||
526 | red >>= 10; | ||
527 | green >>= 10; | ||
528 | blue >>= 10; | ||
529 | |||
530 | Cyber_colour_table [regno][0] = red; | ||
531 | Cyber_colour_table [regno][1] = green; | ||
532 | Cyber_colour_table [regno][2] = blue; | ||
533 | |||
534 | wb_64(regs, 0x3c9, red); | ||
535 | wb_64(regs, 0x3c9, green); | ||
536 | wb_64(regs, 0x3c9, blue); | ||
537 | |||
538 | /*DPRINTK("EXIT\n");*/ | ||
539 | return (0); | ||
540 | } | ||
541 | |||
542 | |||
543 | /* | ||
544 | * Read a single color register and split it into | ||
545 | * colors/transparent. Return != 0 for invalid regno. | ||
546 | */ | ||
547 | |||
548 | static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
549 | u_int *transp, struct fb_info *info) | ||
550 | { | ||
551 | int t; | ||
552 | |||
553 | /*DPRINTK("ENTER\n");*/ | ||
554 | if (regno > 255) { | ||
555 | DPRINTK("EXIT - Register # > 255\n"); | ||
556 | return (1); | ||
557 | } | ||
558 | /* ARB This shifting & oring seems VERY strange */ | ||
559 | t = Cyber_colour_table [regno][0]; | ||
560 | *red = (t<<10) | (t<<4) | (t>>2); | ||
561 | t = Cyber_colour_table [regno][1]; | ||
562 | *green = (t<<10) | (t<<4) | (t>>2); | ||
563 | t = Cyber_colour_table [regno][2]; | ||
564 | *blue = (t<<10) | (t<<4) | (t>>2); | ||
565 | *transp = 0; | ||
566 | /*DPRINTK("EXIT\n");*/ | ||
567 | return (0); | ||
568 | } | ||
569 | |||
570 | |||
571 | /* | ||
572 | * (Un)Blank the screen | ||
573 | * blank: 1 = zero fb cmap | ||
574 | * 0 = restore fb cmap from local cmap | ||
575 | */ | ||
576 | static int cyberfb_blank(int blank, struct fb_info *info) | ||
577 | { | ||
578 | volatile unsigned char *regs = CyberRegs; | ||
579 | int i; | ||
580 | |||
581 | DPRINTK("ENTER\n"); | ||
582 | #if 0 | ||
583 | /* Blank by turning gfx off */ | ||
584 | gfx_on_off (1, regs); | ||
585 | #else | ||
586 | if (blank) { | ||
587 | for (i = 0; i < 256; i++) { | ||
588 | wb_64(regs, 0x3c8, (unsigned char) i); | ||
589 | /* ARB Pale red to detect this blanking method */ | ||
590 | wb_64(regs, 0x3c9, 48); | ||
591 | wb_64(regs, 0x3c9, 0); | ||
592 | wb_64(regs, 0x3c9, 0); | ||
593 | } | ||
594 | } else { | ||
595 | for (i = 0; i < 256; i++) { | ||
596 | wb_64(regs, 0x3c8, (unsigned char) i); | ||
597 | wb_64(regs, 0x3c9, Cyber_colour_table[i][0]); | ||
598 | wb_64(regs, 0x3c9, Cyber_colour_table[i][1]); | ||
599 | wb_64(regs, 0x3c9, Cyber_colour_table[i][2]); | ||
600 | } | ||
601 | } | ||
602 | #endif | ||
603 | DPRINTK("EXIT\n"); | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | |||
608 | /************************************************************** | ||
609 | * We are waiting for "fifo" FIFO-slots empty | ||
610 | */ | ||
611 | static void Cyber_WaitQueue (u_short fifo) | ||
612 | { | ||
613 | unsigned short status; | ||
614 | |||
615 | DPRINTK("ENTER\n"); | ||
616 | do { | ||
617 | status = *((u_short volatile *)(CyberRegs + S3_GP_STAT)); | ||
618 | } while (status & fifo); | ||
619 | DPRINTK("EXIT\n"); | ||
620 | } | ||
621 | |||
622 | /************************************************************** | ||
623 | * We are waiting for Hardware (Graphics Engine) not busy | ||
624 | */ | ||
625 | static void Cyber_WaitBlit (void) | ||
626 | { | ||
627 | unsigned short status; | ||
628 | |||
629 | DPRINTK("ENTER\n"); | ||
630 | do { | ||
631 | status = *((u_short volatile *)(CyberRegs + S3_GP_STAT)); | ||
632 | } while (status & S3_HDW_BUSY); | ||
633 | DPRINTK("EXIT\n"); | ||
634 | } | ||
635 | |||
636 | /************************************************************** | ||
637 | * BitBLT - Through the Plane | ||
638 | */ | ||
639 | static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx, | ||
640 | u_short desty, u_short width, u_short height, | ||
641 | u_short mode) | ||
642 | { | ||
643 | volatile unsigned char *regs = CyberRegs; | ||
644 | u_short blitcmd = S3_BITBLT; | ||
645 | |||
646 | DPRINTK("ENTER\n"); | ||
647 | /* Set drawing direction */ | ||
648 | /* -Y, X maj, -X (default) */ | ||
649 | if (curx > destx) { | ||
650 | blitcmd |= 0x0020; /* Drawing direction +X */ | ||
651 | } else { | ||
652 | curx += (width - 1); | ||
653 | destx += (width - 1); | ||
654 | } | ||
655 | |||
656 | if (cury > desty) { | ||
657 | blitcmd |= 0x0080; /* Drawing direction +Y */ | ||
658 | } else { | ||
659 | cury += (height - 1); | ||
660 | desty += (height - 1); | ||
661 | } | ||
662 | |||
663 | Cyber_WaitQueue (0x8000); | ||
664 | |||
665 | *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000; | ||
666 | *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0060 | mode); | ||
667 | |||
668 | *((u_short volatile *)(regs + S3_CUR_X)) = curx; | ||
669 | *((u_short volatile *)(regs + S3_CUR_Y)) = cury; | ||
670 | |||
671 | *((u_short volatile *)(regs + S3_DESTX_DIASTP)) = destx; | ||
672 | *((u_short volatile *)(regs + S3_DESTY_AXSTP)) = desty; | ||
673 | |||
674 | *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1; | ||
675 | *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1; | ||
676 | |||
677 | *((u_short volatile *)(regs + S3_CMD)) = blitcmd; | ||
678 | DPRINTK("EXIT\n"); | ||
679 | } | ||
680 | |||
681 | /************************************************************** | ||
682 | * Rectangle Fill Solid | ||
683 | */ | ||
684 | static void Cyber_RectFill (u_short x, u_short y, u_short width, | ||
685 | u_short height, u_short mode, u_short color) | ||
686 | { | ||
687 | volatile unsigned char *regs = CyberRegs; | ||
688 | u_short blitcmd = S3_FILLEDRECT; | ||
689 | |||
690 | DPRINTK("ENTER\n"); | ||
691 | Cyber_WaitQueue (0x8000); | ||
692 | |||
693 | *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000; | ||
694 | *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0020 | mode); | ||
695 | |||
696 | *((u_short volatile *)(regs + S3_MULT_MISC)) = 0xe000; | ||
697 | *((u_short volatile *)(regs + S3_FRGD_COLOR)) = color; | ||
698 | |||
699 | *((u_short volatile *)(regs + S3_CUR_X)) = x; | ||
700 | *((u_short volatile *)(regs + S3_CUR_Y)) = y; | ||
701 | |||
702 | *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1; | ||
703 | *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1; | ||
704 | |||
705 | *((u_short volatile *)(regs + S3_CMD)) = blitcmd; | ||
706 | DPRINTK("EXIT\n"); | ||
707 | } | ||
708 | |||
709 | |||
710 | #if 0 | ||
711 | /************************************************************** | ||
712 | * Move cursor to x, y | ||
713 | */ | ||
714 | static void Cyber_MoveCursor (u_short x, u_short y) | ||
715 | { | ||
716 | volatile unsigned char *regs = CyberRegs; | ||
717 | DPRINTK("ENTER\n"); | ||
718 | *(regs + S3_CRTC_ADR) = 0x39; | ||
719 | *(regs + S3_CRTC_DATA) = 0xa0; | ||
720 | |||
721 | *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H; | ||
722 | *(regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8); | ||
723 | *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L; | ||
724 | *(regs + S3_CRTC_DATA) = (char)(x & 0x00ff); | ||
725 | |||
726 | *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H; | ||
727 | *(regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8); | ||
728 | *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L; | ||
729 | *(regs + S3_CRTC_DATA) = (char)(y & 0x00ff); | ||
730 | DPRINTK("EXIT\n"); | ||
731 | } | ||
732 | #endif | ||
733 | |||
734 | |||
735 | /* -------------------- Generic routines ---------------------------------- */ | ||
736 | |||
737 | |||
738 | /* | ||
739 | * Fill the hardware's `par' structure. | ||
740 | */ | ||
741 | |||
742 | static void cyberfb_get_par(struct cyberfb_par *par) | ||
743 | { | ||
744 | DPRINTK("ENTER\n"); | ||
745 | if (current_par_valid) { | ||
746 | *par = current_par; | ||
747 | } else { | ||
748 | Cyber_decode_var(&cyberfb_default, par); | ||
749 | } | ||
750 | DPRINTK("EXIT\n"); | ||
751 | } | ||
752 | |||
753 | |||
754 | static void cyberfb_set_par(struct cyberfb_par *par) | ||
755 | { | ||
756 | DPRINTK("ENTER\n"); | ||
757 | current_par = *par; | ||
758 | current_par_valid = 1; | ||
759 | DPRINTK("EXIT\n"); | ||
760 | } | ||
761 | |||
762 | |||
763 | static void cyber_set_video(struct fb_var_screeninfo *var) | ||
764 | { | ||
765 | |||
766 | /* Load the video mode defined by the 'var' data */ | ||
767 | cv64_load_video_mode (var); | ||
768 | #ifdef CYBERFBDEBUG | ||
769 | DPRINTK("Register state after loading video mode\n"); | ||
770 | cv64_dump(); | ||
771 | #endif | ||
772 | } | ||
773 | |||
774 | |||
775 | static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) | ||
776 | { | ||
777 | int err, activate; | ||
778 | struct cyberfb_par par; | ||
779 | |||
780 | DPRINTK("ENTER\n"); | ||
781 | if ((err = Cyber_decode_var(var, &par))) { | ||
782 | DPRINTK("EXIT - decode_var failed\n"); | ||
783 | return(err); | ||
784 | } | ||
785 | activate = var->activate; | ||
786 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) | ||
787 | cyberfb_set_par(&par); | ||
788 | Cyber_encode_var(var, &par); | ||
789 | var->activate = activate; | ||
790 | |||
791 | cyber_set_video(var); | ||
792 | DPRINTK("EXIT\n"); | ||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | /* | ||
797 | * Get the Fixed Part of the Display | ||
798 | */ | ||
799 | |||
800 | static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
801 | struct fb_info *info) | ||
802 | { | ||
803 | struct cyberfb_par par; | ||
804 | int error = 0; | ||
805 | |||
806 | DPRINTK("ENTER\n"); | ||
807 | if (con == -1) { | ||
808 | cyberfb_get_par(&par); | ||
809 | } else { | ||
810 | error = Cyber_decode_var(&fb_display[con].var, &par); | ||
811 | } | ||
812 | DPRINTK("EXIT\n"); | ||
813 | return(error ? error : Cyber_encode_fix(fix, &par)); | ||
814 | } | ||
815 | |||
816 | |||
817 | /* | ||
818 | * Get the User Defined Part of the Display | ||
819 | */ | ||
820 | |||
821 | static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, | ||
822 | struct fb_info *info) | ||
823 | { | ||
824 | struct cyberfb_par par; | ||
825 | int error = 0; | ||
826 | |||
827 | DPRINTK("ENTER\n"); | ||
828 | if (con == -1) { | ||
829 | cyberfb_get_par(&par); | ||
830 | error = Cyber_encode_var(var, &par); | ||
831 | disp.var = *var; /* ++Andre: don't know if this is the right place */ | ||
832 | } else { | ||
833 | *var = fb_display[con].var; | ||
834 | } | ||
835 | |||
836 | DPRINTK("EXIT\n"); | ||
837 | return(error); | ||
838 | } | ||
839 | |||
840 | |||
841 | static void cyberfb_set_disp(int con, struct fb_info *info) | ||
842 | { | ||
843 | struct fb_fix_screeninfo fix; | ||
844 | struct display *display; | ||
845 | |||
846 | DPRINTK("ENTER\n"); | ||
847 | if (con >= 0) | ||
848 | display = &fb_display[con]; | ||
849 | else | ||
850 | display = &disp; /* used during initialization */ | ||
851 | |||
852 | cyberfb_get_fix(&fix, con, info); | ||
853 | if (con == -1) | ||
854 | con = 0; | ||
855 | display->visual = fix.visual; | ||
856 | display->type = fix.type; | ||
857 | display->type_aux = fix.type_aux; | ||
858 | display->ypanstep = fix.ypanstep; | ||
859 | display->ywrapstep = fix.ywrapstep; | ||
860 | display->can_soft_blank = 1; | ||
861 | display->inverse = Cyberfb_inverse; | ||
862 | switch (display->var.bits_per_pixel) { | ||
863 | #ifdef FBCON_HAS_CFB8 | ||
864 | case 8: | ||
865 | if (display->var.accel_flags & FB_ACCELF_TEXT) { | ||
866 | display->dispsw = &fbcon_cyber8; | ||
867 | #warning FIXME: We should reinit the graphics engine here | ||
868 | } else | ||
869 | display->dispsw = &fbcon_cfb8; | ||
870 | break; | ||
871 | #endif | ||
872 | #ifdef FBCON_HAS_CFB16 | ||
873 | case 16: | ||
874 | display->dispsw = &fbcon_cfb16; | ||
875 | break; | ||
876 | #endif | ||
877 | default: | ||
878 | display->dispsw = NULL; | ||
879 | break; | ||
880 | } | ||
881 | DPRINTK("EXIT\n"); | ||
882 | } | ||
883 | |||
884 | |||
885 | /* | ||
886 | * Set the User Defined Part of the Display | ||
887 | */ | ||
888 | |||
889 | static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, | ||
890 | struct fb_info *info) | ||
891 | { | ||
892 | int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel; | ||
893 | |||
894 | DPRINTK("ENTER\n"); | ||
895 | if ((err = do_fb_set_var(var, con == info->currcon))) { | ||
896 | DPRINTK("EXIT - do_fb_set_var failed\n"); | ||
897 | return(err); | ||
898 | } | ||
899 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { | ||
900 | oldxres = fb_display[con].var.xres; | ||
901 | oldyres = fb_display[con].var.yres; | ||
902 | oldvxres = fb_display[con].var.xres_virtual; | ||
903 | oldvyres = fb_display[con].var.yres_virtual; | ||
904 | oldbpp = fb_display[con].var.bits_per_pixel; | ||
905 | oldaccel = fb_display[con].var.accel_flags; | ||
906 | fb_display[con].var = *var; | ||
907 | if (oldxres != var->xres || oldyres != var->yres || | ||
908 | oldvxres != var->xres_virtual || | ||
909 | oldvyres != var->yres_virtual || | ||
910 | oldbpp != var->bits_per_pixel || | ||
911 | oldaccel != var->accel_flags) { | ||
912 | cyberfb_set_disp(con, info); | ||
913 | (*fb_info.changevar)(con); | ||
914 | fb_alloc_cmap(&fb_display[con].cmap, 0, 0); | ||
915 | do_install_cmap(con, info); | ||
916 | } | ||
917 | } | ||
918 | var->activate = 0; | ||
919 | DPRINTK("EXIT\n"); | ||
920 | return(0); | ||
921 | } | ||
922 | |||
923 | |||
924 | /* | ||
925 | * Get the Colormap | ||
926 | */ | ||
927 | |||
928 | static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
929 | struct fb_info *info) | ||
930 | { | ||
931 | DPRINTK("ENTER\n"); | ||
932 | if (con == info->currcon) { /* current console? */ | ||
933 | DPRINTK("EXIT - console is current console\n"); | ||
934 | return(fb_get_cmap(cmap, kspc, Cyber_getcolreg, info)); | ||
935 | } else if (fb_display[con].cmap.len) { /* non default colormap? */ | ||
936 | DPRINTK("Use console cmap\n"); | ||
937 | fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); | ||
938 | } else { | ||
939 | DPRINTK("Use default cmap\n"); | ||
940 | fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), | ||
941 | cmap, kspc ? 0 : 2); | ||
942 | } | ||
943 | DPRINTK("EXIT\n"); | ||
944 | return(0); | ||
945 | } | ||
946 | |||
947 | static struct fb_ops cyberfb_ops = { | ||
948 | .owner = THIS_MODULE, | ||
949 | .fb_get_fix = cyberfb_get_fix, | ||
950 | .fb_get_var = cyberfb_get_var, | ||
951 | .fb_set_var = cyberfb_set_var, | ||
952 | .fb_get_cmap = cyberfb_get_cmap, | ||
953 | .fb_set_cmap = gen_set_cmap, | ||
954 | .fb_setcolreg = cyberfb_setcolreg, | ||
955 | .fb_blank = cyberfb_blank, | ||
956 | }; | ||
957 | |||
958 | int __init cyberfb_setup(char *options) | ||
959 | { | ||
960 | char *this_opt; | ||
961 | DPRINTK("ENTER\n"); | ||
962 | |||
963 | fb_info.fontname[0] = '\0'; | ||
964 | |||
965 | if (!options || !*options) { | ||
966 | DPRINTK("EXIT - no options\n"); | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
971 | if (!*this_opt) | ||
972 | continue; | ||
973 | if (!strcmp(this_opt, "inverse")) { | ||
974 | Cyberfb_inverse = 1; | ||
975 | fb_invert_cmaps(); | ||
976 | } else if (!strncmp(this_opt, "font:", 5)) { | ||
977 | strcpy(fb_info.fontname, this_opt+5); | ||
978 | } else if (!strcmp (this_opt, "cyber8")) { | ||
979 | cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var; | ||
980 | cyberfb_usermode = 1; | ||
981 | } else if (!strcmp (this_opt, "cyber16")) { | ||
982 | cyberfb_default = cyberfb_predefined[CYBER16_DEFMODE].var; | ||
983 | cyberfb_usermode = 1; | ||
984 | } else get_video_mode(this_opt); | ||
985 | } | ||
986 | |||
987 | DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n", | ||
988 | cyberfb_default.xres, | ||
989 | cyberfb_default.yres, | ||
990 | cyberfb_default.bits_per_pixel); | ||
991 | DPRINTK("EXIT\n"); | ||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | /* | ||
996 | * Initialization | ||
997 | */ | ||
998 | |||
999 | int __init cyberfb_init(void) | ||
1000 | { | ||
1001 | unsigned long board_addr, board_size; | ||
1002 | struct cyberfb_par par; | ||
1003 | struct zorro_dev *z = NULL; | ||
1004 | DPRINTK("ENTER\n"); | ||
1005 | |||
1006 | while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64, z))) { | ||
1007 | board_addr = z->resource.start; | ||
1008 | board_size = z->resource.end-z->resource.start+1; | ||
1009 | CyberMem_phys = board_addr + 0x01400000; | ||
1010 | CyberRegs_phys = CyberMem_phys + 0x00c00000; | ||
1011 | if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 Trio64")) | ||
1012 | continue; | ||
1013 | if (!request_mem_region(CyberMem_phys, 0x400000, "RAM")) { | ||
1014 | release_mem_region(CyberRegs_phys, 0x10000); | ||
1015 | continue; | ||
1016 | } | ||
1017 | DPRINTK("board_addr=%08lx\n", board_addr); | ||
1018 | DPRINTK("board_size=%08lx\n", board_size); | ||
1019 | |||
1020 | CyberBase = ioremap(board_addr, board_size); | ||
1021 | CyberRegs = CyberBase + 0x02000000; | ||
1022 | CyberMem = CyberBase + 0x01400000; | ||
1023 | DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n", | ||
1024 | CyberBase, (long unsigned int)CyberRegs, CyberMem); | ||
1025 | |||
1026 | #ifdef CYBERFBDEBUG | ||
1027 | DPRINTK("Register state just after mapping memory\n"); | ||
1028 | cv64_dump(); | ||
1029 | #endif | ||
1030 | |||
1031 | strcpy(fb_info.modename, cyberfb_name); | ||
1032 | fb_info.changevar = NULL; | ||
1033 | fb_info.fbops = &cyberfb_ops; | ||
1034 | fb_info.screen_base = (unsigned char *)CyberMem; | ||
1035 | fb_info.disp = &disp; | ||
1036 | fb_info.currcon = -1; | ||
1037 | fb_info.switch_con = &Cyberfb_switch; | ||
1038 | fb_info.updatevar = &Cyberfb_updatevar; | ||
1039 | |||
1040 | Cyber_init(); | ||
1041 | /* ++Andre: set cyberfb default mode */ | ||
1042 | if (!cyberfb_usermode) { | ||
1043 | cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var; | ||
1044 | DPRINTK("Use default cyber8 mode\n"); | ||
1045 | } | ||
1046 | Cyber_decode_var(&cyberfb_default, &par); | ||
1047 | Cyber_encode_var(&cyberfb_default, &par); | ||
1048 | |||
1049 | do_fb_set_var(&cyberfb_default, 1); | ||
1050 | cyberfb_get_var(&fb_display[0].var, -1, &fb_info); | ||
1051 | cyberfb_set_disp(-1, &fb_info); | ||
1052 | do_install_cmap(0, &fb_info); | ||
1053 | |||
1054 | if (register_framebuffer(&fb_info) < 0) { | ||
1055 | DPRINTK("EXIT - register_framebuffer failed\n"); | ||
1056 | if (CyberBase) | ||
1057 | iounmap(CyberBase); | ||
1058 | release_mem_region(CyberMem_phys, 0x400000); | ||
1059 | release_mem_region(CyberRegs_phys, 0x10000); | ||
1060 | return -EINVAL; | ||
1061 | } | ||
1062 | |||
1063 | printk("fb%d: %s frame buffer device, using %ldK of video memory\n", | ||
1064 | fb_info.node, fb_info.modename, CyberSize>>10); | ||
1065 | |||
1066 | /* TODO: This driver cannot be unloaded yet */ | ||
1067 | DPRINTK("EXIT\n"); | ||
1068 | return 0; | ||
1069 | } | ||
1070 | return -ENXIO; | ||
1071 | } | ||
1072 | |||
1073 | |||
1074 | static int Cyberfb_switch(int con, struct fb_info *info) | ||
1075 | { | ||
1076 | DPRINTK("ENTER\n"); | ||
1077 | /* Do we have to save the colormap? */ | ||
1078 | if (fb_display[info->currcon].cmap.len) { | ||
1079 | fb_get_cmap(&fb_display[info->currcon].cmap, 1, Cyber_getcolreg, | ||
1080 | info); | ||
1081 | } | ||
1082 | |||
1083 | do_fb_set_var(&fb_display[con].var, 1); | ||
1084 | info->currcon = con; | ||
1085 | /* Install new colormap */ | ||
1086 | do_install_cmap(con, info); | ||
1087 | DPRINTK("EXIT\n"); | ||
1088 | return(0); | ||
1089 | } | ||
1090 | |||
1091 | |||
1092 | /* | ||
1093 | * Update the `var' structure (called by fbcon.c) | ||
1094 | * | ||
1095 | * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. | ||
1096 | * Since it's called by a kernel driver, no range checking is done. | ||
1097 | */ | ||
1098 | |||
1099 | static int Cyberfb_updatevar(int con, struct fb_info *info) | ||
1100 | { | ||
1101 | DPRINTK("Enter - Exit\n"); | ||
1102 | return(0); | ||
1103 | } | ||
1104 | |||
1105 | |||
1106 | /* | ||
1107 | * Get a Video Mode | ||
1108 | */ | ||
1109 | |||
1110 | static int __init get_video_mode(const char *name) | ||
1111 | { | ||
1112 | int i; | ||
1113 | |||
1114 | DPRINTK("ENTER\n"); | ||
1115 | for (i = 0; i < NUM_TOTAL_MODES; i++) { | ||
1116 | if (!strcmp(name, cyberfb_predefined[i].name)) { | ||
1117 | cyberfb_default = cyberfb_predefined[i].var; | ||
1118 | cyberfb_usermode = 1; | ||
1119 | DPRINTK("EXIT - Matched predefined mode\n"); | ||
1120 | return(i); | ||
1121 | } | ||
1122 | } | ||
1123 | return(0); | ||
1124 | } | ||
1125 | |||
1126 | |||
1127 | /* | ||
1128 | * Text console acceleration | ||
1129 | */ | ||
1130 | |||
1131 | #ifdef FBCON_HAS_CFB8 | ||
1132 | static void fbcon_cyber8_bmove(struct display *p, int sy, int sx, int dy, | ||
1133 | int dx, int height, int width) | ||
1134 | { | ||
1135 | DPRINTK("ENTER\n"); | ||
1136 | sx *= 8; dx *= 8; width *= 8; | ||
1137 | Cyber_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx, | ||
1138 | (u_short)(dy*fontheight(p)), (u_short)width, | ||
1139 | (u_short)(height*fontheight(p)), (u_short)S3_NEW); | ||
1140 | DPRINTK("EXIT\n"); | ||
1141 | } | ||
1142 | |||
1143 | static void fbcon_cyber8_clear(struct vc_data *conp, struct display *p, int sy, | ||
1144 | int sx, int height, int width) | ||
1145 | { | ||
1146 | unsigned char bg; | ||
1147 | |||
1148 | DPRINTK("ENTER\n"); | ||
1149 | sx *= 8; width *= 8; | ||
1150 | bg = attr_bgcol_ec(p,conp); | ||
1151 | Cyber_RectFill((u_short)sx, | ||
1152 | (u_short)(sy*fontheight(p)), | ||
1153 | (u_short)width, | ||
1154 | (u_short)(height*fontheight(p)), | ||
1155 | (u_short)S3_NEW, | ||
1156 | (u_short)bg); | ||
1157 | DPRINTK("EXIT\n"); | ||
1158 | } | ||
1159 | |||
1160 | static void fbcon_cyber8_putc(struct vc_data *conp, struct display *p, int c, | ||
1161 | int yy, int xx) | ||
1162 | { | ||
1163 | DPRINTK("ENTER\n"); | ||
1164 | Cyber_WaitBlit(); | ||
1165 | fbcon_cfb8_putc(conp, p, c, yy, xx); | ||
1166 | DPRINTK("EXIT\n"); | ||
1167 | } | ||
1168 | |||
1169 | static void fbcon_cyber8_putcs(struct vc_data *conp, struct display *p, | ||
1170 | const unsigned short *s, int count, | ||
1171 | int yy, int xx) | ||
1172 | { | ||
1173 | DPRINTK("ENTER\n"); | ||
1174 | Cyber_WaitBlit(); | ||
1175 | fbcon_cfb8_putcs(conp, p, s, count, yy, xx); | ||
1176 | DPRINTK("EXIT\n"); | ||
1177 | } | ||
1178 | |||
1179 | static void fbcon_cyber8_revc(struct display *p, int xx, int yy) | ||
1180 | { | ||
1181 | DPRINTK("ENTER\n"); | ||
1182 | Cyber_WaitBlit(); | ||
1183 | fbcon_cfb8_revc(p, xx, yy); | ||
1184 | DPRINTK("EXIT\n"); | ||
1185 | } | ||
1186 | |||
1187 | static struct display_switch fbcon_cyber8 = { | ||
1188 | .setup = fbcon_cfb8_setup, | ||
1189 | .bmove = fbcon_cyber8_bmove, | ||
1190 | .clear = fbcon_cyber8_clear, | ||
1191 | .putc = fbcon_cyber8_putc, | ||
1192 | .putcs = fbcon_cyber8_putcs, | ||
1193 | .revc = fbcon_cyber8_revc, | ||
1194 | .clear_margins =fbcon_cfb8_clear_margins, | ||
1195 | .fontwidthmask =FONTWIDTH(8) | ||
1196 | }; | ||
1197 | #endif | ||
1198 | |||
1199 | |||
1200 | #ifdef MODULE | ||
1201 | MODULE_LICENSE("GPL"); | ||
1202 | |||
1203 | int init_module(void) | ||
1204 | { | ||
1205 | return cyberfb_init(); | ||
1206 | } | ||
1207 | #endif /* MODULE */ | ||
1208 | |||
1209 | /* | ||
1210 | * | ||
1211 | * Low level initialization routines for the CyberVision64 graphics card | ||
1212 | * | ||
1213 | * Most of the following code is from cvision_core.c | ||
1214 | * | ||
1215 | */ | ||
1216 | |||
1217 | #define MAXPIXELCLOCK 135000000 /* safety */ | ||
1218 | |||
1219 | #ifdef CV_AGGRESSIVE_TIMING | ||
1220 | long cv64_memclk = 55000000; | ||
1221 | #else | ||
1222 | long cv64_memclk = 50000000; | ||
1223 | #endif | ||
1224 | |||
1225 | /*********************/ | ||
1226 | |||
1227 | static unsigned char clocks[]={ | ||
1228 | 0x13, 0x61, 0x6b, 0x6d, 0x51, 0x69, 0x54, 0x69, | ||
1229 | 0x4f, 0x68, 0x6b, 0x6b, 0x18, 0x61, 0x7b, 0x6c, | ||
1230 | 0x51, 0x67, 0x24, 0x62, 0x56, 0x67, 0x77, 0x6a, | ||
1231 | 0x1d, 0x61, 0x53, 0x66, 0x6b, 0x68, 0x79, 0x69, | ||
1232 | 0x7c, 0x69, 0x7f, 0x69, 0x22, 0x61, 0x54, 0x65, | ||
1233 | 0x56, 0x65, 0x58, 0x65, 0x67, 0x66, 0x41, 0x63, | ||
1234 | 0x27, 0x61, 0x13, 0x41, 0x37, 0x62, 0x6b, 0x4d, | ||
1235 | 0x23, 0x43, 0x51, 0x49, 0x79, 0x66, 0x54, 0x49, | ||
1236 | 0x7d, 0x66, 0x34, 0x56, 0x4f, 0x63, 0x1f, 0x42, | ||
1237 | 0x6b, 0x4b, 0x7e, 0x4d, 0x18, 0x41, 0x2a, 0x43, | ||
1238 | 0x7b, 0x4c, 0x74, 0x4b, 0x51, 0x47, 0x65, 0x49, | ||
1239 | 0x24, 0x42, 0x68, 0x49, 0x56, 0x47, 0x75, 0x4a, | ||
1240 | 0x77, 0x4a, 0x31, 0x43, 0x1d, 0x41, 0x71, 0x49, | ||
1241 | 0x53, 0x46, 0x29, 0x42, 0x6b, 0x48, 0x1f, 0x41, | ||
1242 | 0x79, 0x49, 0x6f, 0x48, 0x7c, 0x49, 0x38, 0x43, | ||
1243 | 0x7f, 0x49, 0x5d, 0x46, 0x22, 0x41, 0x53, 0x45, | ||
1244 | 0x54, 0x45, 0x55, 0x45, 0x56, 0x45, 0x57, 0x45, | ||
1245 | 0x58, 0x45, 0x25, 0x41, 0x67, 0x46, 0x5b, 0x45, | ||
1246 | 0x41, 0x43, 0x78, 0x47, 0x27, 0x41, 0x51, 0x44, | ||
1247 | 0x13, 0x21, 0x7d, 0x47, 0x37, 0x42, 0x71, 0x46, | ||
1248 | 0x6b, 0x2d, 0x14, 0x21, 0x23, 0x23, 0x7d, 0x2f, | ||
1249 | 0x51, 0x29, 0x61, 0x2b, 0x79, 0x46, 0x1d, 0x22, | ||
1250 | 0x54, 0x29, 0x45, 0x27, 0x7d, 0x46, 0x7f, 0x46, | ||
1251 | 0x4f, 0x43, 0x2f, 0x41, 0x1f, 0x22, 0x6a, 0x2b, | ||
1252 | 0x6b, 0x2b, 0x5b, 0x29, 0x7e, 0x2d, 0x65, 0x44, | ||
1253 | 0x18, 0x21, 0x5e, 0x29, 0x2a, 0x23, 0x45, 0x26, | ||
1254 | 0x7b, 0x2c, 0x19, 0x21, 0x74, 0x2b, 0x75, 0x2b, | ||
1255 | 0x51, 0x27, 0x3f, 0x25, 0x65, 0x29, 0x40, 0x25, | ||
1256 | 0x24, 0x22, 0x41, 0x25, 0x68, 0x29, 0x42, 0x25, | ||
1257 | 0x56, 0x27, 0x7e, 0x2b, 0x75, 0x2a, 0x1c, 0x21, | ||
1258 | 0x77, 0x2a, 0x4f, 0x26, 0x31, 0x23, 0x6f, 0x29, | ||
1259 | 0x1d, 0x21, 0x32, 0x23, 0x71, 0x29, 0x72, 0x29, | ||
1260 | 0x53, 0x26, 0x69, 0x28, 0x29, 0x22, 0x75, 0x29, | ||
1261 | 0x6b, 0x28, 0x1f, 0x21, 0x1f, 0x21, 0x6d, 0x28, | ||
1262 | 0x79, 0x29, 0x2b, 0x22, 0x6f, 0x28, 0x59, 0x26, | ||
1263 | 0x7c, 0x29, 0x7d, 0x29, 0x38, 0x23, 0x21, 0x21, | ||
1264 | 0x7f, 0x29, 0x39, 0x23, 0x5d, 0x26, 0x75, 0x28, | ||
1265 | 0x22, 0x21, 0x77, 0x28, 0x53, 0x25, 0x6c, 0x27, | ||
1266 | 0x54, 0x25, 0x61, 0x26, 0x55, 0x25, 0x30, 0x22, | ||
1267 | 0x56, 0x25, 0x63, 0x26, 0x57, 0x25, 0x71, 0x27, | ||
1268 | 0x58, 0x25, 0x7f, 0x28, 0x25, 0x21, 0x74, 0x27, | ||
1269 | 0x67, 0x26, 0x40, 0x23, 0x5b, 0x25, 0x26, 0x21, | ||
1270 | 0x41, 0x23, 0x34, 0x22, 0x78, 0x27, 0x6b, 0x26, | ||
1271 | 0x27, 0x21, 0x35, 0x22, 0x51, 0x24, 0x7b, 0x27, | ||
1272 | 0x13, 0x1, 0x13, 0x1, 0x7d, 0x27, 0x4c, 0x9, | ||
1273 | 0x37, 0x22, 0x5b, 0xb, 0x71, 0x26, 0x5c, 0xb, | ||
1274 | 0x6b, 0xd, 0x47, 0x23, 0x14, 0x1, 0x4f, 0x9, | ||
1275 | 0x23, 0x3, 0x75, 0x26, 0x7d, 0xf, 0x1c, 0x2, | ||
1276 | 0x51, 0x9, 0x59, 0x24, 0x61, 0xb, 0x69, 0x25, | ||
1277 | 0x79, 0x26, 0x34, 0x5, 0x1d, 0x2, 0x6b, 0x25, | ||
1278 | 0x54, 0x9, 0x35, 0x5, 0x45, 0x7, 0x6d, 0x25, | ||
1279 | 0x7d, 0x26, 0x16, 0x1, 0x7f, 0x26, 0x77, 0xd, | ||
1280 | 0x4f, 0x23, 0x78, 0xd, 0x2f, 0x21, 0x27, 0x3, | ||
1281 | 0x1f, 0x2, 0x59, 0x9, 0x6a, 0xb, 0x73, 0x25, | ||
1282 | 0x6b, 0xb, 0x63, 0x24, 0x5b, 0x9, 0x20, 0x2, | ||
1283 | 0x7e, 0xd, 0x4b, 0x7, 0x65, 0x24, 0x43, 0x22, | ||
1284 | 0x18, 0x1, 0x6f, 0xb, 0x5e, 0x9, 0x70, 0xb, | ||
1285 | 0x2a, 0x3, 0x33, 0x4, 0x45, 0x6, 0x60, 0x9, | ||
1286 | 0x7b, 0xc, 0x19, 0x1, 0x19, 0x1, 0x7d, 0xc, | ||
1287 | 0x74, 0xb, 0x50, 0x7, 0x75, 0xb, 0x63, 0x9, | ||
1288 | 0x51, 0x7, 0x23, 0x2, 0x3f, 0x5, 0x1a, 0x1, | ||
1289 | 0x65, 0x9, 0x2d, 0x3, 0x40, 0x5, 0x0, 0x0, | ||
1290 | }; | ||
1291 | |||
1292 | /* Console colors */ | ||
1293 | unsigned char cvconscolors[16][3] = { /* background, foreground, hilite */ | ||
1294 | /* R G B */ | ||
1295 | {0x30, 0x30, 0x30}, | ||
1296 | {0x00, 0x00, 0x00}, | ||
1297 | {0x80, 0x00, 0x00}, | ||
1298 | {0x00, 0x80, 0x00}, | ||
1299 | {0x00, 0x00, 0x80}, | ||
1300 | {0x80, 0x80, 0x00}, | ||
1301 | {0x00, 0x80, 0x80}, | ||
1302 | {0x80, 0x00, 0x80}, | ||
1303 | {0xff, 0xff, 0xff}, | ||
1304 | {0x40, 0x40, 0x40}, | ||
1305 | {0xff, 0x00, 0x00}, | ||
1306 | {0x00, 0xff, 0x00}, | ||
1307 | {0x00, 0x00, 0xff}, | ||
1308 | {0xff, 0xff, 0x00}, | ||
1309 | {0x00, 0xff, 0xff}, | ||
1310 | {0x00, 0x00, 0xff} | ||
1311 | }; | ||
1312 | |||
1313 | /* -------------------- Hardware specific routines ------------------------- */ | ||
1314 | |||
1315 | /* Read Attribute Controller Register=idx */ | ||
1316 | inline unsigned char RAttr (volatile unsigned char *regs, short idx) | ||
1317 | { | ||
1318 | wb_64 (regs, ACT_ADDRESS_W, idx); | ||
1319 | mb(); | ||
1320 | udelay(100); | ||
1321 | return (rb_64(regs, ACT_ADDRESS_R)); | ||
1322 | } | ||
1323 | |||
1324 | /* Read Sequencer Register=idx */ | ||
1325 | inline unsigned char RSeq (volatile unsigned char *regs, short idx) | ||
1326 | { | ||
1327 | wb_64 (regs, SEQ_ADDRESS, idx); | ||
1328 | mb(); | ||
1329 | return (rb_64(regs, SEQ_ADDRESS_R)); | ||
1330 | } | ||
1331 | |||
1332 | /* Read CRT Controller Register=idx */ | ||
1333 | inline unsigned char RCrt (volatile unsigned char *regs, short idx) | ||
1334 | { | ||
1335 | wb_64 (regs, CRT_ADDRESS, idx); | ||
1336 | mb(); | ||
1337 | return (rb_64(regs, CRT_ADDRESS_R)); | ||
1338 | } | ||
1339 | |||
1340 | /* Read Graphics Controller Register=idx */ | ||
1341 | inline unsigned char RGfx (volatile unsigned char *regs, short idx) | ||
1342 | { | ||
1343 | wb_64 (regs, GCT_ADDRESS, idx); | ||
1344 | mb(); | ||
1345 | return (rb_64(regs, GCT_ADDRESS_R)); | ||
1346 | } | ||
1347 | |||
1348 | /* | ||
1349 | * Special wakeup/passthrough registers on graphics boards | ||
1350 | */ | ||
1351 | |||
1352 | inline void cv64_write_port (unsigned short bits, | ||
1353 | volatile unsigned char *base) | ||
1354 | { | ||
1355 | volatile unsigned char *addr; | ||
1356 | static unsigned char cvportbits = 0; /* Mirror port bits here */ | ||
1357 | DPRINTK("ENTER\n"); | ||
1358 | |||
1359 | addr = base + 0x40001; | ||
1360 | if (bits & 0x8000) { | ||
1361 | cvportbits |= bits & 0xff; /* Set bits */ | ||
1362 | DPRINTK("Set bits: %04x\n", bits); | ||
1363 | } else { | ||
1364 | bits = bits & 0xff; | ||
1365 | bits = (~bits) & 0xff; | ||
1366 | cvportbits &= bits; /* Clear bits */ | ||
1367 | DPRINTK("Clear bits: %04x\n", bits); | ||
1368 | } | ||
1369 | |||
1370 | *addr = cvportbits; | ||
1371 | DPRINTK("EXIT\n"); | ||
1372 | } | ||
1373 | |||
1374 | /* | ||
1375 | * Monitor switch on CyberVision board | ||
1376 | * | ||
1377 | * toggle: | ||
1378 | * 0 = CyberVision Signal | ||
1379 | * 1 = Amiga Signal | ||
1380 | * board = board addr | ||
1381 | * | ||
1382 | */ | ||
1383 | inline void cvscreen (int toggle, volatile unsigned char *board) | ||
1384 | { | ||
1385 | DPRINTK("ENTER\n"); | ||
1386 | if (toggle == 1) { | ||
1387 | DPRINTK("Show Amiga video\n"); | ||
1388 | cv64_write_port (0x10, board); | ||
1389 | } else { | ||
1390 | DPRINTK("Show CyberVision video\n"); | ||
1391 | cv64_write_port (0x8010, board); | ||
1392 | } | ||
1393 | DPRINTK("EXIT\n"); | ||
1394 | } | ||
1395 | |||
1396 | /* Control screen display */ | ||
1397 | /* toggle: 0 = on, 1 = off */ | ||
1398 | /* board = registerbase */ | ||
1399 | inline void gfx_on_off(int toggle, volatile unsigned char *regs) | ||
1400 | { | ||
1401 | int r; | ||
1402 | DPRINTK("ENTER\n"); | ||
1403 | |||
1404 | toggle &= 0x1; | ||
1405 | toggle = toggle << 5; | ||
1406 | DPRINTK("Turn display %s\n", (toggle ? "off" : "on")); | ||
1407 | |||
1408 | r = (int) RSeq(regs, SEQ_ID_CLOCKING_MODE); | ||
1409 | r &= 0xdf; /* Set bit 5 to 0 */ | ||
1410 | |||
1411 | WSeq (regs, SEQ_ID_CLOCKING_MODE, r | toggle); | ||
1412 | DPRINTK("EXIT\n"); | ||
1413 | } | ||
1414 | |||
1415 | /* | ||
1416 | * Computes M, N, and R values from | ||
1417 | * given input frequency. It uses a table of | ||
1418 | * precomputed values, to keep CPU time low. | ||
1419 | * | ||
1420 | * The return value consist of: | ||
1421 | * lower byte: Bits 4-0: N Divider Value | ||
1422 | * Bits 5-6: R Value for e.g. SR10 or SR12 | ||
1423 | * higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13 | ||
1424 | */ | ||
1425 | static unsigned short cv64_compute_clock(unsigned long freq) | ||
1426 | { | ||
1427 | static unsigned char *mnr, *save; /* M, N + R vals */ | ||
1428 | unsigned long work_freq, r; | ||
1429 | unsigned short erg; | ||
1430 | long diff, d2; | ||
1431 | |||
1432 | DPRINTK("ENTER\n"); | ||
1433 | if (freq < 12500000 || freq > MAXPIXELCLOCK) { | ||
1434 | printk("CV64 driver: Illegal clock frequency %ld, using 25MHz\n", | ||
1435 | freq); | ||
1436 | freq = 25000000; | ||
1437 | } | ||
1438 | DPRINTK("Freq = %ld\n", freq); | ||
1439 | mnr = clocks; /* there the vals are stored */ | ||
1440 | d2 = 0x7fffffff; | ||
1441 | |||
1442 | while (*mnr) { /* mnr vals are 0-terminated */ | ||
1443 | work_freq = (0x37EE * (mnr[0] + 2)) / ((mnr[1] & 0x1F) + 2); | ||
1444 | |||
1445 | r = (mnr[1] >> 5) & 0x03; | ||
1446 | if (r != 0) { | ||
1447 | work_freq = work_freq >> r; /* r is the freq divider */ | ||
1448 | } | ||
1449 | |||
1450 | work_freq *= 0x3E8; /* 2nd part of OSC */ | ||
1451 | |||
1452 | diff = abs(freq - work_freq); | ||
1453 | |||
1454 | if (d2 >= diff) { | ||
1455 | d2 = diff; | ||
1456 | /* In save are the vals for minimal diff */ | ||
1457 | save = mnr; | ||
1458 | } | ||
1459 | mnr += 2; | ||
1460 | } | ||
1461 | erg = *((unsigned short *)save); | ||
1462 | |||
1463 | DPRINTK("EXIT\n"); | ||
1464 | return (erg); | ||
1465 | } | ||
1466 | |||
1467 | static int cv_has_4mb (volatile unsigned char *fb) | ||
1468 | { | ||
1469 | volatile unsigned long *tr, *tw; | ||
1470 | DPRINTK("ENTER\n"); | ||
1471 | |||
1472 | /* write patterns in memory and test if they can be read */ | ||
1473 | tw = (volatile unsigned long *) fb; | ||
1474 | tr = (volatile unsigned long *) (fb + 0x02000000); | ||
1475 | |||
1476 | *tw = 0x87654321; | ||
1477 | |||
1478 | if (*tr != 0x87654321) { | ||
1479 | DPRINTK("EXIT - <4MB\n"); | ||
1480 | return (0); | ||
1481 | } | ||
1482 | |||
1483 | /* upper memory region */ | ||
1484 | tw = (volatile unsigned long *) (fb + 0x00200000); | ||
1485 | tr = (volatile unsigned long *) (fb + 0x02200000); | ||
1486 | |||
1487 | *tw = 0x87654321; | ||
1488 | |||
1489 | if (*tr != 0x87654321) { | ||
1490 | DPRINTK("EXIT - <4MB\n"); | ||
1491 | return (0); | ||
1492 | } | ||
1493 | |||
1494 | *tw = 0xAAAAAAAA; | ||
1495 | |||
1496 | if (*tr != 0xAAAAAAAA) { | ||
1497 | DPRINTK("EXIT - <4MB\n"); | ||
1498 | return (0); | ||
1499 | } | ||
1500 | |||
1501 | *tw = 0x55555555; | ||
1502 | |||
1503 | if (*tr != 0x55555555) { | ||
1504 | DPRINTK("EXIT - <4MB\n"); | ||
1505 | return (0); | ||
1506 | } | ||
1507 | |||
1508 | DPRINTK("EXIT\n"); | ||
1509 | return (1); | ||
1510 | } | ||
1511 | |||
1512 | static void cv64_board_init (void) | ||
1513 | { | ||
1514 | volatile unsigned char *regs = CyberRegs; | ||
1515 | int i; | ||
1516 | unsigned int clockpar; | ||
1517 | unsigned char test; | ||
1518 | |||
1519 | DPRINTK("ENTER\n"); | ||
1520 | |||
1521 | /* | ||
1522 | * Special CyberVision 64 board operations | ||
1523 | */ | ||
1524 | /* Reset board */ | ||
1525 | for (i = 0; i < 6; i++) { | ||
1526 | cv64_write_port (0xff, CyberBase); | ||
1527 | } | ||
1528 | /* Return to operational mode */ | ||
1529 | cv64_write_port (0x8004, CyberBase); | ||
1530 | |||
1531 | /* | ||
1532 | * Generic (?) S3 chip wakeup | ||
1533 | */ | ||
1534 | /* Disable I/O & memory decoders, video in setup mode */ | ||
1535 | wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x10); | ||
1536 | /* Video responds to cmds, addrs & data */ | ||
1537 | wb_64 (regs, SREG_OPTION_SELECT, 0x1); | ||
1538 | /* Enable I/O & memory decoders, video in operational mode */ | ||
1539 | wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x8); | ||
1540 | /* VGA color emulation, enable cpu access to display mem */ | ||
1541 | wb_64 (regs, GREG_MISC_OUTPUT_W, 0x03); | ||
1542 | /* Unlock S3 VGA regs */ | ||
1543 | WCrt (regs, CRT_ID_REGISTER_LOCK_1, 0x48); | ||
1544 | /* Unlock system control & extension registers */ | ||
1545 | WCrt (regs, CRT_ID_REGISTER_LOCK_2, 0xA5); | ||
1546 | /* GRF - Enable interrupts */ | ||
1547 | /* Enable enhanced regs access, Ready cntl 0 wait states */ | ||
1548 | test = RCrt (regs, CRT_ID_SYSTEM_CONFIG); | ||
1549 | test = test | 0x01; /* enable enhanced register access */ | ||
1550 | test = test & 0xEF; /* clear bit 4, 0 wait state */ | ||
1551 | WCrt (regs, CRT_ID_SYSTEM_CONFIG, test); | ||
1552 | /* | ||
1553 | * bit 0=1: Enable enhaced mode functions | ||
1554 | * bit 2=0: Enhanced mode 8+ bits/pixel | ||
1555 | * bit 4=1: Enable linear addressing | ||
1556 | * bit 5=1: Enable MMIO | ||
1557 | */ | ||
1558 | wb_64 (regs, ECR_ADV_FUNC_CNTL, 0x31); | ||
1559 | /* | ||
1560 | * bit 0=1: Color emulation | ||
1561 | * bit 1=1: Enable CPU access to display memory | ||
1562 | * bit 5=1: Select high 64K memory page | ||
1563 | */ | ||
1564 | /* GRF - 0xE3 */ | ||
1565 | wb_64 (regs, GREG_MISC_OUTPUT_W, 0x23); | ||
1566 | |||
1567 | /* Cpu base addr */ | ||
1568 | WCrt (regs, CRT_ID_EXT_SYS_CNTL_4, 0x0); | ||
1569 | |||
1570 | /* Reset. This does nothing on Trio, but standard VGA practice */ | ||
1571 | /* WSeq (CyberRegs, SEQ_ID_RESET, 0x03); */ | ||
1572 | /* Character clocks 8 dots wide */ | ||
1573 | WSeq (regs, SEQ_ID_CLOCKING_MODE, 0x01); | ||
1574 | /* Enable cpu write to all color planes */ | ||
1575 | WSeq (regs, SEQ_ID_MAP_MASK, 0x0F); | ||
1576 | /* Font table in 1st 8k of plane 2, font A=B disables swtich */ | ||
1577 | WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x0); | ||
1578 | /* Allow mem access to 256kb */ | ||
1579 | WSeq (regs, SEQ_ID_MEMORY_MODE, 0x2); | ||
1580 | /* Unlock S3 extensions to VGA Sequencer regs */ | ||
1581 | WSeq (regs, SEQ_ID_UNLOCK_EXT, 0x6); | ||
1582 | |||
1583 | /* Enable 4MB fast page mode */ | ||
1584 | test = RSeq (regs, SEQ_ID_BUS_REQ_CNTL); | ||
1585 | test = test | 1 << 6; | ||
1586 | WSeq (regs, SEQ_ID_BUS_REQ_CNTL, test); | ||
1587 | |||
1588 | /* Faster LUT write: 1 DCLK LUT write cycle, RAMDAC clk doubled */ | ||
1589 | WSeq (regs, SEQ_ID_RAMDAC_CNTL, 0xC0); | ||
1590 | |||
1591 | /* Clear immediate clock load bit */ | ||
1592 | test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2); | ||
1593 | test = test & 0xDF; | ||
1594 | /* If > 55MHz, enable 2 cycle memory write */ | ||
1595 | if (cv64_memclk >= 55000000) { | ||
1596 | test |= 0x80; | ||
1597 | } | ||
1598 | WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test); | ||
1599 | |||
1600 | /* Set MCLK value */ | ||
1601 | clockpar = cv64_compute_clock (cv64_memclk); | ||
1602 | test = (clockpar & 0xFF00) >> 8; | ||
1603 | WSeq (regs, SEQ_ID_MCLK_HI, test); | ||
1604 | test = clockpar & 0xFF; | ||
1605 | WSeq (regs, SEQ_ID_MCLK_LO, test); | ||
1606 | |||
1607 | /* Chip rev specific: Not in my Trio manual!!! */ | ||
1608 | if (RCrt (regs, CRT_ID_REVISION) == 0x10) | ||
1609 | WSeq (regs, SEQ_ID_MORE_MAGIC, test); | ||
1610 | |||
1611 | /* We now load an 25 MHz, 31kHz, 640x480 standard VGA Mode. */ | ||
1612 | |||
1613 | /* Set DCLK value */ | ||
1614 | WSeq (regs, SEQ_ID_DCLK_HI, 0x13); | ||
1615 | WSeq (regs, SEQ_ID_DCLK_LO, 0x41); | ||
1616 | |||
1617 | /* Load DCLK (and MCLK?) immediately */ | ||
1618 | test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2); | ||
1619 | test = test | 0x22; | ||
1620 | WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test); | ||
1621 | |||
1622 | /* Enable loading of DCLK */ | ||
1623 | test = rb_64(regs, GREG_MISC_OUTPUT_R); | ||
1624 | test = test | 0x0C; | ||
1625 | wb_64 (regs, GREG_MISC_OUTPUT_W, test); | ||
1626 | |||
1627 | /* Turn off immediate xCLK load */ | ||
1628 | WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, 0x2); | ||
1629 | |||
1630 | /* Horizontal character clock counts */ | ||
1631 | /* 8 LSB of 9 bits = total line - 5 */ | ||
1632 | WCrt (regs, CRT_ID_HOR_TOTAL, 0x5F); | ||
1633 | /* Active display line */ | ||
1634 | WCrt (regs, CRT_ID_HOR_DISP_ENA_END, 0x4F); | ||
1635 | /* Blank assertion start */ | ||
1636 | WCrt (regs, CRT_ID_START_HOR_BLANK, 0x50); | ||
1637 | /* Blank assertion end */ | ||
1638 | WCrt (regs, CRT_ID_END_HOR_BLANK, 0x82); | ||
1639 | /* HSYNC assertion start */ | ||
1640 | WCrt (regs, CRT_ID_START_HOR_RETR, 0x54); | ||
1641 | /* HSYNC assertion end */ | ||
1642 | WCrt (regs, CRT_ID_END_HOR_RETR, 0x80); | ||
1643 | WCrt (regs, CRT_ID_VER_TOTAL, 0xBF); | ||
1644 | WCrt (regs, CRT_ID_OVERFLOW, 0x1F); | ||
1645 | WCrt (regs, CRT_ID_PRESET_ROW_SCAN, 0x0); | ||
1646 | WCrt (regs, CRT_ID_MAX_SCAN_LINE, 0x40); | ||
1647 | WCrt (regs, CRT_ID_CURSOR_START, 0x00); | ||
1648 | WCrt (regs, CRT_ID_CURSOR_END, 0x00); | ||
1649 | WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00); | ||
1650 | WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00); | ||
1651 | WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00); | ||
1652 | WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00); | ||
1653 | WCrt (regs, CRT_ID_START_VER_RETR, 0x9C); | ||
1654 | WCrt (regs, CRT_ID_END_VER_RETR, 0x0E); | ||
1655 | WCrt (regs, CRT_ID_VER_DISP_ENA_END, 0x8F); | ||
1656 | WCrt (regs, CRT_ID_SCREEN_OFFSET, 0x50); | ||
1657 | WCrt (regs, CRT_ID_UNDERLINE_LOC, 0x00); | ||
1658 | WCrt (regs, CRT_ID_START_VER_BLANK, 0x96); | ||
1659 | WCrt (regs, CRT_ID_END_VER_BLANK, 0xB9); | ||
1660 | WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3); | ||
1661 | WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF); | ||
1662 | WCrt (regs, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */ | ||
1663 | WCrt (regs, CRT_ID_MISC_1, 0x35); | ||
1664 | WCrt (regs, CRT_ID_DISPLAY_FIFO, 0x5A); | ||
1665 | WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, 0x70); | ||
1666 | WCrt (regs, CRT_ID_LAW_POS_LO, 0x40); | ||
1667 | WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, 0xFF); | ||
1668 | |||
1669 | WGfx (regs, GCT_ID_SET_RESET, 0x0); | ||
1670 | WGfx (regs, GCT_ID_ENABLE_SET_RESET, 0x0); | ||
1671 | WGfx (regs, GCT_ID_COLOR_COMPARE, 0x0); | ||
1672 | WGfx (regs, GCT_ID_DATA_ROTATE, 0x0); | ||
1673 | WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x0); | ||
1674 | WGfx (regs, GCT_ID_GRAPHICS_MODE, 0x40); | ||
1675 | WGfx (regs, GCT_ID_MISC, 0x01); | ||
1676 | WGfx (regs, GCT_ID_COLOR_XCARE, 0x0F); | ||
1677 | WGfx (regs, GCT_ID_BITMASK, 0xFF); | ||
1678 | |||
1679 | /* Colors for text mode */ | ||
1680 | for (i = 0; i < 0xf; i++) | ||
1681 | WAttr (regs, i, i); | ||
1682 | |||
1683 | WAttr (regs, ACT_ID_ATTR_MODE_CNTL, 0x41); | ||
1684 | WAttr (regs, ACT_ID_OVERSCAN_COLOR, 0x01); | ||
1685 | WAttr (regs, ACT_ID_COLOR_PLANE_ENA, 0x0F); | ||
1686 | WAttr (regs, ACT_ID_HOR_PEL_PANNING, 0x0); | ||
1687 | WAttr (regs, ACT_ID_COLOR_SELECT, 0x0); | ||
1688 | |||
1689 | wb_64 (regs, VDAC_MASK, 0xFF); | ||
1690 | |||
1691 | *((unsigned long *) (regs + ECR_FRGD_COLOR)) = 0xFF; | ||
1692 | *((unsigned long *) (regs + ECR_BKGD_COLOR)) = 0; | ||
1693 | |||
1694 | /* Colors initially set to grayscale */ | ||
1695 | |||
1696 | wb_64 (regs, VDAC_ADDRESS_W, 0); | ||
1697 | for (i = 255; i >= 0; i--) { | ||
1698 | wb_64(regs, VDAC_DATA, i); | ||
1699 | wb_64(regs, VDAC_DATA, i); | ||
1700 | wb_64(regs, VDAC_DATA, i); | ||
1701 | } | ||
1702 | |||
1703 | /* GFx hardware cursor off */ | ||
1704 | WCrt (regs, CRT_ID_HWGC_MODE, 0x00); | ||
1705 | |||
1706 | /* Set first to 4MB, so test will work */ | ||
1707 | WCrt (regs, CRT_ID_LAW_CNTL, 0x13); | ||
1708 | /* Find "correct" size of fbmem of Z3 board */ | ||
1709 | if (cv_has_4mb (CyberMem)) { | ||
1710 | CyberSize = 1024 * 1024 * 4; | ||
1711 | WCrt (regs, CRT_ID_LAW_CNTL, 0x13); | ||
1712 | DPRINTK("4MB board\n"); | ||
1713 | } else { | ||
1714 | CyberSize = 1024 * 1024 * 2; | ||
1715 | WCrt (regs, CRT_ID_LAW_CNTL, 0x12); | ||
1716 | DPRINTK("2MB board\n"); | ||
1717 | } | ||
1718 | |||
1719 | /* Initialize graphics engine */ | ||
1720 | Cyber_WaitBlit(); | ||
1721 | vgaw16 (regs, ECR_FRGD_MIX, 0x27); | ||
1722 | vgaw16 (regs, ECR_BKGD_MIX, 0x07); | ||
1723 | vgaw16 (regs, ECR_READ_REG_DATA, 0x1000); | ||
1724 | udelay(200); | ||
1725 | vgaw16 (regs, ECR_READ_REG_DATA, 0x2000); | ||
1726 | Cyber_WaitBlit(); | ||
1727 | vgaw16 (regs, ECR_READ_REG_DATA, 0x3FFF); | ||
1728 | Cyber_WaitBlit(); | ||
1729 | udelay(200); | ||
1730 | vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF); | ||
1731 | Cyber_WaitBlit(); | ||
1732 | vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, ~0); | ||
1733 | Cyber_WaitBlit(); | ||
1734 | vgaw16 (regs, ECR_READ_REG_DATA, 0xE000); | ||
1735 | vgaw16 (regs, ECR_CURRENT_Y_POS2, 0x00); | ||
1736 | vgaw16 (regs, ECR_CURRENT_X_POS2, 0x00); | ||
1737 | vgaw16 (regs, ECR_READ_REG_DATA, 0xA000); | ||
1738 | vgaw16 (regs, ECR_DEST_Y__AX_STEP, 0x00); | ||
1739 | vgaw16 (regs, ECR_DEST_Y2__AX_STEP2, 0x00); | ||
1740 | vgaw16 (regs, ECR_DEST_X__DIA_STEP, 0x00); | ||
1741 | vgaw16 (regs, ECR_DEST_X2__DIA_STEP2, 0x00); | ||
1742 | vgaw16 (regs, ECR_SHORT_STROKE, 0x00); | ||
1743 | vgaw16 (regs, ECR_DRAW_CMD, 0x01); | ||
1744 | |||
1745 | Cyber_WaitBlit(); | ||
1746 | |||
1747 | vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF); | ||
1748 | vgaw16 (regs, ECR_BKGD_COLOR, 0x01); | ||
1749 | vgaw16 (regs, ECR_FRGD_COLOR, 0x00); | ||
1750 | |||
1751 | |||
1752 | /* Enable video display (set bit 5) */ | ||
1753 | /* ARB - Would also seem to write to AR13. | ||
1754 | * May want to use parts of WAttr to set JUST bit 5 | ||
1755 | */ | ||
1756 | WAttr (regs, 0x33, 0); | ||
1757 | |||
1758 | /* GRF - function code ended here */ | ||
1759 | |||
1760 | /* Turn gfx on again */ | ||
1761 | gfx_on_off (0, regs); | ||
1762 | |||
1763 | /* Pass-through */ | ||
1764 | cvscreen (0, CyberBase); | ||
1765 | |||
1766 | DPRINTK("EXIT\n"); | ||
1767 | } | ||
1768 | |||
1769 | static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode) | ||
1770 | { | ||
1771 | volatile unsigned char *regs = CyberRegs; | ||
1772 | int fx, fy; | ||
1773 | unsigned short mnr; | ||
1774 | unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS, VSE, VT; | ||
1775 | char LACE, DBLSCAN, TEXT, CONSOLE; | ||
1776 | int cr50, sr15, sr18, clock_mode, test; | ||
1777 | int m, n; | ||
1778 | int tfillm, temptym; | ||
1779 | int hmul; | ||
1780 | |||
1781 | /* ---------------- */ | ||
1782 | int xres, hfront, hsync, hback; | ||
1783 | int yres, vfront, vsync, vback; | ||
1784 | int bpp; | ||
1785 | #if 0 | ||
1786 | float freq_f; | ||
1787 | #endif | ||
1788 | long freq; | ||
1789 | /* ---------------- */ | ||
1790 | |||
1791 | DPRINTK("ENTER\n"); | ||
1792 | TEXT = 0; /* if depth == 4 */ | ||
1793 | CONSOLE = 0; /* mode num == 255 (console) */ | ||
1794 | fx = fy = 8; /* force 8x8 font */ | ||
1795 | |||
1796 | /* GRF - Disable interrupts */ | ||
1797 | |||
1798 | gfx_on_off (1, regs); | ||
1799 | |||
1800 | switch (video_mode->bits_per_pixel) { | ||
1801 | case 15: | ||
1802 | case 16: | ||
1803 | hmul = 2; | ||
1804 | break; | ||
1805 | |||
1806 | default: | ||
1807 | hmul = 1; | ||
1808 | break; | ||
1809 | } | ||
1810 | |||
1811 | bpp = video_mode->bits_per_pixel; | ||
1812 | xres = video_mode->xres; | ||
1813 | hfront = video_mode->right_margin; | ||
1814 | hsync = video_mode->hsync_len; | ||
1815 | hback = video_mode->left_margin; | ||
1816 | |||
1817 | LACE = 0; | ||
1818 | DBLSCAN = 0; | ||
1819 | |||
1820 | if (video_mode->vmode & FB_VMODE_DOUBLE) { | ||
1821 | yres = video_mode->yres * 2; | ||
1822 | vfront = video_mode->lower_margin * 2; | ||
1823 | vsync = video_mode->vsync_len * 2; | ||
1824 | vback = video_mode->upper_margin * 2; | ||
1825 | DBLSCAN = 1; | ||
1826 | } else if (video_mode->vmode & FB_VMODE_INTERLACED) { | ||
1827 | yres = (video_mode->yres + 1) / 2; | ||
1828 | vfront = (video_mode->lower_margin + 1) / 2; | ||
1829 | vsync = (video_mode->vsync_len + 1) / 2; | ||
1830 | vback = (video_mode->upper_margin + 1) / 2; | ||
1831 | LACE = 1; | ||
1832 | } else { | ||
1833 | yres = video_mode->yres; | ||
1834 | vfront = video_mode->lower_margin; | ||
1835 | vsync = video_mode->vsync_len; | ||
1836 | vback = video_mode->upper_margin; | ||
1837 | } | ||
1838 | |||
1839 | /* ARB Dropping custom setup method from cvision.c */ | ||
1840 | #if 0 | ||
1841 | if (cvision_custom_mode) { | ||
1842 | HBS = hbs / 8 * hmul; | ||
1843 | HBE = hbe / 8 * hmul; | ||
1844 | HSS = hss / 8 * hmul; | ||
1845 | HSE = hse / 8 * hmul; | ||
1846 | HT = ht / 8 * hmul - 5; | ||
1847 | |||
1848 | VBS = vbs - 1; | ||
1849 | VSS = vss; | ||
1850 | VSE = vse; | ||
1851 | VBE = vbe; | ||
1852 | VT = vt - 2; | ||
1853 | } else { | ||
1854 | #else | ||
1855 | { | ||
1856 | #endif | ||
1857 | HBS = hmul * (xres / 8); | ||
1858 | HBE = hmul * ((xres/8) + (hfront/8) + (hsync/8) + (hback/8) - 2); | ||
1859 | HSS = hmul * ((xres/8) + (hfront/8) + 2); | ||
1860 | HSE = hmul * ((xres/8) + (hfront/8) + (hsync/8) + 1); | ||
1861 | HT = hmul * ((xres/8) + (hfront/8) + (hsync/8) + (hback/8)); | ||
1862 | |||
1863 | VBS = yres; | ||
1864 | VBE = yres + vfront + vsync + vback - 2; | ||
1865 | VSS = yres + vfront - 1; | ||
1866 | VSE = yres + vfront + vsync - 1; | ||
1867 | VT = yres + vfront + vsync + vback - 2; | ||
1868 | } | ||
1869 | |||
1870 | wb_64 (regs, ECR_ADV_FUNC_CNTL, (TEXT ? 0x00 : 0x31)); | ||
1871 | |||
1872 | if (TEXT) | ||
1873 | HDE = ((video_mode->xres + fx - 1) / fx) - 1; | ||
1874 | else | ||
1875 | HDE = (video_mode->xres + 3) * hmul / 8 - 1; | ||
1876 | |||
1877 | VDE = video_mode->yres - 1; | ||
1878 | |||
1879 | WCrt (regs, CRT_ID_HWGC_MODE, 0x00); | ||
1880 | WCrt (regs, CRT_ID_EXT_DAC_CNTL, 0x00); | ||
1881 | |||
1882 | WSeq (regs, SEQ_ID_MEMORY_MODE, | ||
1883 | (TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x0e); | ||
1884 | WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x00); | ||
1885 | WSeq (regs, SEQ_ID_MAP_MASK, | ||
1886 | (video_mode->bits_per_pixel == 1) ? 0x01 : 0xFF); | ||
1887 | WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x00); | ||
1888 | |||
1889 | /* cv64_compute_clock accepts arguments in Hz */ | ||
1890 | /* pixclock is in ps ... convert to Hz */ | ||
1891 | |||
1892 | #if 0 | ||
1893 | freq_f = (1.0 / (float) video_mode->pixclock) * 1000000000; | ||
1894 | freq = ((long) freq_f) * 1000; | ||
1895 | #else | ||
1896 | /* freq = (long) ((long long)1000000000000 / (long long) video_mode->pixclock); | ||
1897 | */ | ||
1898 | freq = (1000000000 / video_mode->pixclock) * 1000; | ||
1899 | #endif | ||
1900 | |||
1901 | mnr = cv64_compute_clock (freq); | ||
1902 | WSeq (regs, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8)); | ||
1903 | WSeq (regs, SEQ_ID_DCLK_LO, (mnr & 0xFF)); | ||
1904 | |||
1905 | /* Load display parameters into board */ | ||
1906 | WCrt (regs, CRT_ID_EXT_HOR_OVF, | ||
1907 | ((HT & 0x100) ? 0x01 : 0x00) | | ||
1908 | ((HDE & 0x100) ? 0x02 : 0x00) | | ||
1909 | ((HBS & 0x100) ? 0x04 : 0x00) | | ||
1910 | /* ((HBE & 0x40) ? 0x08 : 0x00) | */ | ||
1911 | ((HSS & 0x100) ? 0x10 : 0x00) | | ||
1912 | /* ((HSE & 0x20) ? 0x20 : 0x00) | */ | ||
1913 | (((HT-5) & 0x100) ? 0x40 : 0x00) | ||
1914 | ); | ||
1915 | |||
1916 | WCrt (regs, CRT_ID_EXT_VER_OVF, | ||
1917 | 0x40 | | ||
1918 | ((VT & 0x400) ? 0x01 : 0x00) | | ||
1919 | ((VDE & 0x400) ? 0x02 : 0x00) | | ||
1920 | ((VBS & 0x400) ? 0x04 : 0x00) | | ||
1921 | ((VSS & 0x400) ? 0x10 : 0x00) | ||
1922 | ); | ||
1923 | |||
1924 | WCrt (regs, CRT_ID_HOR_TOTAL, HT); | ||
1925 | WCrt (regs, CRT_ID_DISPLAY_FIFO, HT - 5); | ||
1926 | WCrt (regs, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE)); | ||
1927 | WCrt (regs, CRT_ID_START_HOR_BLANK, HBS); | ||
1928 | WCrt (regs, CRT_ID_END_HOR_BLANK, ((HBE & 0x1F) | 0x80)); | ||
1929 | WCrt (regs, CRT_ID_START_HOR_RETR, HSS); | ||
1930 | WCrt (regs, CRT_ID_END_HOR_RETR, | ||
1931 | (HSE & 0x1F) | | ||
1932 | ((HBE & 0x20) ? 0x80 : 0x00) | ||
1933 | ); | ||
1934 | WCrt (regs, CRT_ID_VER_TOTAL, VT); | ||
1935 | WCrt (regs, CRT_ID_OVERFLOW, | ||
1936 | 0x10 | | ||
1937 | ((VT & 0x100) ? 0x01 : 0x00) | | ||
1938 | ((VDE & 0x100) ? 0x02 : 0x00) | | ||
1939 | ((VSS & 0x100) ? 0x04 : 0x00) | | ||
1940 | ((VBS & 0x100) ? 0x08 : 0x00) | | ||
1941 | ((VT & 0x200) ? 0x20 : 0x00) | | ||
1942 | ((VDE & 0x200) ? 0x40 : 0x00) | | ||
1943 | ((VSS & 0x200) ? 0x80 : 0x00) | ||
1944 | ); | ||
1945 | WCrt (regs, CRT_ID_MAX_SCAN_LINE, | ||
1946 | 0x40 | | ||
1947 | (DBLSCAN ? 0x80 : 0x00) | | ||
1948 | ((VBS & 0x200) ? 0x20 : 0x00) | | ||
1949 | (TEXT ? ((fy - 1) & 0x1F) : 0x00) | ||
1950 | ); | ||
1951 | |||
1952 | WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3); | ||
1953 | |||
1954 | /* Text cursor */ | ||
1955 | |||
1956 | if (TEXT) { | ||
1957 | #if 1 | ||
1958 | WCrt (regs, CRT_ID_CURSOR_START, (fy & 0x1f) - 2); | ||
1959 | WCrt (regs, CRT_ID_CURSOR_END, (fy & 0x1F) - 1); | ||
1960 | #else | ||
1961 | WCrt (regs, CRT_ID_CURSOR_START, 0x00); | ||
1962 | WCrt (regs, CRT_ID_CURSOR_END, fy & 0x1F); | ||
1963 | #endif | ||
1964 | WCrt (regs, CRT_ID_UNDERLINE_LOC, (fy - 1) & 0x1F); | ||
1965 | WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00); | ||
1966 | WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00); | ||
1967 | } | ||
1968 | |||
1969 | WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00); | ||
1970 | WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00); | ||
1971 | WCrt (regs, CRT_ID_START_VER_RETR, VSS); | ||
1972 | WCrt (regs, CRT_ID_END_VER_RETR, (VSE & 0x0F)); | ||
1973 | WCrt (regs, CRT_ID_VER_DISP_ENA_END, VDE); | ||
1974 | WCrt (regs, CRT_ID_START_VER_BLANK, VBS); | ||
1975 | WCrt (regs, CRT_ID_END_VER_BLANK, VBE); | ||
1976 | WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF); | ||
1977 | WCrt (regs, CRT_ID_LACE_RETR_START, HT / 2); | ||
1978 | WCrt (regs, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00)); | ||
1979 | WGfx (regs, GCT_ID_GRAPHICS_MODE, | ||
1980 | ((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x00 : 0x40)); | ||
1981 | WGfx (regs, GCT_ID_MISC, (TEXT ? 0x04 : 0x01)); | ||
1982 | WSeq (regs, SEQ_ID_MEMORY_MODE, | ||
1983 | ((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x02)); | ||
1984 | |||
1985 | wb_64 (regs, VDAC_MASK, 0xFF); | ||
1986 | |||
1987 | /* Blank border */ | ||
1988 | test = RCrt (regs, CRT_ID_BACKWAD_COMP_2); | ||
1989 | WCrt (regs, CRT_ID_BACKWAD_COMP_2, (test | 0x20)); | ||
1990 | |||
1991 | sr15 = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2); | ||
1992 | sr15 &= 0xEF; | ||
1993 | sr18 = RSeq (regs, SEQ_ID_RAMDAC_CNTL); | ||
1994 | sr18 &= 0x7F; | ||
1995 | clock_mode = 0x00; | ||
1996 | cr50 = 0x00; | ||
1997 | |||
1998 | test = RCrt (regs, CRT_ID_EXT_MISC_CNTL_2); | ||
1999 | test &= 0xD; | ||
2000 | |||
2001 | /* Clear roxxler byte-swapping... */ | ||
2002 | cv64_write_port (0x0040, CyberBase); | ||
2003 | cv64_write_port (0x0020, CyberBase); | ||
2004 | |||
2005 | switch (video_mode->bits_per_pixel) { | ||
2006 | case 1: | ||
2007 | case 4: /* text */ | ||
2008 | HDE = video_mode->xres / 16; | ||
2009 | break; | ||
2010 | |||
2011 | case 8: | ||
2012 | if (freq > 80000000) { | ||
2013 | clock_mode = 0x10 | 0x02; | ||
2014 | sr15 |= 0x10; | ||
2015 | sr18 |= 0x80; | ||
2016 | } | ||
2017 | HDE = video_mode->xres / 8; | ||
2018 | cr50 |= 0x00; | ||
2019 | break; | ||
2020 | |||
2021 | case 15: | ||
2022 | cv64_write_port (0x8020, CyberBase); | ||
2023 | clock_mode = 0x30; | ||
2024 | HDE = video_mode->xres / 4; | ||
2025 | cr50 |= 0x10; | ||
2026 | break; | ||
2027 | |||
2028 | case 16: | ||
2029 | cv64_write_port (0x8020, CyberBase); | ||
2030 | clock_mode = 0x50; | ||
2031 | HDE = video_mode->xres / 4; | ||
2032 | cr50 |= 0x10; | ||
2033 | break; | ||
2034 | |||
2035 | case 24: | ||
2036 | case 32: | ||
2037 | cv64_write_port (0x8040, CyberBase); | ||
2038 | clock_mode = 0xD0; | ||
2039 | HDE = video_mode->xres / 2; | ||
2040 | cr50 |= 0x30; | ||
2041 | break; | ||
2042 | } | ||
2043 | |||
2044 | WCrt (regs, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test); | ||
2045 | WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, sr15); | ||
2046 | WSeq (regs, SEQ_ID_RAMDAC_CNTL, sr18); | ||
2047 | WCrt (regs, CRT_ID_SCREEN_OFFSET, HDE); | ||
2048 | |||
2049 | WCrt (regs, CRT_ID_MISC_1, (TEXT ? 0x05 : 0x35)); | ||
2050 | |||
2051 | test = RCrt (regs, CRT_ID_EXT_SYS_CNTL_2); | ||
2052 | test &= ~0x30; | ||
2053 | test |= (HDE >> 4) & 0x30; | ||
2054 | WCrt (regs, CRT_ID_EXT_SYS_CNTL_2, test); | ||
2055 | |||
2056 | /* Set up graphics engine */ | ||
2057 | switch (video_mode->xres) { | ||
2058 | case 1024: | ||
2059 | cr50 |= 0x00; | ||
2060 | break; | ||
2061 | |||
2062 | case 640: | ||
2063 | cr50 |= 0x40; | ||
2064 | break; | ||
2065 | |||
2066 | case 800: | ||
2067 | cr50 |= 0x80; | ||
2068 | break; | ||
2069 | |||
2070 | case 1280: | ||
2071 | cr50 |= 0xC0; | ||
2072 | break; | ||
2073 | |||
2074 | case 1152: | ||
2075 | cr50 |= 0x01; | ||
2076 | break; | ||
2077 | |||
2078 | case 1600: | ||
2079 | cr50 |= 0x81; | ||
2080 | break; | ||
2081 | |||
2082 | default: /* XXX */ | ||
2083 | break; | ||
2084 | } | ||
2085 | |||
2086 | WCrt (regs, CRT_ID_EXT_SYS_CNTL_1, cr50); | ||
2087 | |||
2088 | udelay(100); | ||
2089 | WAttr (regs, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x08 : 0x41)); | ||
2090 | udelay(100); | ||
2091 | WAttr (regs, ACT_ID_COLOR_PLANE_ENA, | ||
2092 | (video_mode->bits_per_pixel == 1) ? 0x01 : 0x0F); | ||
2093 | udelay(100); | ||
2094 | |||
2095 | tfillm = (96 * (cv64_memclk / 1000)) / 240000; | ||
2096 | |||
2097 | switch (video_mode->bits_per_pixel) { | ||
2098 | case 32: | ||
2099 | case 24: | ||
2100 | temptym = (24 * (cv64_memclk / 1000)) / (freq / 1000); | ||
2101 | break; | ||
2102 | case 15: | ||
2103 | case 16: | ||
2104 | temptym = (48 * (cv64_memclk / 1000)) / (freq / 1000); | ||
2105 | break; | ||
2106 | case 4: | ||
2107 | temptym = (192 * (cv64_memclk / 1000)) / (freq / 1000); | ||
2108 | break; | ||
2109 | default: | ||
2110 | temptym = (96 * (cv64_memclk / 1000)) / (freq / 1000); | ||
2111 | break; | ||
2112 | } | ||
2113 | |||
2114 | m = (temptym - tfillm - 9) / 2; | ||
2115 | if (m < 0) | ||
2116 | m = 0; | ||
2117 | m = (m & 0x1F) << 3; | ||
2118 | if (m < 0x18) | ||
2119 | m = 0x18; | ||
2120 | n = 0xFF; | ||
2121 | |||
2122 | WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, m); | ||
2123 | WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, n); | ||
2124 | udelay(10); | ||
2125 | |||
2126 | /* Text initialization */ | ||
2127 | |||
2128 | if (TEXT) { | ||
2129 | /* Do text initialization here ! */ | ||
2130 | } | ||
2131 | |||
2132 | if (CONSOLE) { | ||
2133 | int i; | ||
2134 | wb_64 (regs, VDAC_ADDRESS_W, 0); | ||
2135 | for (i = 0; i < 4; i++) { | ||
2136 | wb_64 (regs, VDAC_DATA, cvconscolors [i][0]); | ||
2137 | wb_64 (regs, VDAC_DATA, cvconscolors [i][1]); | ||
2138 | wb_64 (regs, VDAC_DATA, cvconscolors [i][2]); | ||
2139 | } | ||
2140 | } | ||
2141 | |||
2142 | WAttr (regs, 0x33, 0); | ||
2143 | |||
2144 | /* Turn gfx on again */ | ||
2145 | gfx_on_off (0, (volatile unsigned char *) regs); | ||
2146 | |||
2147 | /* Pass-through */ | ||
2148 | cvscreen (0, CyberBase); | ||
2149 | |||
2150 | DPRINTK("EXIT\n"); | ||
2151 | } | ||
2152 | |||
2153 | void cvision_bitblt (u_short sx, u_short sy, u_short dx, u_short dy, | ||
2154 | u_short w, u_short h) | ||
2155 | { | ||
2156 | volatile unsigned char *regs = CyberRegs; | ||
2157 | unsigned short drawdir = 0; | ||
2158 | |||
2159 | DPRINTK("ENTER\n"); | ||
2160 | if (sx > dx) { | ||
2161 | drawdir |= 1 << 5; | ||
2162 | } else { | ||
2163 | sx += w - 1; | ||
2164 | dx += w - 1; | ||
2165 | } | ||
2166 | |||
2167 | if (sy > dy) { | ||
2168 | drawdir |= 1 << 7; | ||
2169 | } else { | ||
2170 | sy += h - 1; | ||
2171 | dy += h - 1; | ||
2172 | } | ||
2173 | |||
2174 | Cyber_WaitBlit(); | ||
2175 | vgaw16 (regs, ECR_READ_REG_DATA, 0xA000); | ||
2176 | vgaw16 (regs, ECR_BKGD_MIX, 0x7); | ||
2177 | vgaw16 (regs, ECR_FRGD_MIX, 0x67); | ||
2178 | vgaw16 (regs, ECR_BKGD_COLOR, 0x0); | ||
2179 | vgaw16 (regs, ECR_FRGD_COLOR, 0x1); | ||
2180 | vgaw16 (regs, ECR_BITPLANE_READ_MASK, 0x1); | ||
2181 | vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, 0xFFF); | ||
2182 | vgaw16 (regs, ECR_CURRENT_Y_POS, sy); | ||
2183 | vgaw16 (regs, ECR_CURRENT_X_POS, sx); | ||
2184 | vgaw16 (regs, ECR_DEST_Y__AX_STEP, dy); | ||
2185 | vgaw16 (regs, ECR_DEST_X__DIA_STEP, dx); | ||
2186 | vgaw16 (regs, ECR_READ_REG_DATA, h - 1); | ||
2187 | vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1); | ||
2188 | vgaw16 (regs, ECR_DRAW_CMD, 0xC051 | drawdir); | ||
2189 | DPRINTK("EXIT\n"); | ||
2190 | } | ||
2191 | |||
2192 | void cvision_clear (u_short dx, u_short dy, u_short w, u_short h, u_short bg) | ||
2193 | { | ||
2194 | volatile unsigned char *regs = CyberRegs; | ||
2195 | DPRINTK("ENTER\n"); | ||
2196 | Cyber_WaitBlit(); | ||
2197 | vgaw16 (regs, ECR_FRGD_MIX, 0x0027); | ||
2198 | vgaw16 (regs, ECR_FRGD_COLOR, bg); | ||
2199 | vgaw16 (regs, ECR_READ_REG_DATA, 0xA000); | ||
2200 | vgaw16 (regs, ECR_CURRENT_Y_POS, dy); | ||
2201 | vgaw16 (regs, ECR_CURRENT_X_POS, dx); | ||
2202 | vgaw16 (regs, ECR_READ_REG_DATA, h - 1); | ||
2203 | vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1); | ||
2204 | vgaw16 (regs, ECR_DRAW_CMD, 0x40B1); | ||
2205 | DPRINTK("EXIT\n"); | ||
2206 | } | ||
2207 | |||
2208 | #ifdef CYBERFBDEBUG | ||
2209 | /* | ||
2210 | * Dump internal settings of CyberVision board | ||
2211 | */ | ||
2212 | static void cv64_dump (void) | ||
2213 | { | ||
2214 | volatile unsigned char *regs = CyberRegs; | ||
2215 | DPRINTK("ENTER\n"); | ||
2216 | /* Dump the VGA setup values */ | ||
2217 | *(regs + S3_CRTC_ADR) = 0x00; | ||
2218 | DPRINTK("CR00 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2219 | *(regs + S3_CRTC_ADR) = 0x01; | ||
2220 | DPRINTK("CR01 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2221 | *(regs + S3_CRTC_ADR) = 0x02; | ||
2222 | DPRINTK("CR02 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2223 | *(regs + S3_CRTC_ADR) = 0x03; | ||
2224 | DPRINTK("CR03 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2225 | *(regs + S3_CRTC_ADR) = 0x04; | ||
2226 | DPRINTK("CR04 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2227 | *(regs + S3_CRTC_ADR) = 0x05; | ||
2228 | DPRINTK("CR05 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2229 | *(regs + S3_CRTC_ADR) = 0x06; | ||
2230 | DPRINTK("CR06 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2231 | *(regs + S3_CRTC_ADR) = 0x07; | ||
2232 | DPRINTK("CR07 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2233 | *(regs + S3_CRTC_ADR) = 0x08; | ||
2234 | DPRINTK("CR08 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2235 | *(regs + S3_CRTC_ADR) = 0x09; | ||
2236 | DPRINTK("CR09 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2237 | *(regs + S3_CRTC_ADR) = 0x10; | ||
2238 | DPRINTK("CR10 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2239 | *(regs + S3_CRTC_ADR) = 0x11; | ||
2240 | DPRINTK("CR11 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2241 | *(regs + S3_CRTC_ADR) = 0x12; | ||
2242 | DPRINTK("CR12 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2243 | *(regs + S3_CRTC_ADR) = 0x13; | ||
2244 | DPRINTK("CR13 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2245 | *(regs + S3_CRTC_ADR) = 0x15; | ||
2246 | DPRINTK("CR15 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2247 | *(regs + S3_CRTC_ADR) = 0x16; | ||
2248 | DPRINTK("CR16 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2249 | *(regs + S3_CRTC_ADR) = 0x36; | ||
2250 | DPRINTK("CR36 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2251 | *(regs + S3_CRTC_ADR) = 0x37; | ||
2252 | DPRINTK("CR37 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2253 | *(regs + S3_CRTC_ADR) = 0x42; | ||
2254 | DPRINTK("CR42 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2255 | *(regs + S3_CRTC_ADR) = 0x43; | ||
2256 | DPRINTK("CR43 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2257 | *(regs + S3_CRTC_ADR) = 0x50; | ||
2258 | DPRINTK("CR50 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2259 | *(regs + S3_CRTC_ADR) = 0x51; | ||
2260 | DPRINTK("CR51 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2261 | *(regs + S3_CRTC_ADR) = 0x53; | ||
2262 | DPRINTK("CR53 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2263 | *(regs + S3_CRTC_ADR) = 0x58; | ||
2264 | DPRINTK("CR58 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2265 | *(regs + S3_CRTC_ADR) = 0x59; | ||
2266 | DPRINTK("CR59 = %x\n", *(regs + S3_CRTC_DATA)); | ||
2267 | *(regs + S3_CRTC_ADR) = 0x5A; | ||
2268 | DPRINTK("CR5A = %x\n", *(regs + S3_CRTC_DATA)); | ||
2269 | *(regs + S3_CRTC_ADR) = 0x5D; | ||
2270 | DPRINTK("CR5D = %x\n", *(regs + S3_CRTC_DATA)); | ||
2271 | *(regs + S3_CRTC_ADR) = 0x5E; | ||
2272 | DPRINTK("CR5E = %x\n", *(regs + S3_CRTC_DATA)); | ||
2273 | DPRINTK("MISC = %x\n", *(regs + GREG_MISC_OUTPUT_R)); | ||
2274 | *(regs + SEQ_ADDRESS) = 0x01; | ||
2275 | DPRINTK("SR01 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2276 | *(regs + SEQ_ADDRESS) = 0x02; | ||
2277 | DPRINTK("SR02 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2278 | *(regs + SEQ_ADDRESS) = 0x03; | ||
2279 | DPRINTK("SR03 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2280 | *(regs + SEQ_ADDRESS) = 0x09; | ||
2281 | DPRINTK("SR09 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2282 | *(regs + SEQ_ADDRESS) = 0x10; | ||
2283 | DPRINTK("SR10 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2284 | *(regs + SEQ_ADDRESS) = 0x11; | ||
2285 | DPRINTK("SR11 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2286 | *(regs + SEQ_ADDRESS) = 0x12; | ||
2287 | DPRINTK("SR12 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2288 | *(regs + SEQ_ADDRESS) = 0x13; | ||
2289 | DPRINTK("SR13 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2290 | *(regs + SEQ_ADDRESS) = 0x15; | ||
2291 | DPRINTK("SR15 = %x\n", *(regs + SEQ_ADDRESS_R)); | ||
2292 | |||
2293 | return; | ||
2294 | } | ||
2295 | #endif | ||
diff --git a/drivers/video/cyberfb.h b/drivers/video/cyberfb.h deleted file mode 100644 index 8435c430ad2..00000000000 --- a/drivers/video/cyberfb.h +++ /dev/null | |||
@@ -1,415 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/console/cvision.h -- CyberVision64 definitions for the | ||
3 | * text console driver. | ||
4 | * | ||
5 | * Copyright (c) 1998 Alan Bair | ||
6 | * | ||
7 | * This file is based on the initial port to Linux of grf_cvreg.h: | ||
8 | * | ||
9 | * Copyright (c) 1997 Antonio Santos | ||
10 | * | ||
11 | * The original work is from the NetBSD CyberVision 64 framebuffer driver | ||
12 | * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c): | ||
13 | * Permission to use the source of this driver was obtained from the | ||
14 | * author Michael Teske by Alan Bair. | ||
15 | * | ||
16 | * Copyright (c) 1995 Michael Teske | ||
17 | * | ||
18 | * History: | ||
19 | * | ||
20 | * | ||
21 | * | ||
22 | * This file is subject to the terms and conditions of the GNU General Public | ||
23 | * License. See the file COPYING in the main directory of this archive | ||
24 | * for more details. | ||
25 | */ | ||
26 | |||
27 | /* s3 commands */ | ||
28 | #define S3_BITBLT 0xc011 | ||
29 | #define S3_TWOPOINTLINE 0x2811 | ||
30 | #define S3_FILLEDRECT 0x40b1 | ||
31 | |||
32 | #define S3_FIFO_EMPTY 0x0400 | ||
33 | #define S3_HDW_BUSY 0x0200 | ||
34 | |||
35 | /* Enhanced register mapping (MMIO mode) */ | ||
36 | |||
37 | #define S3_READ_SEL 0xbee8 /* offset f */ | ||
38 | #define S3_MULT_MISC 0xbee8 /* offset e */ | ||
39 | #define S3_ERR_TERM 0x92e8 | ||
40 | #define S3_FRGD_COLOR 0xa6e8 | ||
41 | #define S3_BKGD_COLOR 0xa2e8 | ||
42 | #define S3_PIXEL_CNTL 0xbee8 /* offset a */ | ||
43 | #define S3_FRGD_MIX 0xbae8 | ||
44 | #define S3_BKGD_MIX 0xb6e8 | ||
45 | #define S3_CUR_Y 0x82e8 | ||
46 | #define S3_CUR_X 0x86e8 | ||
47 | #define S3_DESTY_AXSTP 0x8ae8 | ||
48 | #define S3_DESTX_DIASTP 0x8ee8 | ||
49 | #define S3_MIN_AXIS_PCNT 0xbee8 /* offset 0 */ | ||
50 | #define S3_MAJ_AXIS_PCNT 0x96e8 | ||
51 | #define S3_CMD 0x9ae8 | ||
52 | #define S3_GP_STAT 0x9ae8 | ||
53 | #define S3_ADVFUNC_CNTL 0x4ae8 | ||
54 | #define S3_WRT_MASK 0xaae8 | ||
55 | #define S3_RD_MASK 0xaee8 | ||
56 | |||
57 | /* Enhanced register mapping (Packed MMIO mode, write only) */ | ||
58 | #define S3_ALT_CURXY 0x8100 | ||
59 | #define S3_ALT_CURXY2 0x8104 | ||
60 | #define S3_ALT_STEP 0x8108 | ||
61 | #define S3_ALT_STEP2 0x810c | ||
62 | #define S3_ALT_ERR 0x8110 | ||
63 | #define S3_ALT_CMD 0x8118 | ||
64 | #define S3_ALT_MIX 0x8134 | ||
65 | #define S3_ALT_PCNT 0x8148 | ||
66 | #define S3_ALT_PAT 0x8168 | ||
67 | |||
68 | /* Drawing modes */ | ||
69 | #define S3_NOTCUR 0x0000 | ||
70 | #define S3_LOGICALZERO 0x0001 | ||
71 | #define S3_LOGICALONE 0x0002 | ||
72 | #define S3_LEAVEASIS 0x0003 | ||
73 | #define S3_NOTNEW 0x0004 | ||
74 | #define S3_CURXORNEW 0x0005 | ||
75 | #define S3_NOT_CURXORNEW 0x0006 | ||
76 | #define S3_NEW 0x0007 | ||
77 | #define S3_NOTCURORNOTNEW 0x0008 | ||
78 | #define S3_CURORNOTNEW 0x0009 | ||
79 | #define S3_NOTCURORNEW 0x000a | ||
80 | #define S3_CURORNEW 0x000b | ||
81 | #define S3_CURANDNEW 0x000c | ||
82 | #define S3_NOTCURANDNEW 0x000d | ||
83 | #define S3_CURANDNOTNEW 0x000e | ||
84 | #define S3_NOTCURANDNOTNEW 0x000f | ||
85 | |||
86 | #define S3_CRTC_ADR 0x03d4 | ||
87 | #define S3_CRTC_DATA 0x03d5 | ||
88 | |||
89 | #define S3_REG_LOCK2 0x39 | ||
90 | #define S3_HGC_MODE 0x45 | ||
91 | |||
92 | #define S3_HWGC_ORGX_H 0x46 | ||
93 | #define S3_HWGC_ORGX_L 0x47 | ||
94 | #define S3_HWGC_ORGY_H 0x48 | ||
95 | #define S3_HWGC_ORGY_L 0x49 | ||
96 | #define S3_HWGC_DX 0x4e | ||
97 | #define S3_HWGC_DY 0x4f | ||
98 | |||
99 | #define S3_LAW_CTL 0x58 | ||
100 | |||
101 | /**************************************************/ | ||
102 | |||
103 | /* support for a BitBlt operation. The op-codes are identical | ||
104 | to X11 GCs */ | ||
105 | #define GRFBBOPclear 0x0 /* 0 */ | ||
106 | #define GRFBBOPand 0x1 /* src AND dst */ | ||
107 | #define GRFBBOPandReverse 0x2 /* src AND NOT dst */ | ||
108 | #define GRFBBOPcopy 0x3 /* src */ | ||
109 | #define GRFBBOPandInverted 0x4 /* NOT src AND dst */ | ||
110 | #define GRFBBOPnoop 0x5 /* dst */ | ||
111 | #define GRFBBOPxor 0x6 /* src XOR dst */ | ||
112 | #define GRFBBOPor 0x7 /* src OR dst */ | ||
113 | #define GRFBBOPnor 0x8 /* NOT src AND NOT dst */ | ||
114 | #define GRFBBOPequiv 0x9 /* NOT src XOR dst */ | ||
115 | #define GRFBBOPinvert 0xa /* NOT dst */ | ||
116 | #define GRFBBOPorReverse 0xb /* src OR NOT dst */ | ||
117 | #define GRFBBOPcopyInverted 0xc /* NOT src */ | ||
118 | #define GRFBBOPorInverted 0xd /* NOT src OR dst */ | ||
119 | #define GRFBBOPnand 0xe /* NOT src OR NOT dst */ | ||
120 | #define GRFBBOPset 0xf /* 1 */ | ||
121 | |||
122 | |||
123 | /* Write 16 Bit VGA register */ | ||
124 | #define vgaw16(ba, reg, val) \ | ||
125 | *((unsigned short *) (((volatile unsigned char *)ba)+reg)) = val | ||
126 | |||
127 | /* | ||
128 | * Defines for the used register addresses (mw) | ||
129 | * | ||
130 | * NOTE: There are some registers that have different addresses when | ||
131 | * in mono or color mode. We only support color mode, and thus | ||
132 | * some addresses won't work in mono-mode! | ||
133 | * | ||
134 | * General and VGA-registers taken from retina driver. Fixed a few | ||
135 | * bugs in it. (SR and GR read address is Port + 1, NOT Port) | ||
136 | * | ||
137 | */ | ||
138 | |||
139 | /* General Registers: */ | ||
140 | #define GREG_MISC_OUTPUT_R 0x03CC | ||
141 | #define GREG_MISC_OUTPUT_W 0x03C2 | ||
142 | #define GREG_FEATURE_CONTROL_R 0x03CA | ||
143 | #define GREG_FEATURE_CONTROL_W 0x03DA | ||
144 | #define GREG_INPUT_STATUS0_R 0x03C2 | ||
145 | #define GREG_INPUT_STATUS1_R 0x03DA | ||
146 | |||
147 | /* Setup Registers: */ | ||
148 | #define SREG_OPTION_SELECT 0x0102 | ||
149 | #define SREG_VIDEO_SUBS_ENABLE 0x46E8 | ||
150 | |||
151 | /* Attribute Controller: */ | ||
152 | #define ACT_ADDRESS 0x03C0 | ||
153 | #define ACT_ADDRESS_R 0x03C1 | ||
154 | #define ACT_ADDRESS_W 0x03C0 | ||
155 | #define ACT_ADDRESS_RESET 0x03DA | ||
156 | #define ACT_ID_PALETTE0 0x00 | ||
157 | #define ACT_ID_PALETTE1 0x01 | ||
158 | #define ACT_ID_PALETTE2 0x02 | ||
159 | #define ACT_ID_PALETTE3 0x03 | ||
160 | #define ACT_ID_PALETTE4 0x04 | ||
161 | #define ACT_ID_PALETTE5 0x05 | ||
162 | #define ACT_ID_PALETTE6 0x06 | ||
163 | #define ACT_ID_PALETTE7 0x07 | ||
164 | #define ACT_ID_PALETTE8 0x08 | ||
165 | #define ACT_ID_PALETTE9 0x09 | ||
166 | #define ACT_ID_PALETTE10 0x0A | ||
167 | #define ACT_ID_PALETTE11 0x0B | ||
168 | #define ACT_ID_PALETTE12 0x0C | ||
169 | #define ACT_ID_PALETTE13 0x0D | ||
170 | #define ACT_ID_PALETTE14 0x0E | ||
171 | #define ACT_ID_PALETTE15 0x0F | ||
172 | #define ACT_ID_ATTR_MODE_CNTL 0x10 | ||
173 | #define ACT_ID_OVERSCAN_COLOR 0x11 | ||
174 | #define ACT_ID_COLOR_PLANE_ENA 0x12 | ||
175 | #define ACT_ID_HOR_PEL_PANNING 0x13 | ||
176 | #define ACT_ID_COLOR_SELECT 0x14 | ||
177 | |||
178 | /* Graphics Controller: */ | ||
179 | #define GCT_ADDRESS 0x03CE | ||
180 | #define GCT_ADDRESS_R 0x03CF | ||
181 | #define GCT_ADDRESS_W 0x03CF | ||
182 | #define GCT_ID_SET_RESET 0x00 | ||
183 | #define GCT_ID_ENABLE_SET_RESET 0x01 | ||
184 | #define GCT_ID_COLOR_COMPARE 0x02 | ||
185 | #define GCT_ID_DATA_ROTATE 0x03 | ||
186 | #define GCT_ID_READ_MAP_SELECT 0x04 | ||
187 | #define GCT_ID_GRAPHICS_MODE 0x05 | ||
188 | #define GCT_ID_MISC 0x06 | ||
189 | #define GCT_ID_COLOR_XCARE 0x07 | ||
190 | #define GCT_ID_BITMASK 0x08 | ||
191 | |||
192 | /* Sequencer: */ | ||
193 | #define SEQ_ADDRESS 0x03C4 | ||
194 | #define SEQ_ADDRESS_R 0x03C5 | ||
195 | #define SEQ_ADDRESS_W 0x03C5 | ||
196 | #define SEQ_ID_RESET 0x00 | ||
197 | #define SEQ_ID_CLOCKING_MODE 0x01 | ||
198 | #define SEQ_ID_MAP_MASK 0x02 | ||
199 | #define SEQ_ID_CHAR_MAP_SELECT 0x03 | ||
200 | #define SEQ_ID_MEMORY_MODE 0x04 | ||
201 | #define SEQ_ID_UNKNOWN1 0x05 | ||
202 | #define SEQ_ID_UNKNOWN2 0x06 | ||
203 | #define SEQ_ID_UNKNOWN3 0x07 | ||
204 | /* S3 extensions */ | ||
205 | #define SEQ_ID_UNLOCK_EXT 0x08 | ||
206 | #define SEQ_ID_EXT_SEQ_REG9 0x09 | ||
207 | #define SEQ_ID_BUS_REQ_CNTL 0x0A | ||
208 | #define SEQ_ID_EXT_MISC_SEQ 0x0B | ||
209 | #define SEQ_ID_UNKNOWN4 0x0C | ||
210 | #define SEQ_ID_EXT_SEQ 0x0D | ||
211 | #define SEQ_ID_UNKNOWN5 0x0E | ||
212 | #define SEQ_ID_UNKNOWN6 0x0F | ||
213 | #define SEQ_ID_MCLK_LO 0x10 | ||
214 | #define SEQ_ID_MCLK_HI 0x11 | ||
215 | #define SEQ_ID_DCLK_LO 0x12 | ||
216 | #define SEQ_ID_DCLK_HI 0x13 | ||
217 | #define SEQ_ID_CLKSYN_CNTL_1 0x14 | ||
218 | #define SEQ_ID_CLKSYN_CNTL_2 0x15 | ||
219 | #define SEQ_ID_CLKSYN_TEST_HI 0x16 /* reserved for S3 testing of the */ | ||
220 | #define SEQ_ID_CLKSYN_TEST_LO 0x17 /* internal clock synthesizer */ | ||
221 | #define SEQ_ID_RAMDAC_CNTL 0x18 | ||
222 | #define SEQ_ID_MORE_MAGIC 0x1A | ||
223 | |||
224 | /* CRT Controller: */ | ||
225 | #define CRT_ADDRESS 0x03D4 | ||
226 | #define CRT_ADDRESS_R 0x03D5 | ||
227 | #define CRT_ADDRESS_W 0x03D5 | ||
228 | #define CRT_ID_HOR_TOTAL 0x00 | ||
229 | #define CRT_ID_HOR_DISP_ENA_END 0x01 | ||
230 | #define CRT_ID_START_HOR_BLANK 0x02 | ||
231 | #define CRT_ID_END_HOR_BLANK 0x03 | ||
232 | #define CRT_ID_START_HOR_RETR 0x04 | ||
233 | #define CRT_ID_END_HOR_RETR 0x05 | ||
234 | #define CRT_ID_VER_TOTAL 0x06 | ||
235 | #define CRT_ID_OVERFLOW 0x07 | ||
236 | #define CRT_ID_PRESET_ROW_SCAN 0x08 | ||
237 | #define CRT_ID_MAX_SCAN_LINE 0x09 | ||
238 | #define CRT_ID_CURSOR_START 0x0A | ||
239 | #define CRT_ID_CURSOR_END 0x0B | ||
240 | #define CRT_ID_START_ADDR_HIGH 0x0C | ||
241 | #define CRT_ID_START_ADDR_LOW 0x0D | ||
242 | #define CRT_ID_CURSOR_LOC_HIGH 0x0E | ||
243 | #define CRT_ID_CURSOR_LOC_LOW 0x0F | ||
244 | #define CRT_ID_START_VER_RETR 0x10 | ||
245 | #define CRT_ID_END_VER_RETR 0x11 | ||
246 | #define CRT_ID_VER_DISP_ENA_END 0x12 | ||
247 | #define CRT_ID_SCREEN_OFFSET 0x13 | ||
248 | #define CRT_ID_UNDERLINE_LOC 0x14 | ||
249 | #define CRT_ID_START_VER_BLANK 0x15 | ||
250 | #define CRT_ID_END_VER_BLANK 0x16 | ||
251 | #define CRT_ID_MODE_CONTROL 0x17 | ||
252 | #define CRT_ID_LINE_COMPARE 0x18 | ||
253 | #define CRT_ID_GD_LATCH_RBACK 0x22 | ||
254 | #define CRT_ID_ACT_TOGGLE_RBACK 0x24 | ||
255 | #define CRT_ID_ACT_INDEX_RBACK 0x26 | ||
256 | /* S3 extensions: S3 VGA Registers */ | ||
257 | #define CRT_ID_DEVICE_HIGH 0x2D | ||
258 | #define CRT_ID_DEVICE_LOW 0x2E | ||
259 | #define CRT_ID_REVISION 0x2F | ||
260 | #define CRT_ID_CHIP_ID_REV 0x30 | ||
261 | #define CRT_ID_MEMORY_CONF 0x31 | ||
262 | #define CRT_ID_BACKWAD_COMP_1 0x32 | ||
263 | #define CRT_ID_BACKWAD_COMP_2 0x33 | ||
264 | #define CRT_ID_BACKWAD_COMP_3 0x34 | ||
265 | #define CRT_ID_REGISTER_LOCK 0x35 | ||
266 | #define CRT_ID_CONFIG_1 0x36 | ||
267 | #define CRT_ID_CONFIG_2 0x37 | ||
268 | #define CRT_ID_REGISTER_LOCK_1 0x38 | ||
269 | #define CRT_ID_REGISTER_LOCK_2 0x39 | ||
270 | #define CRT_ID_MISC_1 0x3A | ||
271 | #define CRT_ID_DISPLAY_FIFO 0x3B | ||
272 | #define CRT_ID_LACE_RETR_START 0x3C | ||
273 | /* S3 extensions: System Control Registers */ | ||
274 | #define CRT_ID_SYSTEM_CONFIG 0x40 | ||
275 | #define CRT_ID_BIOS_FLAG 0x41 | ||
276 | #define CRT_ID_LACE_CONTROL 0x42 | ||
277 | #define CRT_ID_EXT_MODE 0x43 | ||
278 | #define CRT_ID_HWGC_MODE 0x45 /* HWGC = Hardware Graphics Cursor */ | ||
279 | #define CRT_ID_HWGC_ORIGIN_X_HI 0x46 | ||
280 | #define CRT_ID_HWGC_ORIGIN_X_LO 0x47 | ||
281 | #define CRT_ID_HWGC_ORIGIN_Y_HI 0x48 | ||
282 | #define CRT_ID_HWGC_ORIGIN_Y_LO 0x49 | ||
283 | #define CRT_ID_HWGC_FG_STACK 0x4A | ||
284 | #define CRT_ID_HWGC_BG_STACK 0x4B | ||
285 | #define CRT_ID_HWGC_START_AD_HI 0x4C | ||
286 | #define CRT_ID_HWGC_START_AD_LO 0x4D | ||
287 | #define CRT_ID_HWGC_DSTART_X 0x4E | ||
288 | #define CRT_ID_HWGC_DSTART_Y 0x4F | ||
289 | /* S3 extensions: System Extension Registers */ | ||
290 | #define CRT_ID_EXT_SYS_CNTL_1 0x50 | ||
291 | #define CRT_ID_EXT_SYS_CNTL_2 0x51 | ||
292 | #define CRT_ID_EXT_BIOS_FLAG_1 0x52 | ||
293 | #define CRT_ID_EXT_MEM_CNTL_1 0x53 | ||
294 | #define CRT_ID_EXT_MEM_CNTL_2 0x54 | ||
295 | #define CRT_ID_EXT_DAC_CNTL 0x55 | ||
296 | #define CRT_ID_EX_SYNC_1 0x56 | ||
297 | #define CRT_ID_EX_SYNC_2 0x57 | ||
298 | #define CRT_ID_LAW_CNTL 0x58 /* LAW = Linear Address Window */ | ||
299 | #define CRT_ID_LAW_POS_HI 0x59 | ||
300 | #define CRT_ID_LAW_POS_LO 0x5A | ||
301 | #define CRT_ID_GOUT_PORT 0x5C | ||
302 | #define CRT_ID_EXT_HOR_OVF 0x5D | ||
303 | #define CRT_ID_EXT_VER_OVF 0x5E | ||
304 | #define CRT_ID_EXT_MEM_CNTL_3 0x60 | ||
305 | #define CRT_ID_EX_SYNC_3 0x63 | ||
306 | #define CRT_ID_EXT_MISC_CNTL 0x65 | ||
307 | #define CRT_ID_EXT_MISC_CNTL_1 0x66 | ||
308 | #define CRT_ID_EXT_MISC_CNTL_2 0x67 | ||
309 | #define CRT_ID_CONFIG_3 0x68 | ||
310 | #define CRT_ID_EXT_SYS_CNTL_3 0x69 | ||
311 | #define CRT_ID_EXT_SYS_CNTL_4 0x6A | ||
312 | #define CRT_ID_EXT_BIOS_FLAG_3 0x6B | ||
313 | #define CRT_ID_EXT_BIOS_FLAG_4 0x6C | ||
314 | |||
315 | /* Enhanced Commands Registers: */ | ||
316 | #define ECR_SUBSYSTEM_STAT 0x42E8 | ||
317 | #define ECR_SUBSYSTEM_CNTL 0x42E8 | ||
318 | #define ECR_ADV_FUNC_CNTL 0x4AE8 | ||
319 | #define ECR_CURRENT_Y_POS 0x82E8 | ||
320 | #define ECR_CURRENT_Y_POS2 0x82EA /* Trio64 only */ | ||
321 | #define ECR_CURRENT_X_POS 0x86E8 | ||
322 | #define ECR_CURRENT_X_POS2 0x86EA /* Trio64 only */ | ||
323 | #define ECR_DEST_Y__AX_STEP 0x8AE8 | ||
324 | #define ECR_DEST_Y2__AX_STEP2 0x8AEA /* Trio64 only */ | ||
325 | #define ECR_DEST_X__DIA_STEP 0x8EE8 | ||
326 | #define ECR_DEST_X2__DIA_STEP2 0x8EEA /* Trio64 only */ | ||
327 | #define ECR_ERR_TERM 0x92E8 | ||
328 | #define ECR_ERR_TERM2 0x92EA /* Trio64 only */ | ||
329 | #define ECR_MAJ_AXIS_PIX_CNT 0x96E8 | ||
330 | #define ECR_MAJ_AXIS_PIX_CNT2 0x96EA /* Trio64 only */ | ||
331 | #define ECR_GP_STAT 0x9AE8 /* GP = Graphics Processor */ | ||
332 | #define ECR_DRAW_CMD 0x9AE8 | ||
333 | #define ECR_DRAW_CMD2 0x9AEA /* Trio64 only */ | ||
334 | #define ECR_SHORT_STROKE 0x9EE8 | ||
335 | #define ECR_BKGD_COLOR 0xA2E8 /* BKGD = Background */ | ||
336 | #define ECR_FRGD_COLOR 0xA6E8 /* FRGD = Foreground */ | ||
337 | #define ECR_BITPLANE_WRITE_MASK 0xAAE8 | ||
338 | #define ECR_BITPLANE_READ_MASK 0xAEE8 | ||
339 | #define ECR_COLOR_COMPARE 0xB2E8 | ||
340 | #define ECR_BKGD_MIX 0xB6E8 | ||
341 | #define ECR_FRGD_MIX 0xBAE8 | ||
342 | #define ECR_READ_REG_DATA 0xBEE8 | ||
343 | #define ECR_ID_MIN_AXIS_PIX_CNT 0x00 | ||
344 | #define ECR_ID_SCISSORS_TOP 0x01 | ||
345 | #define ECR_ID_SCISSORS_LEFT 0x02 | ||
346 | #define ECR_ID_SCISSORS_BUTTOM 0x03 | ||
347 | #define ECR_ID_SCISSORS_RIGHT 0x04 | ||
348 | #define ECR_ID_PIX_CNTL 0x0A | ||
349 | #define ECR_ID_MULT_CNTL_MISC_2 0x0D | ||
350 | #define ECR_ID_MULT_CNTL_MISC 0x0E | ||
351 | #define ECR_ID_READ_SEL 0x0F | ||
352 | #define ECR_PIX_TRANS 0xE2E8 | ||
353 | #define ECR_PIX_TRANS_EXT 0xE2EA | ||
354 | #define ECR_PATTERN_Y 0xEAE8 /* Trio64 only */ | ||
355 | #define ECR_PATTERN_X 0xEAEA /* Trio64 only */ | ||
356 | |||
357 | |||
358 | /* Pass-through */ | ||
359 | #define PASS_ADDRESS 0x40001 | ||
360 | #define PASS_ADDRESS_W 0x40001 | ||
361 | |||
362 | /* Video DAC */ | ||
363 | #define VDAC_ADDRESS 0x03c8 | ||
364 | #define VDAC_ADDRESS_W 0x03c8 | ||
365 | #define VDAC_ADDRESS_R 0x03c7 | ||
366 | #define VDAC_STATE 0x03c7 | ||
367 | #define VDAC_DATA 0x03c9 | ||
368 | #define VDAC_MASK 0x03c6 | ||
369 | |||
370 | |||
371 | #define WGfx(ba, idx, val) \ | ||
372 | do { wb_64(ba, GCT_ADDRESS, idx); wb_64(ba, GCT_ADDRESS_W , val); } while (0) | ||
373 | |||
374 | #define WSeq(ba, idx, val) \ | ||
375 | do { wb_64(ba, SEQ_ADDRESS, idx); wb_64(ba, SEQ_ADDRESS_W , val); } while (0) | ||
376 | |||
377 | #define WCrt(ba, idx, val) \ | ||
378 | do { wb_64(ba, CRT_ADDRESS, idx); wb_64(ba, CRT_ADDRESS_W , val); } while (0) | ||
379 | |||
380 | #define WAttr(ba, idx, val) \ | ||
381 | do { \ | ||
382 | unsigned char tmp;\ | ||
383 | tmp = rb_64(ba, ACT_ADDRESS_RESET);\ | ||
384 | wb_64(ba, ACT_ADDRESS_W, idx);\ | ||
385 | wb_64(ba, ACT_ADDRESS_W, val);\ | ||
386 | } while (0) | ||
387 | |||
388 | #define SetTextPlane(ba, m) \ | ||
389 | do { \ | ||
390 | WGfx(ba, GCT_ID_READ_MAP_SELECT, m & 3 );\ | ||
391 | WSeq(ba, SEQ_ID_MAP_MASK, (1 << (m & 3)));\ | ||
392 | } while (0) | ||
393 | |||
394 | /* --------------------------------- */ | ||
395 | /* prototypes */ | ||
396 | /* --------------------------------- */ | ||
397 | |||
398 | inline unsigned char RAttr(volatile unsigned char * board, short idx); | ||
399 | inline unsigned char RSeq(volatile unsigned char * board, short idx); | ||
400 | inline unsigned char RCrt(volatile unsigned char * board, short idx); | ||
401 | inline unsigned char RGfx(volatile unsigned char * board, short idx); | ||
402 | inline void cv64_write_port(unsigned short bits, | ||
403 | volatile unsigned char *board); | ||
404 | inline void cvscreen(int toggle, volatile unsigned char *board); | ||
405 | inline void gfx_on_off(int toggle, volatile unsigned char *board); | ||
406 | #if 0 | ||
407 | unsigned short cv64_compute_clock(unsigned long freq); | ||
408 | int cv_has_4mb(volatile unsigned char * fb); | ||
409 | void cv64_board_init(void); | ||
410 | void cv64_load_video_mode(struct fb_var_screeninfo *video_mode); | ||
411 | #endif | ||
412 | |||
413 | void cvision_bitblt(u_short sx, u_short sy, u_short dx, u_short dy, u_short w, | ||
414 | u_short h); | ||
415 | void cvision_clear(u_short dx, u_short dy, u_short w, u_short h, u_short bg); | ||
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c deleted file mode 100644 index bc7ffc84e18..00000000000 --- a/drivers/video/retz3fb.c +++ /dev/null | |||
@@ -1,1588 +0,0 @@ | |||
1 | /* | ||
2 | * Linux/drivers/video/retz3fb.c -- RetinaZ3 frame buffer device | ||
3 | * | ||
4 | * Copyright (C) 1997 Jes Sorensen | ||
5 | * | ||
6 | * This file is based on the CyberVision64 frame buffer device and | ||
7 | * the generic Cirrus Logic driver. | ||
8 | * | ||
9 | * cyberfb.c: Copyright (C) 1996 Martin Apel, | ||
10 | * Geert Uytterhoeven | ||
11 | * clgen.c: Copyright (C) 1996 Frank Neumann | ||
12 | * | ||
13 | * History: | ||
14 | * - 22 Jan 97: Initial work | ||
15 | * - 14 Feb 97: Screen initialization works somewhat, still only | ||
16 | * 8-bit packed pixel is supported. | ||
17 | * | ||
18 | * This file is subject to the terms and conditions of the GNU General Public | ||
19 | * License. See the file COPYING in the main directory of this archive | ||
20 | * for more details. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/string.h> | ||
27 | #include <linux/mm.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/fb.h> | ||
31 | #include <linux/zorro.h> | ||
32 | #include <linux/init.h> | ||
33 | |||
34 | #include <asm/uaccess.h> | ||
35 | #include <asm/system.h> | ||
36 | #include <asm/irq.h> | ||
37 | #include <asm/pgtable.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | #include <video/fbcon.h> | ||
41 | #include <video/fbcon-cfb8.h> | ||
42 | #include <video/fbcon-cfb16.h> | ||
43 | |||
44 | #include "retz3fb.h" | ||
45 | |||
46 | /* #define DEBUG if(1) */ | ||
47 | #define DEBUG if(0) | ||
48 | |||
49 | /* | ||
50 | * Reserve space for one pattern line. | ||
51 | * | ||
52 | * For the time being we only support 4MB boards! | ||
53 | */ | ||
54 | |||
55 | #define PAT_MEM_SIZE 16*3 | ||
56 | #define PAT_MEM_OFF (4*1024*1024 - PAT_MEM_SIZE) | ||
57 | |||
58 | struct retz3fb_par { | ||
59 | int xres; | ||
60 | int yres; | ||
61 | int xres_vir; | ||
62 | int yres_vir; | ||
63 | int xoffset; | ||
64 | int yoffset; | ||
65 | int bpp; | ||
66 | |||
67 | struct fb_bitfield red; | ||
68 | struct fb_bitfield green; | ||
69 | struct fb_bitfield blue; | ||
70 | struct fb_bitfield transp; | ||
71 | |||
72 | int pixclock; | ||
73 | int left_margin; /* time from sync to picture */ | ||
74 | int right_margin; /* time from picture to sync */ | ||
75 | int upper_margin; /* time from sync to picture */ | ||
76 | int lower_margin; | ||
77 | int hsync_len; /* length of horizontal sync */ | ||
78 | int vsync_len; /* length of vertical sync */ | ||
79 | int vmode; | ||
80 | |||
81 | int accel; | ||
82 | }; | ||
83 | |||
84 | struct display_data { | ||
85 | long h_total; /* Horizontal Total */ | ||
86 | long h_sstart; /* Horizontal Sync Start */ | ||
87 | long h_sstop; /* Horizontal Sync Stop */ | ||
88 | long h_bstart; /* Horizontal Blank Start */ | ||
89 | long h_bstop; /* Horizontal Blank Stop */ | ||
90 | long h_dispend; /* Horizontal Display End */ | ||
91 | long v_total; /* Vertical Total */ | ||
92 | long v_sstart; /* Vertical Sync Start */ | ||
93 | long v_sstop; /* Vertical Sync Stop */ | ||
94 | long v_bstart; /* Vertical Blank Start */ | ||
95 | long v_bstop; /* Vertical Blank Stop */ | ||
96 | long v_dispend; /* Horizontal Display End */ | ||
97 | }; | ||
98 | |||
99 | struct retz3_fb_info { | ||
100 | struct fb_info info; | ||
101 | unsigned char *base; | ||
102 | unsigned char *fbmem; | ||
103 | unsigned long fbsize; | ||
104 | volatile unsigned char *regs; | ||
105 | unsigned long physfbmem; | ||
106 | unsigned long physregs; | ||
107 | int current_par_valid; /* set to 0 by memset */ | ||
108 | int blitbusy; | ||
109 | struct display disp; | ||
110 | struct retz3fb_par current_par; | ||
111 | unsigned char color_table [256][3]; | ||
112 | }; | ||
113 | |||
114 | |||
115 | static char fontname[40] __initdata = { 0 }; | ||
116 | |||
117 | #define retz3info(info) ((struct retz3_fb_info *)(info)) | ||
118 | #define fbinfo(info) ((struct fb_info *)(info)) | ||
119 | |||
120 | |||
121 | /* | ||
122 | * Frame Buffer Name | ||
123 | */ | ||
124 | |||
125 | static char retz3fb_name[16] = "RetinaZ3"; | ||
126 | |||
127 | |||
128 | /* | ||
129 | * A small info on how to convert XFree86 timing values into fb | ||
130 | * timings - by Frank Neumann: | ||
131 | * | ||
132 | An XFree86 mode line consists of the following fields: | ||
133 | "800x600" 50 800 856 976 1040 600 637 643 666 | ||
134 | < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL | ||
135 | |||
136 | The fields in the fb_var_screeninfo structure are: | ||
137 | unsigned long pixclock; * pixel clock in ps (pico seconds) * | ||
138 | unsigned long left_margin; * time from sync to picture * | ||
139 | unsigned long right_margin; * time from picture to sync * | ||
140 | unsigned long upper_margin; * time from sync to picture * | ||
141 | unsigned long lower_margin; | ||
142 | unsigned long hsync_len; * length of horizontal sync * | ||
143 | unsigned long vsync_len; * length of vertical sync * | ||
144 | |||
145 | 1) Pixelclock: | ||
146 | xfree: in MHz | ||
147 | fb: In Picoseconds (ps) | ||
148 | |||
149 | pixclock = 1000000 / DCF | ||
150 | |||
151 | 2) horizontal timings: | ||
152 | left_margin = HFL - SH2 | ||
153 | right_margin = SH1 - HR | ||
154 | hsync_len = SH2 - SH1 | ||
155 | |||
156 | 3) vertical timings: | ||
157 | upper_margin = VFL - SV2 | ||
158 | lower_margin = SV1 - VR | ||
159 | vsync_len = SV2 - SV1 | ||
160 | |||
161 | Good examples for VESA timings can be found in the XFree86 source tree, | ||
162 | under "programs/Xserver/hw/xfree86/doc/modeDB.txt". | ||
163 | */ | ||
164 | |||
165 | /* | ||
166 | * Predefined Video Modes | ||
167 | */ | ||
168 | |||
169 | static struct { | ||
170 | const char *name; | ||
171 | struct fb_var_screeninfo var; | ||
172 | } retz3fb_predefined[] __initdata = { | ||
173 | /* | ||
174 | * NB: it is very important to adjust the pixel-clock to the color-depth. | ||
175 | */ | ||
176 | |||
177 | { | ||
178 | "640x480", { /* 640x480, 8 bpp */ | ||
179 | 640, 480, 640, 480, 0, 0, 8, 0, | ||
180 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
181 | 0, 0, -1, -1, FB_ACCEL_NONE, 39722, 48, 16, 33, 10, 96, 2, | ||
182 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED | ||
183 | } | ||
184 | }, | ||
185 | /* | ||
186 | ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 | ||
187 | < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL | ||
188 | */ | ||
189 | { | ||
190 | "800x600", { /* 800x600, 8 bpp */ | ||
191 | 800, 600, 800, 600, 0, 0, 8, 0, | ||
192 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
193 | 0, 0, -1, -1, FB_ACCELF_TEXT, 27778, 64, 24, 22, 1, 120, 2, | ||
194 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
195 | } | ||
196 | }, | ||
197 | { | ||
198 | "800x600-60", { /* 800x600, 8 bpp */ | ||
199 | 800, 600, 800, 600, 0, 0, 8, 0, | ||
200 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
201 | 0, 0, -1, -1, FB_ACCELF_TEXT, 25000, 88, 40, 23, 1, 128, 4, | ||
202 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
203 | } | ||
204 | }, | ||
205 | { | ||
206 | "800x600-70", { /* 800x600, 8 bpp */ | ||
207 | 800, 600, 800, 600, 0, 0, 8, 0, | ||
208 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
209 | 0, 0, -1, -1, FB_ACCELF_TEXT, 22272, 40, 24, 15, 9, 144, 12, | ||
210 | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
211 | } | ||
212 | }, | ||
213 | /* | ||
214 | ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace | ||
215 | < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL | ||
216 | */ | ||
217 | { | ||
218 | "1024x768i", { /* 1024x768, 8 bpp, interlaced */ | ||
219 | 1024, 768, 1024, 768, 0, 0, 8, 0, | ||
220 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
221 | 0, 0, -1, -1, FB_ACCELF_TEXT, 22222, 40, 40, 32, 9, 160, 8, | ||
222 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED | ||
223 | } | ||
224 | }, | ||
225 | { | ||
226 | "1024x768", { | ||
227 | 1024, 768, 1024, 768, 0, 0, 8, 0, | ||
228 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
229 | 0, 0, -1, -1, FB_ACCEL_NONE, 12500, 92, 112, 31, 2, 204, 4, | ||
230 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
231 | } | ||
232 | }, | ||
233 | { | ||
234 | "640x480-16", { /* 640x480, 16 bpp */ | ||
235 | 640, 480, 640, 480, 0, 0, 16, 0, | ||
236 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
237 | 0, 0, -1, -1, 0, 38461/2, 28, 32, 12, 10, 96, 2, | ||
238 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED | ||
239 | } | ||
240 | }, | ||
241 | { | ||
242 | "640x480-24", { /* 640x480, 24 bpp */ | ||
243 | 640, 480, 640, 480, 0, 0, 24, 0, | ||
244 | {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, | ||
245 | 0, 0, -1, -1, 0, 38461/3, 28, 32, 12, 10, 96, 2, | ||
246 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED | ||
247 | } | ||
248 | }, | ||
249 | }; | ||
250 | |||
251 | |||
252 | #define NUM_TOTAL_MODES ARRAY_SIZE(retz3fb_predefined) | ||
253 | |||
254 | static struct fb_var_screeninfo retz3fb_default; | ||
255 | |||
256 | static int z3fb_inverse = 0; | ||
257 | static int z3fb_mode __initdata = 0; | ||
258 | |||
259 | |||
260 | /* | ||
261 | * Interface used by the world | ||
262 | */ | ||
263 | |||
264 | int retz3fb_setup(char *options); | ||
265 | |||
266 | static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
267 | struct fb_info *info); | ||
268 | static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, | ||
269 | struct fb_info *info); | ||
270 | static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, | ||
271 | struct fb_info *info); | ||
272 | static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
273 | struct fb_info *info); | ||
274 | static int retz3fb_setcolreg(unsigned int regno, unsigned int red, | ||
275 | unsigned int green, unsigned int blue, | ||
276 | unsigned int transp, struct fb_info *info); | ||
277 | static int retz3fb_blank(int blank, struct fb_info *info); | ||
278 | |||
279 | |||
280 | /* | ||
281 | * Interface to the low level console driver | ||
282 | */ | ||
283 | |||
284 | int retz3fb_init(void); | ||
285 | static int z3fb_switch(int con, struct fb_info *info); | ||
286 | static int z3fb_updatevar(int con, struct fb_info *info); | ||
287 | |||
288 | |||
289 | /* | ||
290 | * Text console acceleration | ||
291 | */ | ||
292 | |||
293 | #ifdef FBCON_HAS_CFB8 | ||
294 | static struct display_switch fbcon_retz3_8; | ||
295 | #endif | ||
296 | |||
297 | |||
298 | /* | ||
299 | * Accelerated Functions used by the low level console driver | ||
300 | */ | ||
301 | |||
302 | static void retz3_bitblt(struct display *p, | ||
303 | unsigned short curx, unsigned short cury, unsigned | ||
304 | short destx, unsigned short desty, unsigned short | ||
305 | width, unsigned short height, unsigned short cmd, | ||
306 | unsigned short mask); | ||
307 | |||
308 | /* | ||
309 | * Hardware Specific Routines | ||
310 | */ | ||
311 | |||
312 | static int retz3_encode_fix(struct fb_info *info, | ||
313 | struct fb_fix_screeninfo *fix, | ||
314 | struct retz3fb_par *par); | ||
315 | static int retz3_decode_var(struct fb_var_screeninfo *var, | ||
316 | struct retz3fb_par *par); | ||
317 | static int retz3_encode_var(struct fb_var_screeninfo *var, | ||
318 | struct retz3fb_par *par); | ||
319 | static int retz3_getcolreg(unsigned int regno, unsigned int *red, | ||
320 | unsigned int *green, unsigned int *blue, | ||
321 | unsigned int *transp, struct fb_info *info); | ||
322 | |||
323 | /* | ||
324 | * Internal routines | ||
325 | */ | ||
326 | |||
327 | static void retz3fb_get_par(struct fb_info *info, struct retz3fb_par *par); | ||
328 | static void retz3fb_set_par(struct fb_info *info, struct retz3fb_par *par); | ||
329 | static int do_fb_set_var(struct fb_info *info, | ||
330 | struct fb_var_screeninfo *var, int isactive); | ||
331 | static void retz3fb_set_disp(int con, struct fb_info *info); | ||
332 | static int get_video_mode(const char *name); | ||
333 | |||
334 | |||
335 | /* -------------------- Hardware specific routines ------------------------- */ | ||
336 | |||
337 | static unsigned short find_fq(unsigned int freq) | ||
338 | { | ||
339 | unsigned long f; | ||
340 | long tmp; | ||
341 | long prev = 0x7fffffff; | ||
342 | long n2, n1 = 3; | ||
343 | unsigned long m; | ||
344 | unsigned short res = 0; | ||
345 | |||
346 | if (freq <= 31250000) | ||
347 | n2 = 3; | ||
348 | else if (freq <= 62500000) | ||
349 | n2 = 2; | ||
350 | else if (freq <= 125000000) | ||
351 | n2 = 1; | ||
352 | else if (freq <= 250000000) | ||
353 | n2 = 0; | ||
354 | else | ||
355 | return 0; | ||
356 | |||
357 | |||
358 | do { | ||
359 | f = freq >> (10 - n2); | ||
360 | |||
361 | m = (f * n1) / (14318180/1024); | ||
362 | |||
363 | if (m > 129) | ||
364 | break; | ||
365 | |||
366 | tmp = (((m * 14318180) >> n2) / n1) - freq; | ||
367 | if (tmp < 0) | ||
368 | tmp = -tmp; | ||
369 | |||
370 | if (tmp < prev) { | ||
371 | prev = tmp; | ||
372 | res = (((n2 << 5) | (n1-2)) << 8) | (m-2); | ||
373 | } | ||
374 | |||
375 | } while ( (++n1) <= 21); | ||
376 | |||
377 | return res; | ||
378 | } | ||
379 | |||
380 | |||
381 | static int retz3_set_video(struct fb_info *info, | ||
382 | struct fb_var_screeninfo *var, | ||
383 | struct retz3fb_par *par) | ||
384 | { | ||
385 | volatile unsigned char *regs = retz3info(info)->regs; | ||
386 | unsigned int freq; | ||
387 | |||
388 | int xres, hfront, hsync, hback; | ||
389 | int yres, vfront, vsync, vback; | ||
390 | unsigned char tmp; | ||
391 | unsigned short best_freq; | ||
392 | struct display_data data; | ||
393 | |||
394 | short clocksel = 0; /* Apparantly this is always zero */ | ||
395 | |||
396 | int bpp = var->bits_per_pixel; | ||
397 | |||
398 | /* | ||
399 | * XXX | ||
400 | */ | ||
401 | if (bpp == 24) | ||
402 | return 0; | ||
403 | |||
404 | if ((bpp != 8) && (bpp != 16) && (bpp != 24)) | ||
405 | return -EFAULT; | ||
406 | |||
407 | par->xoffset = 0; | ||
408 | par->yoffset = 0; | ||
409 | |||
410 | xres = var->xres * bpp / 4; | ||
411 | hfront = var->right_margin * bpp / 4; | ||
412 | hsync = var->hsync_len * bpp / 4; | ||
413 | hback = var->left_margin * bpp / 4; | ||
414 | |||
415 | if (var->vmode & FB_VMODE_DOUBLE) | ||
416 | { | ||
417 | yres = var->yres * 2; | ||
418 | vfront = var->lower_margin * 2; | ||
419 | vsync = var->vsync_len * 2; | ||
420 | vback = var->upper_margin * 2; | ||
421 | } | ||
422 | else if (var->vmode & FB_VMODE_INTERLACED) | ||
423 | { | ||
424 | yres = (var->yres + 1) / 2; | ||
425 | vfront = (var->lower_margin + 1) / 2; | ||
426 | vsync = (var->vsync_len + 1) / 2; | ||
427 | vback = (var->upper_margin + 1) / 2; | ||
428 | } | ||
429 | else | ||
430 | { | ||
431 | yres = var->yres; /* -1 ? */ | ||
432 | vfront = var->lower_margin; | ||
433 | vsync = var->vsync_len; | ||
434 | vback = var->upper_margin; | ||
435 | } | ||
436 | |||
437 | data.h_total = (hback / 8) + (xres / 8) | ||
438 | + (hfront / 8) + (hsync / 8) - 1 /* + 1 */; | ||
439 | data.h_dispend = ((xres + bpp - 1)/ 8) - 1; | ||
440 | data.h_bstart = xres / 8 - 1 /* + 1 */; | ||
441 | |||
442 | data.h_bstop = data.h_total+1 + 2 + 1; | ||
443 | data.h_sstart = (xres / 8) + (hfront / 8) + 1; | ||
444 | data.h_sstop = (xres / 8) + (hfront / 8) + (hsync / 8) + 1; | ||
445 | |||
446 | data.v_total = yres + vfront + vsync + vback - 1; | ||
447 | |||
448 | data.v_dispend = yres - 1; | ||
449 | data.v_bstart = yres - 1; | ||
450 | |||
451 | data.v_bstop = data.v_total; | ||
452 | data.v_sstart = yres + vfront - 1 - 2; | ||
453 | data.v_sstop = yres + vfront + vsync - 1; | ||
454 | |||
455 | #if 0 /* testing */ | ||
456 | |||
457 | printk("HBS: %i\n", data.h_bstart); | ||
458 | printk("HSS: %i\n", data.h_sstart); | ||
459 | printk("HSE: %i\n", data.h_sstop); | ||
460 | printk("HBE: %i\n", data.h_bstop); | ||
461 | printk("HT: %i\n", data.h_total); | ||
462 | |||
463 | printk("hsync: %i\n", hsync); | ||
464 | printk("hfront: %i\n", hfront); | ||
465 | printk("hback: %i\n", hback); | ||
466 | |||
467 | printk("VBS: %i\n", data.v_bstart); | ||
468 | printk("VSS: %i\n", data.v_sstart); | ||
469 | printk("VSE: %i\n", data.v_sstop); | ||
470 | printk("VBE: %i\n", data.v_bstop); | ||
471 | printk("VT: %i\n", data.v_total); | ||
472 | |||
473 | printk("vsync: %i\n", vsync); | ||
474 | printk("vfront: %i\n", vfront); | ||
475 | printk("vback: %i\n", vback); | ||
476 | #endif | ||
477 | |||
478 | if (data.v_total >= 1024) | ||
479 | printk(KERN_ERR "MAYDAY: v_total >= 1024; bailing out!\n"); | ||
480 | |||
481 | reg_w(regs, GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04)); | ||
482 | reg_w(regs, GREG_FEATURE_CONTROL_W, 0x00); | ||
483 | |||
484 | seq_w(regs, SEQ_RESET, 0x00); | ||
485 | seq_w(regs, SEQ_RESET, 0x03); /* reset sequencer logic */ | ||
486 | |||
487 | /* | ||
488 | * CLOCKING_MODE bits: | ||
489 | * 2: This one is only set for certain text-modes, wonder if | ||
490 | * it may be for EGA-lines? (it was referred to as CLKDIV2) | ||
491 | * (The CL drivers sets it to 0x21 with the comment: | ||
492 | * FullBandwidth (video off) and 8/9 dot clock) | ||
493 | */ | ||
494 | seq_w(regs, SEQ_CLOCKING_MODE, 0x01 | 0x00 /* 0x08 */); | ||
495 | |||
496 | seq_w(regs, SEQ_MAP_MASK, 0x0f); /* enable writing to plane 0-3 */ | ||
497 | seq_w(regs, SEQ_CHAR_MAP_SELECT, 0x00); /* doesn't matter in gfx-mode */ | ||
498 | seq_w(regs, SEQ_MEMORY_MODE, 0x06); /* CL driver says 0x0e for 256 col mode*/ | ||
499 | seq_w(regs, SEQ_RESET, 0x01); | ||
500 | seq_w(regs, SEQ_RESET, 0x03); | ||
501 | |||
502 | seq_w(regs, SEQ_EXTENDED_ENABLE, 0x05); | ||
503 | |||
504 | seq_w(regs, SEQ_CURSOR_CONTROL, 0x00); /* disable cursor */ | ||
505 | seq_w(regs, SEQ_PRIM_HOST_OFF_HI, 0x00); | ||
506 | seq_w(regs, SEQ_PRIM_HOST_OFF_HI, 0x00); | ||
507 | seq_w(regs, SEQ_LINEAR_0, 0x4a); | ||
508 | seq_w(regs, SEQ_LINEAR_1, 0x00); | ||
509 | |||
510 | seq_w(regs, SEQ_SEC_HOST_OFF_HI, 0x00); | ||
511 | seq_w(regs, SEQ_SEC_HOST_OFF_LO, 0x00); | ||
512 | seq_w(regs, SEQ_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); | ||
513 | |||
514 | /* | ||
515 | * The lower 4 bits (0-3) are used to set the font-width for | ||
516 | * text-mode - DON'T try to set this for gfx-mode. | ||
517 | */ | ||
518 | seq_w(regs, SEQ_EXT_CLOCK_MODE, 0x10); | ||
519 | seq_w(regs, SEQ_EXT_VIDEO_ADDR, 0x03); | ||
520 | |||
521 | /* | ||
522 | * Extended Pixel Control: | ||
523 | * bit 0: text-mode=0, gfx-mode=1 (Graphics Byte ?) | ||
524 | * bit 1: (Packed/Nibble Pixel Format ?) | ||
525 | * bit 4-5: depth, 0=1-8bpp, 1=9-16bpp, 2=17-24bpp | ||
526 | */ | ||
527 | seq_w(regs, SEQ_EXT_PIXEL_CNTL, 0x01 | (((bpp / 8) - 1) << 4)); | ||
528 | |||
529 | seq_w(regs, SEQ_BUS_WIDTH_FEEDB, 0x04); | ||
530 | seq_w(regs, SEQ_COLOR_EXP_WFG, 0x01); | ||
531 | seq_w(regs, SEQ_COLOR_EXP_WBG, 0x00); | ||
532 | seq_w(regs, SEQ_EXT_RW_CONTROL, 0x00); | ||
533 | seq_w(regs, SEQ_MISC_FEATURE_SEL, (0x51 | (clocksel & 8))); | ||
534 | seq_w(regs, SEQ_COLOR_KEY_CNTL, 0x40); | ||
535 | seq_w(regs, SEQ_COLOR_KEY_MATCH0, 0x00); | ||
536 | seq_w(regs, SEQ_COLOR_KEY_MATCH1, 0x00); | ||
537 | seq_w(regs, SEQ_COLOR_KEY_MATCH2, 0x00); | ||
538 | seq_w(regs, SEQ_CRC_CONTROL, 0x00); | ||
539 | seq_w(regs, SEQ_PERF_SELECT, 0x10); | ||
540 | seq_w(regs, SEQ_ACM_APERTURE_1, 0x00); | ||
541 | seq_w(regs, SEQ_ACM_APERTURE_2, 0x30); | ||
542 | seq_w(regs, SEQ_ACM_APERTURE_3, 0x00); | ||
543 | seq_w(regs, SEQ_MEMORY_MAP_CNTL, 0x03); | ||
544 | |||
545 | |||
546 | /* unlock register CRT0..CRT7 */ | ||
547 | crt_w(regs, CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20); | ||
548 | |||
549 | /* Zuerst zu schreibende Werte nur per printk ausgeben */ | ||
550 | DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total); | ||
551 | crt_w(regs, CRT_HOR_TOTAL, data.h_total & 0xff); | ||
552 | |||
553 | DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend); | ||
554 | crt_w(regs, CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff); | ||
555 | |||
556 | DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart); | ||
557 | crt_w(regs, CRT_START_HOR_BLANK, data.h_bstart & 0xff); | ||
558 | |||
559 | DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32); | ||
560 | crt_w(regs, CRT_END_HOR_BLANK, 0x80 | (data.h_bstop & 0x1f)); | ||
561 | |||
562 | DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart); | ||
563 | crt_w(regs, CRT_START_HOR_RETR, data.h_sstart & 0xff); | ||
564 | |||
565 | tmp = (data.h_sstop & 0x1f); | ||
566 | if (data.h_bstop & 0x20) | ||
567 | tmp |= 0x80; | ||
568 | DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp); | ||
569 | crt_w(regs, CRT_END_HOR_RETR, tmp); | ||
570 | |||
571 | DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff); | ||
572 | crt_w(regs, CRT_VER_TOTAL, (data.v_total & 0xff)); | ||
573 | |||
574 | tmp = 0x10; /* LineCompare bit #9 */ | ||
575 | if (data.v_total & 256) | ||
576 | tmp |= 0x01; | ||
577 | if (data.v_dispend & 256) | ||
578 | tmp |= 0x02; | ||
579 | if (data.v_sstart & 256) | ||
580 | tmp |= 0x04; | ||
581 | if (data.v_bstart & 256) | ||
582 | tmp |= 0x08; | ||
583 | if (data.v_total & 512) | ||
584 | tmp |= 0x20; | ||
585 | if (data.v_dispend & 512) | ||
586 | tmp |= 0x40; | ||
587 | if (data.v_sstart & 512) | ||
588 | tmp |= 0x80; | ||
589 | DEBUG printk("CRT_OVERFLOW: %d\n", tmp); | ||
590 | crt_w(regs, CRT_OVERFLOW, tmp); | ||
591 | |||
592 | crt_w(regs, CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */ | ||
593 | |||
594 | tmp = 0x40; /* LineCompare bit #8 */ | ||
595 | if (data.v_bstart & 512) | ||
596 | tmp |= 0x20; | ||
597 | if (var->vmode & FB_VMODE_DOUBLE) | ||
598 | tmp |= 0x80; | ||
599 | DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp); | ||
600 | crt_w(regs, CRT_MAX_SCAN_LINE, tmp); | ||
601 | |||
602 | crt_w(regs, CRT_CURSOR_START, 0x00); | ||
603 | crt_w(regs, CRT_CURSOR_END, 8 & 0x1f); /* font height */ | ||
604 | |||
605 | crt_w(regs, CRT_START_ADDR_HIGH, 0x00); | ||
606 | crt_w(regs, CRT_START_ADDR_LOW, 0x00); | ||
607 | |||
608 | crt_w(regs, CRT_CURSOR_LOC_HIGH, 0x00); | ||
609 | crt_w(regs, CRT_CURSOR_LOC_LOW, 0x00); | ||
610 | |||
611 | DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff); | ||
612 | crt_w(regs, CRT_START_VER_RETR, (data.v_sstart & 0xff)); | ||
613 | |||
614 | #if 1 | ||
615 | /* 5 refresh cycles per scanline */ | ||
616 | DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16); | ||
617 | crt_w(regs, CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20)); | ||
618 | #else | ||
619 | DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16); | ||
620 | crt_w(regs, CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32)); | ||
621 | #endif | ||
622 | DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff); | ||
623 | crt_w(regs, CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff)); | ||
624 | |||
625 | DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff); | ||
626 | crt_w(regs, CRT_START_VER_BLANK, (data.v_bstart & 0xff)); | ||
627 | |||
628 | DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff); | ||
629 | crt_w(regs, CRT_END_VER_BLANK, (data.v_bstop & 0xff)); | ||
630 | |||
631 | DEBUG printk("CRT_MODE_CONTROL: 0xe3\n"); | ||
632 | crt_w(regs, CRT_MODE_CONTROL, 0xe3); | ||
633 | |||
634 | DEBUG printk("CRT_LINE_COMPARE: 0xff\n"); | ||
635 | crt_w(regs, CRT_LINE_COMPARE, 0xff); | ||
636 | |||
637 | tmp = (var->xres_virtual / 8) * (bpp / 8); | ||
638 | crt_w(regs, CRT_OFFSET, tmp); | ||
639 | |||
640 | crt_w(regs, CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */ | ||
641 | |||
642 | tmp = 0x20; /* Enable extended end bits */ | ||
643 | if (data.h_total & 0x100) | ||
644 | tmp |= 0x01; | ||
645 | if ((data.h_dispend) & 0x100) | ||
646 | tmp |= 0x02; | ||
647 | if (data.h_bstart & 0x100) | ||
648 | tmp |= 0x04; | ||
649 | if (data.h_sstart & 0x100) | ||
650 | tmp |= 0x08; | ||
651 | if (var->vmode & FB_VMODE_INTERLACED) | ||
652 | tmp |= 0x10; | ||
653 | DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp); | ||
654 | crt_w(regs, CRT_EXT_HOR_TIMING1, tmp); | ||
655 | |||
656 | tmp = 0x00; | ||
657 | if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100) | ||
658 | tmp |= 0x10; | ||
659 | crt_w(regs, CRT_EXT_START_ADDR, tmp); | ||
660 | |||
661 | tmp = 0x00; | ||
662 | if (data.h_total & 0x200) | ||
663 | tmp |= 0x01; | ||
664 | if ((data.h_dispend) & 0x200) | ||
665 | tmp |= 0x02; | ||
666 | if (data.h_bstart & 0x200) | ||
667 | tmp |= 0x04; | ||
668 | if (data.h_sstart & 0x200) | ||
669 | tmp |= 0x08; | ||
670 | tmp |= ((data.h_bstop & 0xc0) >> 2); | ||
671 | tmp |= ((data.h_sstop & 0x60) << 1); | ||
672 | crt_w(regs, CRT_EXT_HOR_TIMING2, tmp); | ||
673 | DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp); | ||
674 | |||
675 | tmp = 0x10; /* Line compare bit 10 */ | ||
676 | if (data.v_total & 0x400) | ||
677 | tmp |= 0x01; | ||
678 | if ((data.v_dispend) & 0x400) | ||
679 | tmp |= 0x02; | ||
680 | if (data.v_bstart & 0x400) | ||
681 | tmp |= 0x04; | ||
682 | if (data.v_sstart & 0x400) | ||
683 | tmp |= 0x08; | ||
684 | tmp |= ((data.v_bstop & 0x300) >> 3); | ||
685 | if (data.v_sstop & 0x10) | ||
686 | tmp |= 0x80; | ||
687 | crt_w(regs, CRT_EXT_VER_TIMING, tmp); | ||
688 | DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp); | ||
689 | |||
690 | crt_w(regs, CRT_MONITOR_POWER, 0x00); | ||
691 | |||
692 | /* | ||
693 | * Convert from ps to Hz. | ||
694 | */ | ||
695 | freq = 2000000000 / var->pixclock; | ||
696 | freq = freq * 500; | ||
697 | |||
698 | best_freq = find_fq(freq); | ||
699 | pll_w(regs, 0x02, best_freq); | ||
700 | best_freq = find_fq(61000000); | ||
701 | pll_w(regs, 0x0a, best_freq); | ||
702 | pll_w(regs, 0x0e, 0x22); | ||
703 | |||
704 | gfx_w(regs, GFX_SET_RESET, 0x00); | ||
705 | gfx_w(regs, GFX_ENABLE_SET_RESET, 0x00); | ||
706 | gfx_w(regs, GFX_COLOR_COMPARE, 0x00); | ||
707 | gfx_w(regs, GFX_DATA_ROTATE, 0x00); | ||
708 | gfx_w(regs, GFX_READ_MAP_SELECT, 0x00); | ||
709 | gfx_w(regs, GFX_GRAPHICS_MODE, 0x00); | ||
710 | gfx_w(regs, GFX_MISC, 0x05); | ||
711 | gfx_w(regs, GFX_COLOR_XCARE, 0x0f); | ||
712 | gfx_w(regs, GFX_BITMASK, 0xff); | ||
713 | |||
714 | reg_r(regs, ACT_ADDRESS_RESET); | ||
715 | attr_w(regs, ACT_PALETTE0 , 0x00); | ||
716 | attr_w(regs, ACT_PALETTE1 , 0x01); | ||
717 | attr_w(regs, ACT_PALETTE2 , 0x02); | ||
718 | attr_w(regs, ACT_PALETTE3 , 0x03); | ||
719 | attr_w(regs, ACT_PALETTE4 , 0x04); | ||
720 | attr_w(regs, ACT_PALETTE5 , 0x05); | ||
721 | attr_w(regs, ACT_PALETTE6 , 0x06); | ||
722 | attr_w(regs, ACT_PALETTE7 , 0x07); | ||
723 | attr_w(regs, ACT_PALETTE8 , 0x08); | ||
724 | attr_w(regs, ACT_PALETTE9 , 0x09); | ||
725 | attr_w(regs, ACT_PALETTE10, 0x0a); | ||
726 | attr_w(regs, ACT_PALETTE11, 0x0b); | ||
727 | attr_w(regs, ACT_PALETTE12, 0x0c); | ||
728 | attr_w(regs, ACT_PALETTE13, 0x0d); | ||
729 | attr_w(regs, ACT_PALETTE14, 0x0e); | ||
730 | attr_w(regs, ACT_PALETTE15, 0x0f); | ||
731 | reg_r(regs, ACT_ADDRESS_RESET); | ||
732 | |||
733 | attr_w(regs, ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */ | ||
734 | |||
735 | attr_w(regs, ACT_OVERSCAN_COLOR, 0x00); | ||
736 | attr_w(regs, ACT_COLOR_PLANE_ENA, 0x0f); | ||
737 | attr_w(regs, ACT_HOR_PEL_PANNING, 0x00); | ||
738 | attr_w(regs, ACT_COLOR_SELECT, 0x00); | ||
739 | |||
740 | reg_r(regs, ACT_ADDRESS_RESET); | ||
741 | reg_w(regs, ACT_DATA, 0x20); | ||
742 | |||
743 | reg_w(regs, VDAC_MASK, 0xff); | ||
744 | |||
745 | /* | ||
746 | * Extended palette addressing ??? | ||
747 | */ | ||
748 | switch (bpp){ | ||
749 | case 8: | ||
750 | reg_w(regs, 0x83c6, 0x00); | ||
751 | break; | ||
752 | case 16: | ||
753 | reg_w(regs, 0x83c6, 0x60); | ||
754 | break; | ||
755 | case 24: | ||
756 | reg_w(regs, 0x83c6, 0xe0); | ||
757 | break; | ||
758 | default: | ||
759 | printk(KERN_INFO "Illegal color-depth: %i\n", bpp); | ||
760 | } | ||
761 | |||
762 | reg_w(regs, VDAC_ADDRESS, 0x00); | ||
763 | |||
764 | seq_w(regs, SEQ_MAP_MASK, 0x0f ); | ||
765 | |||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | |||
770 | /* | ||
771 | * This function should fill in the `fix' structure based on the | ||
772 | * values in the `par' structure. | ||
773 | */ | ||
774 | |||
775 | static int retz3_encode_fix(struct fb_info *info, | ||
776 | struct fb_fix_screeninfo *fix, | ||
777 | struct retz3fb_par *par) | ||
778 | { | ||
779 | struct retz3_fb_info *zinfo = retz3info(info); | ||
780 | |||
781 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | ||
782 | strcpy(fix->id, retz3fb_name); | ||
783 | fix->smem_start = zinfo->physfbmem; | ||
784 | fix->smem_len = zinfo->fbsize; | ||
785 | fix->mmio_start = zinfo->physregs; | ||
786 | fix->mmio_len = 0x00c00000; | ||
787 | |||
788 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
789 | fix->type_aux = 0; | ||
790 | if (par->bpp == 8) | ||
791 | fix->visual = FB_VISUAL_PSEUDOCOLOR; | ||
792 | else | ||
793 | fix->visual = FB_VISUAL_TRUECOLOR; | ||
794 | |||
795 | fix->xpanstep = 0; | ||
796 | fix->ypanstep = 0; | ||
797 | fix->ywrapstep = 0; | ||
798 | fix->line_length = 0; | ||
799 | |||
800 | fix->accel = FB_ACCEL_NCR_77C32BLT; | ||
801 | |||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | |||
806 | /* | ||
807 | * Get the video params out of `var'. If a value doesn't fit, round | ||
808 | * it up, if it's too big, return -EINVAL. | ||
809 | */ | ||
810 | |||
811 | static int retz3_decode_var(struct fb_var_screeninfo *var, | ||
812 | struct retz3fb_par *par) | ||
813 | { | ||
814 | par->xres = var->xres; | ||
815 | par->yres = var->yres; | ||
816 | par->xres_vir = var->xres_virtual; | ||
817 | par->yres_vir = var->yres_virtual; | ||
818 | par->bpp = var->bits_per_pixel; | ||
819 | par->pixclock = var->pixclock; | ||
820 | par->vmode = var->vmode; | ||
821 | |||
822 | par->red = var->red; | ||
823 | par->green = var->green; | ||
824 | par->blue = var->blue; | ||
825 | par->transp = var->transp; | ||
826 | |||
827 | par->left_margin = var->left_margin; | ||
828 | par->right_margin = var->right_margin; | ||
829 | par->upper_margin = var->upper_margin; | ||
830 | par->lower_margin = var->lower_margin; | ||
831 | par->hsync_len = var->hsync_len; | ||
832 | par->vsync_len = var->vsync_len; | ||
833 | |||
834 | if (var->accel_flags & FB_ACCELF_TEXT) | ||
835 | par->accel = FB_ACCELF_TEXT; | ||
836 | else | ||
837 | par->accel = 0; | ||
838 | |||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | |||
843 | /* | ||
844 | * Fill the `var' structure based on the values in `par' and maybe | ||
845 | * other values read out of the hardware. | ||
846 | */ | ||
847 | |||
848 | static int retz3_encode_var(struct fb_var_screeninfo *var, | ||
849 | struct retz3fb_par *par) | ||
850 | { | ||
851 | memset(var, 0, sizeof(struct fb_var_screeninfo)); | ||
852 | var->xres = par->xres; | ||
853 | var->yres = par->yres; | ||
854 | var->xres_virtual = par->xres_vir; | ||
855 | var->yres_virtual = par->yres_vir; | ||
856 | var->xoffset = 0; | ||
857 | var->yoffset = 0; | ||
858 | |||
859 | var->bits_per_pixel = par->bpp; | ||
860 | var->grayscale = 0; | ||
861 | |||
862 | var->red = par->red; | ||
863 | var->green = par->green; | ||
864 | var->blue = par->blue; | ||
865 | var->transp = par->transp; | ||
866 | |||
867 | var->nonstd = 0; | ||
868 | var->activate = 0; | ||
869 | |||
870 | var->height = -1; | ||
871 | var->width = -1; | ||
872 | |||
873 | var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0; | ||
874 | |||
875 | var->pixclock = par->pixclock; | ||
876 | |||
877 | var->sync = 0; /* ??? */ | ||
878 | var->left_margin = par->left_margin; | ||
879 | var->right_margin = par->right_margin; | ||
880 | var->upper_margin = par->upper_margin; | ||
881 | var->lower_margin = par->lower_margin; | ||
882 | var->hsync_len = par->hsync_len; | ||
883 | var->vsync_len = par->vsync_len; | ||
884 | |||
885 | var->vmode = par->vmode; | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | |||
890 | /* | ||
891 | * Set a single color register. Return != 0 for invalid regno. | ||
892 | */ | ||
893 | |||
894 | static int retz3fb_setcolreg(unsigned int regno, unsigned int red, | ||
895 | unsigned int green, unsigned int blue, | ||
896 | unsigned int transp, struct fb_info *info) | ||
897 | { | ||
898 | struct retz3_fb_info *zinfo = retz3info(info); | ||
899 | volatile unsigned char *regs = zinfo->regs; | ||
900 | |||
901 | /* We'll get to this */ | ||
902 | |||
903 | if (regno > 255) | ||
904 | return 1; | ||
905 | |||
906 | red >>= 10; | ||
907 | green >>= 10; | ||
908 | blue >>= 10; | ||
909 | |||
910 | zinfo->color_table[regno][0] = red; | ||
911 | zinfo->color_table[regno][1] = green; | ||
912 | zinfo->color_table[regno][2] = blue; | ||
913 | |||
914 | reg_w(regs, VDAC_ADDRESS_W, regno); | ||
915 | reg_w(regs, VDAC_DATA, red); | ||
916 | reg_w(regs, VDAC_DATA, green); | ||
917 | reg_w(regs, VDAC_DATA, blue); | ||
918 | |||
919 | return 0; | ||
920 | } | ||
921 | |||
922 | |||
923 | /* | ||
924 | * Read a single color register and split it into | ||
925 | * colors/transparent. Return != 0 for invalid regno. | ||
926 | */ | ||
927 | |||
928 | static int retz3_getcolreg(unsigned int regno, unsigned int *red, | ||
929 | unsigned int *green, unsigned int *blue, | ||
930 | unsigned int *transp, struct fb_info *info) | ||
931 | { | ||
932 | struct retz3_fb_info *zinfo = retz3info(info); | ||
933 | int t; | ||
934 | |||
935 | if (regno > 255) | ||
936 | return 1; | ||
937 | t = zinfo->color_table[regno][0]; | ||
938 | *red = (t<<10) | (t<<4) | (t>>2); | ||
939 | t = zinfo->color_table[regno][1]; | ||
940 | *green = (t<<10) | (t<<4) | (t>>2); | ||
941 | t = zinfo->color_table[regno][2]; | ||
942 | *blue = (t<<10) | (t<<4) | (t>>2); | ||
943 | *transp = 0; | ||
944 | return 0; | ||
945 | } | ||
946 | |||
947 | |||
948 | static inline void retz3_busy(struct display *p) | ||
949 | { | ||
950 | struct retz3_fb_info *zinfo = retz3info(p->fb_info); | ||
951 | volatile unsigned char *acm = zinfo->base + ACM_OFFSET; | ||
952 | unsigned char blt_status; | ||
953 | |||
954 | if (zinfo->blitbusy) { | ||
955 | do{ | ||
956 | blt_status = *((acm) + (ACM_START_STATUS + 2)); | ||
957 | }while ((blt_status & 1) == 0); | ||
958 | zinfo->blitbusy = 0; | ||
959 | } | ||
960 | } | ||
961 | |||
962 | |||
963 | static void retz3_bitblt (struct display *p, | ||
964 | unsigned short srcx, unsigned short srcy, | ||
965 | unsigned short destx, unsigned short desty, | ||
966 | unsigned short width, unsigned short height, | ||
967 | unsigned short cmd, unsigned short mask) | ||
968 | { | ||
969 | struct fb_var_screeninfo *var = &p->var; | ||
970 | struct retz3_fb_info *zinfo = retz3info(p->fb_info); | ||
971 | volatile unsigned long *acm = (unsigned long *)(zinfo->base + ACM_OFFSET); | ||
972 | unsigned long *pattern = (unsigned long *)(zinfo->fbmem + PAT_MEM_OFF); | ||
973 | |||
974 | unsigned short mod; | ||
975 | unsigned long tmp; | ||
976 | unsigned long pat, src, dst; | ||
977 | |||
978 | int i, xres_virtual = var->xres_virtual; | ||
979 | short bpp = (var->bits_per_pixel & 0xff); | ||
980 | |||
981 | if (bpp < 8) | ||
982 | bpp = 8; | ||
983 | |||
984 | tmp = mask | (mask << 16); | ||
985 | |||
986 | retz3_busy(p); | ||
987 | |||
988 | i = 0; | ||
989 | do{ | ||
990 | *pattern++ = tmp; | ||
991 | }while(i++ < bpp/4); | ||
992 | |||
993 | tmp = cmd << 8; | ||
994 | *(acm + ACM_RASTEROP_ROTATION/4) = tmp; | ||
995 | |||
996 | mod = 0xc0c2; | ||
997 | |||
998 | pat = 8 * PAT_MEM_OFF; | ||
999 | dst = bpp * (destx + desty * xres_virtual); | ||
1000 | |||
1001 | /* | ||
1002 | * Source is not set for clear. | ||
1003 | */ | ||
1004 | if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) { | ||
1005 | src = bpp * (srcx + srcy * xres_virtual); | ||
1006 | |||
1007 | if (destx > srcx) { | ||
1008 | mod &= ~0x8000; | ||
1009 | src += bpp * (width - 1); | ||
1010 | dst += bpp * (width - 1); | ||
1011 | pat += bpp * 2; | ||
1012 | } | ||
1013 | if (desty > srcy) { | ||
1014 | mod &= ~0x4000; | ||
1015 | src += bpp * (height - 1) * xres_virtual; | ||
1016 | dst += bpp * (height - 1) * xres_virtual; | ||
1017 | pat += bpp * 4; | ||
1018 | } | ||
1019 | |||
1020 | *(acm + ACM_SOURCE/4) = cpu_to_le32(src); | ||
1021 | } | ||
1022 | |||
1023 | *(acm + ACM_PATTERN/4) = cpu_to_le32(pat); | ||
1024 | |||
1025 | *(acm + ACM_DESTINATION/4) = cpu_to_le32(dst); | ||
1026 | |||
1027 | tmp = mod << 16; | ||
1028 | *(acm + ACM_CONTROL/4) = tmp; | ||
1029 | |||
1030 | tmp = width | (height << 16); | ||
1031 | |||
1032 | *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp); | ||
1033 | |||
1034 | *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; | ||
1035 | *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; | ||
1036 | zinfo->blitbusy = 1; | ||
1037 | } | ||
1038 | |||
1039 | #if 0 | ||
1040 | /* | ||
1041 | * Move cursor to x, y | ||
1042 | */ | ||
1043 | static void retz3_MoveCursor (unsigned short x, unsigned short y) | ||
1044 | { | ||
1045 | /* Guess we gotta deal with the cursor at some point */ | ||
1046 | } | ||
1047 | #endif | ||
1048 | |||
1049 | |||
1050 | /* | ||
1051 | * Fill the hardware's `par' structure. | ||
1052 | */ | ||
1053 | |||
1054 | static void retz3fb_get_par(struct fb_info *info, struct retz3fb_par *par) | ||
1055 | { | ||
1056 | struct retz3_fb_info *zinfo = retz3info(info); | ||
1057 | |||
1058 | if (zinfo->current_par_valid) | ||
1059 | *par = zinfo->current_par; | ||
1060 | else | ||
1061 | retz3_decode_var(&retz3fb_default, par); | ||
1062 | } | ||
1063 | |||
1064 | |||
1065 | static void retz3fb_set_par(struct fb_info *info, struct retz3fb_par *par) | ||
1066 | { | ||
1067 | struct retz3_fb_info *zinfo = retz3info(info); | ||
1068 | |||
1069 | zinfo->current_par = *par; | ||
1070 | zinfo->current_par_valid = 1; | ||
1071 | } | ||
1072 | |||
1073 | |||
1074 | static int do_fb_set_var(struct fb_info *info, | ||
1075 | struct fb_var_screeninfo *var, int isactive) | ||
1076 | { | ||
1077 | int err, activate; | ||
1078 | struct retz3fb_par par; | ||
1079 | struct retz3_fb_info *zinfo = retz3info(info); | ||
1080 | |||
1081 | if ((err = retz3_decode_var(var, &par))) | ||
1082 | return err; | ||
1083 | activate = var->activate; | ||
1084 | |||
1085 | /* XXX ... what to do about isactive ? */ | ||
1086 | |||
1087 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) | ||
1088 | retz3fb_set_par(info, &par); | ||
1089 | retz3_encode_var(var, &par); | ||
1090 | var->activate = activate; | ||
1091 | |||
1092 | retz3_set_video(info, var, &zinfo->current_par); | ||
1093 | |||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | /* | ||
1098 | * Get the Fixed Part of the Display | ||
1099 | */ | ||
1100 | |||
1101 | static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
1102 | struct fb_info *info) | ||
1103 | { | ||
1104 | struct retz3fb_par par; | ||
1105 | int error = 0; | ||
1106 | |||
1107 | if (con == -1) | ||
1108 | retz3fb_get_par(info, &par); | ||
1109 | else | ||
1110 | error = retz3_decode_var(&fb_display[con].var, &par); | ||
1111 | return(error ? error : retz3_encode_fix(info, fix, &par)); | ||
1112 | } | ||
1113 | |||
1114 | |||
1115 | /* | ||
1116 | * Get the User Defined Part of the Display | ||
1117 | */ | ||
1118 | |||
1119 | static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, | ||
1120 | struct fb_info *info) | ||
1121 | { | ||
1122 | struct retz3fb_par par; | ||
1123 | int error = 0; | ||
1124 | |||
1125 | if (con == -1) { | ||
1126 | retz3fb_get_par(info, &par); | ||
1127 | error = retz3_encode_var(var, &par); | ||
1128 | } else | ||
1129 | *var = fb_display[con].var; | ||
1130 | return error; | ||
1131 | } | ||
1132 | |||
1133 | |||
1134 | static void retz3fb_set_disp(int con, struct fb_info *info) | ||
1135 | { | ||
1136 | struct fb_fix_screeninfo fix; | ||
1137 | struct display *display; | ||
1138 | struct retz3_fb_info *zinfo = retz3info(info); | ||
1139 | |||
1140 | if (con >= 0) | ||
1141 | display = &fb_display[con]; | ||
1142 | else | ||
1143 | display = &zinfo->disp; /* used during initialization */ | ||
1144 | |||
1145 | retz3fb_get_fix(&fix, con, info); | ||
1146 | |||
1147 | if (con == -1) | ||
1148 | con = 0; | ||
1149 | |||
1150 | display->visual = fix.visual; | ||
1151 | display->type = fix.type; | ||
1152 | display->type_aux = fix.type_aux; | ||
1153 | display->ypanstep = fix.ypanstep; | ||
1154 | display->ywrapstep = fix.ywrapstep; | ||
1155 | display->can_soft_blank = 1; | ||
1156 | display->inverse = z3fb_inverse; | ||
1157 | |||
1158 | /* | ||
1159 | * This seems to be about 20% faster. | ||
1160 | */ | ||
1161 | display->scrollmode = SCROLL_YREDRAW; | ||
1162 | |||
1163 | switch (display->var.bits_per_pixel) { | ||
1164 | #ifdef FBCON_HAS_CFB8 | ||
1165 | case 8: | ||
1166 | if (display->var.accel_flags & FB_ACCELF_TEXT) { | ||
1167 | display->dispsw = &fbcon_retz3_8; | ||
1168 | retz3_set_video(info, &display->var, &zinfo->current_par); | ||
1169 | } else | ||
1170 | display->dispsw = &fbcon_cfb8; | ||
1171 | break; | ||
1172 | #endif | ||
1173 | #ifdef FBCON_HAS_CFB16 | ||
1174 | case 16: | ||
1175 | display->dispsw = &fbcon_cfb16; | ||
1176 | break; | ||
1177 | #endif | ||
1178 | default: | ||
1179 | display->dispsw = &fbcon_dummy; | ||
1180 | break; | ||
1181 | } | ||
1182 | } | ||
1183 | |||
1184 | |||
1185 | /* | ||
1186 | * Set the User Defined Part of the Display | ||
1187 | */ | ||
1188 | |||
1189 | static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, | ||
1190 | struct fb_info *info) | ||
1191 | { | ||
1192 | int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel; | ||
1193 | struct display *display; | ||
1194 | struct retz3_fb_info *zinfo = retz3info(info); | ||
1195 | |||
1196 | if (con >= 0) | ||
1197 | display = &fb_display[con]; | ||
1198 | else | ||
1199 | display = &zinfo->disp; /* used during initialization */ | ||
1200 | |||
1201 | if ((err = do_fb_set_var(info, var, con == info->currcon))) | ||
1202 | return err; | ||
1203 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { | ||
1204 | oldxres = display->var.xres; | ||
1205 | oldyres = display->var.yres; | ||
1206 | oldvxres = display->var.xres_virtual; | ||
1207 | oldvyres = display->var.yres_virtual; | ||
1208 | oldbpp = display->var.bits_per_pixel; | ||
1209 | oldaccel = display->var.accel_flags; | ||
1210 | display->var = *var; | ||
1211 | |||
1212 | if (oldxres != var->xres || oldyres != var->yres || | ||
1213 | oldvxres != var->xres_virtual || | ||
1214 | oldvyres != var->yres_virtual || | ||
1215 | oldbpp != var->bits_per_pixel || | ||
1216 | oldaccel != var->accel_flags) { | ||
1217 | |||
1218 | struct fb_fix_screeninfo fix; | ||
1219 | retz3fb_get_fix(&fix, con, info); | ||
1220 | |||
1221 | display->visual = fix.visual; | ||
1222 | display->type = fix.type; | ||
1223 | display->type_aux = fix.type_aux; | ||
1224 | display->ypanstep = fix.ypanstep; | ||
1225 | display->ywrapstep = fix.ywrapstep; | ||
1226 | display->line_length = fix.line_length; | ||
1227 | display->can_soft_blank = 1; | ||
1228 | display->inverse = z3fb_inverse; | ||
1229 | switch (display->var.bits_per_pixel) { | ||
1230 | #ifdef FBCON_HAS_CFB8 | ||
1231 | case 8: | ||
1232 | if (var->accel_flags & FB_ACCELF_TEXT) { | ||
1233 | display->dispsw = &fbcon_retz3_8; | ||
1234 | } else | ||
1235 | display->dispsw = &fbcon_cfb8; | ||
1236 | break; | ||
1237 | #endif | ||
1238 | #ifdef FBCON_HAS_CFB16 | ||
1239 | case 16: | ||
1240 | display->dispsw = &fbcon_cfb16; | ||
1241 | break; | ||
1242 | #endif | ||
1243 | default: | ||
1244 | display->dispsw = &fbcon_dummy; | ||
1245 | break; | ||
1246 | } | ||
1247 | /* | ||
1248 | * We still need to find a way to tell the X | ||
1249 | * server that the video mem has been fiddled with | ||
1250 | * so it redraws the entire screen when switching | ||
1251 | * between X and a text console. | ||
1252 | */ | ||
1253 | retz3_set_video(info, var, &zinfo->current_par); | ||
1254 | |||
1255 | if (info->changevar) | ||
1256 | (*info->changevar)(con); | ||
1257 | } | ||
1258 | |||
1259 | if (oldbpp != var->bits_per_pixel) { | ||
1260 | if ((err = fb_alloc_cmap(&display->cmap, 0, 0))) | ||
1261 | return err; | ||
1262 | do_install_cmap(con, info); | ||
1263 | } | ||
1264 | } | ||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | |||
1269 | /* | ||
1270 | * Get the Colormap | ||
1271 | */ | ||
1272 | |||
1273 | static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
1274 | struct fb_info *info) | ||
1275 | { | ||
1276 | if (con == info->currcon) /* current console? */ | ||
1277 | return(fb_get_cmap(cmap, kspc, retz3_getcolreg, info)); | ||
1278 | else if (fb_display[con].cmap.len) /* non default colormap? */ | ||
1279 | fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); | ||
1280 | else | ||
1281 | fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), | ||
1282 | cmap, kspc ? 0 : 2); | ||
1283 | return 0; | ||
1284 | } | ||
1285 | |||
1286 | /* | ||
1287 | * Blank the display. | ||
1288 | */ | ||
1289 | |||
1290 | static int retz3fb_blank(int blank, struct fb_info *info) | ||
1291 | { | ||
1292 | struct retz3_fb_info *zinfo = retz3info(info); | ||
1293 | volatile unsigned char *regs = retz3info(info)->regs; | ||
1294 | short i; | ||
1295 | |||
1296 | if (blank) | ||
1297 | for (i = 0; i < 256; i++){ | ||
1298 | reg_w(regs, VDAC_ADDRESS_W, i); | ||
1299 | reg_w(regs, VDAC_DATA, 0); | ||
1300 | reg_w(regs, VDAC_DATA, 0); | ||
1301 | reg_w(regs, VDAC_DATA, 0); | ||
1302 | } | ||
1303 | else | ||
1304 | for (i = 0; i < 256; i++){ | ||
1305 | reg_w(regs, VDAC_ADDRESS_W, i); | ||
1306 | reg_w(regs, VDAC_DATA, zinfo->color_table[i][0]); | ||
1307 | reg_w(regs, VDAC_DATA, zinfo->color_table[i][1]); | ||
1308 | reg_w(regs, VDAC_DATA, zinfo->color_table[i][2]); | ||
1309 | } | ||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1313 | static struct fb_ops retz3fb_ops = { | ||
1314 | .owner = THIS_MODULE, | ||
1315 | .fb_get_fix = retz3fb_get_fix, | ||
1316 | .fb_get_var = retz3fb_get_var, | ||
1317 | .fb_set_var = retz3fb_set_var, | ||
1318 | .fb_get_cmap = retz3fb_get_cmap, | ||
1319 | .fb_set_cmap = gen_set_cmap, | ||
1320 | .fb_setcolreg = retz3fb_setcolreg, | ||
1321 | .fb_blank = retz3fb_blank, | ||
1322 | }; | ||
1323 | |||
1324 | int __init retz3fb_setup(char *options) | ||
1325 | { | ||
1326 | char *this_opt; | ||
1327 | |||
1328 | if (!options || !*options) | ||
1329 | return 0; | ||
1330 | |||
1331 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
1332 | if (!*this_opt) | ||
1333 | continue; | ||
1334 | if (!strcmp(this_opt, "inverse")) { | ||
1335 | z3fb_inverse = 1; | ||
1336 | fb_invert_cmaps(); | ||
1337 | } else if (!strncmp(this_opt, "font:", 5)) { | ||
1338 | strlcpy(fontname, this_opt+5, sizeof(fontname)); | ||
1339 | } else | ||
1340 | z3fb_mode = get_video_mode(this_opt); | ||
1341 | } | ||
1342 | return 0; | ||
1343 | } | ||
1344 | |||
1345 | |||
1346 | /* | ||
1347 | * Initialization | ||
1348 | */ | ||
1349 | |||
1350 | int __init retz3fb_init(void) | ||
1351 | { | ||
1352 | unsigned long board_addr, board_size; | ||
1353 | struct zorro_dev *z = NULL; | ||
1354 | volatile unsigned char *regs; | ||
1355 | struct retz3fb_par par; | ||
1356 | struct retz3_fb_info *zinfo; | ||
1357 | struct fb_info *fb_info; | ||
1358 | short i; | ||
1359 | int res = -ENXIO; | ||
1360 | |||
1361 | while ((z = zorro_find_device(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, z))) { | ||
1362 | board_addr = z->resource.start; | ||
1363 | board_size = z->resource.end-z->resource.start+1; | ||
1364 | if (!request_mem_region(board_addr, 0x0c00000, | ||
1365 | "ncr77c32blt")) { | ||
1366 | continue; | ||
1367 | if (!request_mem_region(board_addr+VIDEO_MEM_OFFSET, | ||
1368 | 0x00400000, "RAM")) | ||
1369 | release_mem_region(board_addr, 0x00c00000); | ||
1370 | continue; | ||
1371 | } | ||
1372 | if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info), | ||
1373 | GFP_KERNEL))) | ||
1374 | return -ENOMEM; | ||
1375 | memset(zinfo, 0, sizeof(struct retz3_fb_info)); | ||
1376 | |||
1377 | zinfo->base = ioremap(board_addr, board_size); | ||
1378 | zinfo->regs = zinfo->base; | ||
1379 | zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET; | ||
1380 | /* Get memory size - for now we asume it's a 4MB board */ | ||
1381 | zinfo->fbsize = 0x00400000; /* 4 MB */ | ||
1382 | zinfo->physregs = board_addr; | ||
1383 | zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET; | ||
1384 | |||
1385 | fb_info = fbinfo(zinfo); | ||
1386 | |||
1387 | for (i = 0; i < 256; i++){ | ||
1388 | for (i = 0; i < 256; i++){ | ||
1389 | zinfo->color_table[i][0] = i; | ||
1390 | zinfo->color_table[i][1] = i; | ||
1391 | zinfo->color_table[i][2] = i; | ||
1392 | } | ||
1393 | } | ||
1394 | |||
1395 | regs = zinfo->regs; | ||
1396 | /* Disable hardware cursor */ | ||
1397 | seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00); | ||
1398 | |||
1399 | retz3fb_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info); | ||
1400 | retz3fb_setcolreg (254, 0, 0, 0, 0, fb_info); | ||
1401 | |||
1402 | strcpy(fb_info->modename, retz3fb_name); | ||
1403 | fb_info->changevar = NULL; | ||
1404 | fb_info->fbops = &retz3fb_ops; | ||
1405 | fb_info->screen_base = zinfo->fbmem; | ||
1406 | fb_info->disp = &zinfo->disp; | ||
1407 | fb_info->currcon = -1; | ||
1408 | fb_info->switch_con = &z3fb_switch; | ||
1409 | fb_info->updatevar = &z3fb_updatevar; | ||
1410 | fb_info->flags = FBINFO_FLAG_DEFAULT; | ||
1411 | strlcpy(fb_info->fontname, fontname, sizeof(fb_info->fontname)); | ||
1412 | |||
1413 | if (z3fb_mode == -1) | ||
1414 | retz3fb_default = retz3fb_predefined[0].var; | ||
1415 | |||
1416 | retz3_decode_var(&retz3fb_default, &par); | ||
1417 | retz3_encode_var(&retz3fb_default, &par); | ||
1418 | |||
1419 | do_fb_set_var(fb_info, &retz3fb_default, 0); | ||
1420 | retz3fb_get_var(&zinfo->disp.var, -1, fb_info); | ||
1421 | |||
1422 | retz3fb_set_disp(-1, fb_info); | ||
1423 | |||
1424 | do_install_cmap(0, fb_info); | ||
1425 | |||
1426 | if (register_framebuffer(fb_info) < 0) { | ||
1427 | iounmap(zinfo->base); | ||
1428 | return -EINVAL; | ||
1429 | } | ||
1430 | |||
1431 | printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of " | ||
1432 | "video memory\n", fb_info->node, | ||
1433 | fb_info->modename, zinfo->fbsize>>10); | ||
1434 | |||
1435 | /* FIXME: This driver cannot be unloaded yet */ | ||
1436 | res = 0; | ||
1437 | } | ||
1438 | return res; | ||
1439 | } | ||
1440 | |||
1441 | |||
1442 | static int z3fb_switch(int con, struct fb_info *info) | ||
1443 | { | ||
1444 | /* Do we have to save the colormap? */ | ||
1445 | if (fb_display[info->currcon].cmap.len) | ||
1446 | fb_get_cmap(&fb_display[info->currcon].cmap, 1, | ||
1447 | retz3_getcolreg, info); | ||
1448 | |||
1449 | do_fb_set_var(info, &fb_display[con].var, 1); | ||
1450 | info->currcon = con; | ||
1451 | /* Install new colormap */ | ||
1452 | do_install_cmap(con, info); | ||
1453 | return 0; | ||
1454 | } | ||
1455 | |||
1456 | |||
1457 | /* | ||
1458 | * Update the `var' structure (called by fbcon.c) | ||
1459 | * | ||
1460 | * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. | ||
1461 | * Since it's called by a kernel driver, no range checking is done. | ||
1462 | */ | ||
1463 | |||
1464 | static int z3fb_updatevar(int con, struct fb_info *info) | ||
1465 | { | ||
1466 | return 0; | ||
1467 | } | ||
1468 | |||
1469 | /* | ||
1470 | * Get a Video Mode | ||
1471 | */ | ||
1472 | |||
1473 | static int __init get_video_mode(const char *name) | ||
1474 | { | ||
1475 | short i; | ||
1476 | |||
1477 | for (i = 0; i < NUM_TOTAL_MODES; i++) | ||
1478 | if (!strcmp(name, retz3fb_predefined[i].name)){ | ||
1479 | retz3fb_default = retz3fb_predefined[i].var; | ||
1480 | return i; | ||
1481 | } | ||
1482 | return -1; | ||
1483 | } | ||
1484 | |||
1485 | |||
1486 | #ifdef MODULE | ||
1487 | MODULE_LICENSE("GPL"); | ||
1488 | |||
1489 | int init_module(void) | ||
1490 | { | ||
1491 | return retz3fb_init(); | ||
1492 | } | ||
1493 | #endif | ||
1494 | |||
1495 | |||
1496 | /* | ||
1497 | * Text console acceleration | ||
1498 | */ | ||
1499 | |||
1500 | #ifdef FBCON_HAS_CFB8 | ||
1501 | static void retz3_8_bmove(struct display *p, int sy, int sx, | ||
1502 | int dy, int dx, int height, int width) | ||
1503 | { | ||
1504 | int fontwidth = fontwidth(p); | ||
1505 | |||
1506 | sx *= fontwidth; | ||
1507 | dx *= fontwidth; | ||
1508 | width *= fontwidth; | ||
1509 | |||
1510 | retz3_bitblt(p, | ||
1511 | (unsigned short)sx, | ||
1512 | (unsigned short)(sy*fontheight(p)), | ||
1513 | (unsigned short)dx, | ||
1514 | (unsigned short)(dy*fontheight(p)), | ||
1515 | (unsigned short)width, | ||
1516 | (unsigned short)(height*fontheight(p)), | ||
1517 | Z3BLTcopy, | ||
1518 | 0xffff); | ||
1519 | } | ||
1520 | |||
1521 | static void retz3_8_clear(struct vc_data *conp, struct display *p, | ||
1522 | int sy, int sx, int height, int width) | ||
1523 | { | ||
1524 | unsigned short col; | ||
1525 | int fontwidth = fontwidth(p); | ||
1526 | |||
1527 | sx *= fontwidth; | ||
1528 | width *= fontwidth; | ||
1529 | |||
1530 | col = attr_bgcol_ec(p, conp); | ||
1531 | col &= 0xff; | ||
1532 | col |= (col << 8); | ||
1533 | |||
1534 | retz3_bitblt(p, | ||
1535 | (unsigned short)sx, | ||
1536 | (unsigned short)(sy*fontheight(p)), | ||
1537 | (unsigned short)sx, | ||
1538 | (unsigned short)(sy*fontheight(p)), | ||
1539 | (unsigned short)width, | ||
1540 | (unsigned short)(height*fontheight(p)), | ||
1541 | Z3BLTset, | ||
1542 | col); | ||
1543 | } | ||
1544 | |||
1545 | |||
1546 | static void retz3_putc(struct vc_data *conp, struct display *p, int c, | ||
1547 | int yy, int xx) | ||
1548 | { | ||
1549 | retz3_busy(p); | ||
1550 | fbcon_cfb8_putc(conp, p, c, yy, xx); | ||
1551 | } | ||
1552 | |||
1553 | |||
1554 | static void retz3_putcs(struct vc_data *conp, struct display *p, | ||
1555 | const unsigned short *s, int count, | ||
1556 | int yy, int xx) | ||
1557 | { | ||
1558 | retz3_busy(p); | ||
1559 | fbcon_cfb8_putcs(conp, p, s, count, yy, xx); | ||
1560 | } | ||
1561 | |||
1562 | |||
1563 | static void retz3_revc(struct display *p, int xx, int yy) | ||
1564 | { | ||
1565 | retz3_busy(p); | ||
1566 | fbcon_cfb8_revc(p, xx, yy); | ||
1567 | } | ||
1568 | |||
1569 | |||
1570 | static void retz3_clear_margins(struct vc_data* conp, struct display* p, | ||
1571 | int bottom_only) | ||
1572 | { | ||
1573 | retz3_busy(p); | ||
1574 | fbcon_cfb8_clear_margins(conp, p, bottom_only); | ||
1575 | } | ||
1576 | |||
1577 | |||
1578 | static struct display_switch fbcon_retz3_8 = { | ||
1579 | .setup = fbcon_cfb8_setup, | ||
1580 | .bmove = retz3_8_bmove, | ||
1581 | .clear = retz3_8_clear, | ||
1582 | .putc = retz3_putc, | ||
1583 | .putcs = retz3_putcs, | ||
1584 | .revc = retz3_revc, | ||
1585 | .clear_margins = retz3_clear_margins, | ||
1586 | .fontwidthmask = FONTWIDTH(8) | ||
1587 | }; | ||
1588 | #endif | ||
diff --git a/drivers/video/retz3fb.h b/drivers/video/retz3fb.h deleted file mode 100644 index 5cc75106772..00000000000 --- a/drivers/video/retz3fb.h +++ /dev/null | |||
@@ -1,286 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/retz3fb.h -- Defines and macros for the RetinaZ3 frame | ||
3 | * buffer device | ||
4 | * | ||
5 | * Copyright (C) 1997 Jes Sorensen | ||
6 | * | ||
7 | * History: | ||
8 | * - 22 Jan 97: Initial work | ||
9 | * | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file COPYING in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * Macros to read and write to registers. | ||
18 | */ | ||
19 | #define reg_w(regs, reg,dat) (*(regs + reg) = dat) | ||
20 | #define reg_r(regs, reg) (*(regs + reg)) | ||
21 | |||
22 | /* | ||
23 | * Macro to access the sequencer. | ||
24 | */ | ||
25 | #define seq_w(regs, sreg, sdat) \ | ||
26 | do{ reg_w(regs, SEQ_IDX, sreg); reg_w(regs, SEQ_DATA, sdat); } while(0) | ||
27 | |||
28 | /* | ||
29 | * Macro to access the CRT controller. | ||
30 | */ | ||
31 | #define crt_w(regs, creg, cdat) \ | ||
32 | do{ reg_w(regs, CRT_IDX, creg); reg_w(regs, CRT_DATA, cdat); } while(0) | ||
33 | |||
34 | /* | ||
35 | * Macro to access the graphics controller. | ||
36 | */ | ||
37 | #define gfx_w(regs, greg, gdat) \ | ||
38 | do{ reg_w(regs, GFX_IDX, greg); reg_w(regs, GFX_DATA, gdat); } while(0) | ||
39 | |||
40 | /* | ||
41 | * Macro to access the attribute controller. | ||
42 | */ | ||
43 | #define attr_w(regs, areg, adat) \ | ||
44 | do{ reg_w(regs, ACT_IDX, areg); reg_w(regs, ACT_DATA, adat); } while(0) | ||
45 | |||
46 | /* | ||
47 | * Macro to access the pll. | ||
48 | */ | ||
49 | #define pll_w(regs, preg, pdat) \ | ||
50 | do{ reg_w(regs, PLL_IDX, preg); \ | ||
51 | reg_w(regs, PLL_DATA, (pdat & 0xff)); \ | ||
52 | reg_w(regs, PLL_DATA, (pdat >> 8));\ | ||
53 | } while(0) | ||
54 | |||
55 | /* | ||
56 | * Offsets | ||
57 | */ | ||
58 | #define VIDEO_MEM_OFFSET 0x00c00000 | ||
59 | #define ACM_OFFSET 0x00b00000 | ||
60 | |||
61 | /* | ||
62 | * Accelerator Control Menu | ||
63 | */ | ||
64 | #define ACM_PRIMARY_OFFSET 0x00 | ||
65 | #define ACM_SECONDARY_OFFSET 0x04 | ||
66 | #define ACM_MODE_CONTROL 0x08 | ||
67 | #define ACM_CURSOR_POSITION 0x0c | ||
68 | #define ACM_START_STATUS 0x30 | ||
69 | #define ACM_CONTROL 0x34 | ||
70 | #define ACM_RASTEROP_ROTATION 0x38 | ||
71 | #define ACM_BITMAP_DIMENSION 0x3c | ||
72 | #define ACM_DESTINATION 0x40 | ||
73 | #define ACM_SOURCE 0x44 | ||
74 | #define ACM_PATTERN 0x48 | ||
75 | #define ACM_FOREGROUND 0x4c | ||
76 | #define ACM_BACKGROUND 0x50 | ||
77 | |||
78 | /* | ||
79 | * Video DAC addresses | ||
80 | */ | ||
81 | #define VDAC_ADDRESS 0x03c8 | ||
82 | #define VDAC_ADDRESS_W 0x03c8 | ||
83 | #define VDAC_ADDRESS_R 0x03c7 | ||
84 | #define VDAC_STATE 0x03c7 | ||
85 | #define VDAC_DATA 0x03c9 | ||
86 | #define VDAC_MASK 0x03c6 | ||
87 | |||
88 | /* | ||
89 | * Sequencer | ||
90 | */ | ||
91 | #define SEQ_IDX 0x03c4 /* Sequencer Index */ | ||
92 | #define SEQ_DATA 0x03c5 | ||
93 | #define SEQ_RESET 0x00 | ||
94 | #define SEQ_CLOCKING_MODE 0x01 | ||
95 | #define SEQ_MAP_MASK 0x02 | ||
96 | #define SEQ_CHAR_MAP_SELECT 0x03 | ||
97 | #define SEQ_MEMORY_MODE 0x04 | ||
98 | #define SEQ_EXTENDED_ENABLE 0x05 /* NCR extensions */ | ||
99 | #define SEQ_UNKNOWN1 0x06 | ||
100 | #define SEQ_UNKNOWN2 0x07 | ||
101 | #define SEQ_CHIP_ID 0x08 | ||
102 | #define SEQ_UNKNOWN3 0x09 | ||
103 | #define SEQ_CURSOR_COLOR1 0x0a | ||
104 | #define SEQ_CURSOR_COLOR0 0x0b | ||
105 | #define SEQ_CURSOR_CONTROL 0x0c | ||
106 | #define SEQ_CURSOR_X_LOC_HI 0x0d | ||
107 | #define SEQ_CURSOR_X_LOC_LO 0x0e | ||
108 | #define SEQ_CURSOR_Y_LOC_HI 0x0f | ||
109 | #define SEQ_CURSOR_Y_LOC_LO 0x10 | ||
110 | #define SEQ_CURSOR_X_INDEX 0x11 | ||
111 | #define SEQ_CURSOR_Y_INDEX 0x12 | ||
112 | #define SEQ_CURSOR_STORE_HI 0x13 | ||
113 | #define SEQ_CURSOR_STORE_LO 0x14 | ||
114 | #define SEQ_CURSOR_ST_OFF_HI 0x15 | ||
115 | #define SEQ_CURSOR_ST_OFF_LO 0x16 | ||
116 | #define SEQ_CURSOR_PIXELMASK 0x17 | ||
117 | #define SEQ_PRIM_HOST_OFF_HI 0x18 | ||
118 | #define SEQ_PRIM_HOST_OFF_LO 0x19 | ||
119 | #define SEQ_LINEAR_0 0x1a | ||
120 | #define SEQ_LINEAR_1 0x1b | ||
121 | #define SEQ_SEC_HOST_OFF_HI 0x1c | ||
122 | #define SEQ_SEC_HOST_OFF_LO 0x1d | ||
123 | #define SEQ_EXTENDED_MEM_ENA 0x1e | ||
124 | #define SEQ_EXT_CLOCK_MODE 0x1f | ||
125 | #define SEQ_EXT_VIDEO_ADDR 0x20 | ||
126 | #define SEQ_EXT_PIXEL_CNTL 0x21 | ||
127 | #define SEQ_BUS_WIDTH_FEEDB 0x22 | ||
128 | #define SEQ_PERF_SELECT 0x23 | ||
129 | #define SEQ_COLOR_EXP_WFG 0x24 | ||
130 | #define SEQ_COLOR_EXP_WBG 0x25 | ||
131 | #define SEQ_EXT_RW_CONTROL 0x26 | ||
132 | #define SEQ_MISC_FEATURE_SEL 0x27 | ||
133 | #define SEQ_COLOR_KEY_CNTL 0x28 | ||
134 | #define SEQ_COLOR_KEY_MATCH0 0x29 | ||
135 | #define SEQ_COLOR_KEY_MATCH1 0x2a | ||
136 | #define SEQ_COLOR_KEY_MATCH2 0x2b | ||
137 | #define SEQ_UNKNOWN6 0x2c | ||
138 | #define SEQ_CRC_CONTROL 0x2d | ||
139 | #define SEQ_CRC_DATA_LOW 0x2e | ||
140 | #define SEQ_CRC_DATA_HIGH 0x2f | ||
141 | #define SEQ_MEMORY_MAP_CNTL 0x30 | ||
142 | #define SEQ_ACM_APERTURE_1 0x31 | ||
143 | #define SEQ_ACM_APERTURE_2 0x32 | ||
144 | #define SEQ_ACM_APERTURE_3 0x33 | ||
145 | #define SEQ_BIOS_UTILITY_0 0x3e | ||
146 | #define SEQ_BIOS_UTILITY_1 0x3f | ||
147 | |||
148 | /* | ||
149 | * Graphics Controller | ||
150 | */ | ||
151 | #define GFX_IDX 0x03ce | ||
152 | #define GFX_DATA 0x03cf | ||
153 | #define GFX_SET_RESET 0x00 | ||
154 | #define GFX_ENABLE_SET_RESET 0x01 | ||
155 | #define GFX_COLOR_COMPARE 0x02 | ||
156 | #define GFX_DATA_ROTATE 0x03 | ||
157 | #define GFX_READ_MAP_SELECT 0x04 | ||
158 | #define GFX_GRAPHICS_MODE 0x05 | ||
159 | #define GFX_MISC 0x06 | ||
160 | #define GFX_COLOR_XCARE 0x07 | ||
161 | #define GFX_BITMASK 0x08 | ||
162 | |||
163 | /* | ||
164 | * CRT Controller | ||
165 | */ | ||
166 | #define CRT_IDX 0x03d4 | ||
167 | #define CRT_DATA 0x03d5 | ||
168 | #define CRT_HOR_TOTAL 0x00 | ||
169 | #define CRT_HOR_DISP_ENA_END 0x01 | ||
170 | #define CRT_START_HOR_BLANK 0x02 | ||
171 | #define CRT_END_HOR_BLANK 0x03 | ||
172 | #define CRT_START_HOR_RETR 0x04 | ||
173 | #define CRT_END_HOR_RETR 0x05 | ||
174 | #define CRT_VER_TOTAL 0x06 | ||
175 | #define CRT_OVERFLOW 0x07 | ||
176 | #define CRT_PRESET_ROW_SCAN 0x08 | ||
177 | #define CRT_MAX_SCAN_LINE 0x09 | ||
178 | #define CRT_CURSOR_START 0x0a | ||
179 | #define CRT_CURSOR_END 0x0b | ||
180 | #define CRT_START_ADDR_HIGH 0x0c | ||
181 | #define CRT_START_ADDR_LOW 0x0d | ||
182 | #define CRT_CURSOR_LOC_HIGH 0x0e | ||
183 | #define CRT_CURSOR_LOC_LOW 0x0f | ||
184 | #define CRT_START_VER_RETR 0x10 | ||
185 | #define CRT_END_VER_RETR 0x11 | ||
186 | #define CRT_VER_DISP_ENA_END 0x12 | ||
187 | #define CRT_OFFSET 0x13 | ||
188 | #define CRT_UNDERLINE_LOC 0x14 | ||
189 | #define CRT_START_VER_BLANK 0x15 | ||
190 | #define CRT_END_VER_BLANK 0x16 | ||
191 | #define CRT_MODE_CONTROL 0x17 | ||
192 | #define CRT_LINE_COMPARE 0x18 | ||
193 | #define CRT_UNKNOWN1 0x19 | ||
194 | #define CRT_UNKNOWN2 0x1a | ||
195 | #define CRT_UNKNOWN3 0x1b | ||
196 | #define CRT_UNKNOWN4 0x1c | ||
197 | #define CRT_UNKNOWN5 0x1d | ||
198 | #define CRT_UNKNOWN6 0x1e | ||
199 | #define CRT_UNKNOWN7 0x1f | ||
200 | #define CRT_UNKNOWN8 0x20 | ||
201 | #define CRT_UNKNOWN9 0x21 | ||
202 | #define CRT_UNKNOWN10 0x22 | ||
203 | #define CRT_UNKNOWN11 0x23 | ||
204 | #define CRT_UNKNOWN12 0x24 | ||
205 | #define CRT_UNKNOWN13 0x25 | ||
206 | #define CRT_UNKNOWN14 0x26 | ||
207 | #define CRT_UNKNOWN15 0x27 | ||
208 | #define CRT_UNKNOWN16 0x28 | ||
209 | #define CRT_UNKNOWN17 0x29 | ||
210 | #define CRT_UNKNOWN18 0x2a | ||
211 | #define CRT_UNKNOWN19 0x2b | ||
212 | #define CRT_UNKNOWN20 0x2c | ||
213 | #define CRT_UNKNOWN21 0x2d | ||
214 | #define CRT_UNKNOWN22 0x2e | ||
215 | #define CRT_UNKNOWN23 0x2f | ||
216 | #define CRT_EXT_HOR_TIMING1 0x30 /* NCR crt extensions */ | ||
217 | #define CRT_EXT_START_ADDR 0x31 | ||
218 | #define CRT_EXT_HOR_TIMING2 0x32 | ||
219 | #define CRT_EXT_VER_TIMING 0x33 | ||
220 | #define CRT_MONITOR_POWER 0x34 | ||
221 | |||
222 | /* | ||
223 | * General Registers | ||
224 | */ | ||
225 | #define GREG_STATUS0_R 0x03c2 | ||
226 | #define GREG_STATUS1_R 0x03da | ||
227 | #define GREG_MISC_OUTPUT_R 0x03cc | ||
228 | #define GREG_MISC_OUTPUT_W 0x03c2 | ||
229 | #define GREG_FEATURE_CONTROL_R 0x03ca | ||
230 | #define GREG_FEATURE_CONTROL_W 0x03da | ||
231 | #define GREG_POS 0x0102 | ||
232 | |||
233 | /* | ||
234 | * Attribute Controller | ||
235 | */ | ||
236 | #define ACT_IDX 0x03C0 | ||
237 | #define ACT_ADDRESS_R 0x03C0 | ||
238 | #define ACT_DATA 0x03C0 | ||
239 | #define ACT_ADDRESS_RESET 0x03DA | ||
240 | #define ACT_PALETTE0 0x00 | ||
241 | #define ACT_PALETTE1 0x01 | ||
242 | #define ACT_PALETTE2 0x02 | ||
243 | #define ACT_PALETTE3 0x03 | ||
244 | #define ACT_PALETTE4 0x04 | ||
245 | #define ACT_PALETTE5 0x05 | ||
246 | #define ACT_PALETTE6 0x06 | ||
247 | #define ACT_PALETTE7 0x07 | ||
248 | #define ACT_PALETTE8 0x08 | ||
249 | #define ACT_PALETTE9 0x09 | ||
250 | #define ACT_PALETTE10 0x0A | ||
251 | #define ACT_PALETTE11 0x0B | ||
252 | #define ACT_PALETTE12 0x0C | ||
253 | #define ACT_PALETTE13 0x0D | ||
254 | #define ACT_PALETTE14 0x0E | ||
255 | #define ACT_PALETTE15 0x0F | ||
256 | #define ACT_ATTR_MODE_CNTL 0x10 | ||
257 | #define ACT_OVERSCAN_COLOR 0x11 | ||
258 | #define ACT_COLOR_PLANE_ENA 0x12 | ||
259 | #define ACT_HOR_PEL_PANNING 0x13 | ||
260 | #define ACT_COLOR_SELECT 0x14 | ||
261 | |||
262 | /* | ||
263 | * PLL | ||
264 | */ | ||
265 | #define PLL_IDX 0x83c8 | ||
266 | #define PLL_DATA 0x83c9 | ||
267 | |||
268 | /* | ||
269 | * Blitter operations | ||
270 | */ | ||
271 | #define Z3BLTclear 0x00 /* 0 */ | ||
272 | #define Z3BLTand 0x80 /* src AND dst */ | ||
273 | #define Z3BLTandReverse 0x40 /* src AND NOT dst */ | ||
274 | #define Z3BLTcopy 0xc0 /* src */ | ||
275 | #define Z3BLTandInverted 0x20 /* NOT src AND dst */ | ||
276 | #define Z3BLTnoop 0xa0 /* dst */ | ||
277 | #define Z3BLTxor 0x60 /* src XOR dst */ | ||
278 | #define Z3BLTor 0xe0 /* src OR dst */ | ||
279 | #define Z3BLTnor 0x10 /* NOT src AND NOT dst */ | ||
280 | #define Z3BLTequiv 0x90 /* NOT src XOR dst */ | ||
281 | #define Z3BLTinvert 0x50 /* NOT dst */ | ||
282 | #define Z3BLTorReverse 0xd0 /* src OR NOT dst */ | ||
283 | #define Z3BLTcopyInverted 0x30 /* NOT src */ | ||
284 | #define Z3BLTorInverted 0xb0 /* NOT src OR dst */ | ||
285 | #define Z3BLTnand 0x70 /* NOT src OR NOT dst */ | ||
286 | #define Z3BLTset 0xf0 /* 1 */ | ||
diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c deleted file mode 100644 index f80356dfa8e..00000000000 --- a/drivers/video/sun3fb.c +++ /dev/null | |||
@@ -1,702 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/sun3fb.c -- Frame buffer driver for Sun3 | ||
3 | * | ||
4 | * (C) 1998 Thomas Bogendoerfer | ||
5 | * | ||
6 | * This driver is bases on sbusfb.c, which is | ||
7 | * | ||
8 | * Copyright (C) 1998 Jakub Jelinek | ||
9 | * | ||
10 | * This driver is partly based on the Open Firmware console driver | ||
11 | * | ||
12 | * Copyright (C) 1997 Geert Uytterhoeven | ||
13 | * | ||
14 | * and SPARC console subsystem | ||
15 | * | ||
16 | * Copyright (C) 1995 Peter Zaitcev (zaitcev@yahoo.com) | ||
17 | * Copyright (C) 1995-1997 David S. Miller (davem@caip.rutgers.edu) | ||
18 | * Copyright (C) 1995-1996 Miguel de Icaza (miguel@nuclecu.unam.mx) | ||
19 | * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) | ||
20 | * Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
21 | * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) | ||
22 | * | ||
23 | * This file is subject to the terms and conditions of the GNU General Public | ||
24 | * License. See the file COPYING in the main directory of this archive for | ||
25 | * more details. | ||
26 | */ | ||
27 | |||
28 | #include <linux/module.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/string.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/vmalloc.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/fb.h> | ||
38 | #include <linux/selection.h> | ||
39 | #include <linux/init.h> | ||
40 | #include <linux/console.h> | ||
41 | #include <linux/kd.h> | ||
42 | #include <linux/vt_kern.h> | ||
43 | |||
44 | #include <asm/uaccess.h> | ||
45 | #include <asm/pgtable.h> /* io_remap_page_range() */ | ||
46 | |||
47 | #ifdef CONFIG_SUN3 | ||
48 | #include <asm/oplib.h> | ||
49 | #include <asm/machines.h> | ||
50 | #include <asm/idprom.h> | ||
51 | |||
52 | #define CGFOUR_OBMEM_ADDR 0x1f300000 | ||
53 | #define BWTWO_OBMEM_ADDR 0x1f000000 | ||
54 | #define BWTWO_OBMEM50_ADDR 0x00100000 | ||
55 | |||
56 | #endif | ||
57 | #ifdef CONFIG_SUN3X | ||
58 | #include <asm/sun3x.h> | ||
59 | #endif | ||
60 | #include <video/sbusfb.h> | ||
61 | |||
62 | #define DEFAULT_CURSOR_BLINK_RATE (2*HZ/5) | ||
63 | |||
64 | #define CURSOR_SHAPE 1 | ||
65 | #define CURSOR_BLINK 2 | ||
66 | |||
67 | #define mymemset(x,y) memset(x,0,y) | ||
68 | |||
69 | /* | ||
70 | * Interface used by the world | ||
71 | */ | ||
72 | |||
73 | int sun3fb_init(void); | ||
74 | void sun3fb_setup(char *options); | ||
75 | |||
76 | static char fontname[40] __initdata = { 0 }; | ||
77 | static int curblink __initdata = 1; | ||
78 | |||
79 | static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
80 | struct fb_info *info); | ||
81 | static int sun3fb_get_var(struct fb_var_screeninfo *var, int con, | ||
82 | struct fb_info *info); | ||
83 | static int sun3fb_set_var(struct fb_var_screeninfo *var, int con, | ||
84 | struct fb_info *info); | ||
85 | static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
86 | struct fb_info *info); | ||
87 | static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
88 | struct fb_info *info); | ||
89 | static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
90 | u_int transp, struct fb_info *info); | ||
91 | static int sun3fb_blank(int blank, struct fb_info *info); | ||
92 | static void sun3fb_cursor(struct display *p, int mode, int x, int y); | ||
93 | static void sun3fb_clear_margin(struct display *p, int s); | ||
94 | |||
95 | /* | ||
96 | * Interface to the low level console driver | ||
97 | */ | ||
98 | |||
99 | static int sun3fbcon_switch(int con, struct fb_info *info); | ||
100 | static int sun3fbcon_updatevar(int con, struct fb_info *info); | ||
101 | |||
102 | /* | ||
103 | * Internal routines | ||
104 | */ | ||
105 | |||
106 | static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
107 | u_int *transp, struct fb_info *info); | ||
108 | |||
109 | static struct fb_ops sun3fb_ops = { | ||
110 | .owner = THIS_MODULE, | ||
111 | .fb_get_fix = sun3fb_get_fix, | ||
112 | .fb_get_var = sun3fb_get_var, | ||
113 | .fb_set_var = sun3fb_set_var, | ||
114 | .fb_get_cmap = sun3fb_get_cmap, | ||
115 | .fb_set_cmap = sun3fb_set_cmap, | ||
116 | .fb_setcolreg = sun3fb_setcolreg, | ||
117 | .fb_blank = sun3fb_blank, | ||
118 | }; | ||
119 | |||
120 | static void sun3fb_clear_margin(struct display *p, int s) | ||
121 | { | ||
122 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
123 | |||
124 | return; | ||
125 | |||
126 | if (fb->switch_from_graph) | ||
127 | (*fb->switch_from_graph)(fb); | ||
128 | if (fb->fill) { | ||
129 | unsigned short rects [16]; | ||
130 | |||
131 | rects [0] = 0; | ||
132 | rects [1] = 0; | ||
133 | rects [2] = fb->var.xres_virtual; | ||
134 | rects [3] = fb->y_margin; | ||
135 | rects [4] = 0; | ||
136 | rects [5] = fb->y_margin; | ||
137 | rects [6] = fb->x_margin; | ||
138 | rects [7] = fb->var.yres_virtual; | ||
139 | rects [8] = fb->var.xres_virtual - fb->x_margin; | ||
140 | rects [9] = fb->y_margin; | ||
141 | rects [10] = fb->var.xres_virtual; | ||
142 | rects [11] = fb->var.yres_virtual; | ||
143 | rects [12] = fb->x_margin; | ||
144 | rects [13] = fb->var.yres_virtual - fb->y_margin; | ||
145 | rects [14] = fb->var.xres_virtual - fb->x_margin; | ||
146 | rects [15] = fb->var.yres_virtual; | ||
147 | (*fb->fill)(fb, p, s, 4, rects); | ||
148 | } else { | ||
149 | unsigned char *fb_base = fb->info.screen_base, *q; | ||
150 | int skip_bytes = fb->y_margin * fb->var.xres_virtual; | ||
151 | int scr_size = fb->var.xres_virtual * fb->var.yres_virtual; | ||
152 | int h, he, incr, size; | ||
153 | |||
154 | he = fb->var.yres; | ||
155 | if (fb->var.bits_per_pixel == 1) { | ||
156 | fb_base -= (skip_bytes + fb->x_margin) / 8; | ||
157 | skip_bytes /= 8; | ||
158 | scr_size /= 8; | ||
159 | mymemset (fb_base, skip_bytes - fb->x_margin / 8); | ||
160 | mymemset (fb_base + scr_size - skip_bytes + fb->x_margin / 8, skip_bytes - fb->x_margin / 8); | ||
161 | incr = fb->var.xres_virtual / 8; | ||
162 | size = fb->x_margin / 8 * 2; | ||
163 | for (q = fb_base + skip_bytes - fb->x_margin / 8, h = 0; | ||
164 | h <= he; q += incr, h++) | ||
165 | mymemset (q, size); | ||
166 | } else { | ||
167 | fb_base -= (skip_bytes + fb->x_margin); | ||
168 | memset (fb_base, attr_bgcol(p,s), skip_bytes - fb->x_margin); | ||
169 | memset (fb_base + scr_size - skip_bytes + fb->x_margin, attr_bgcol(p,s), skip_bytes - fb->x_margin); | ||
170 | incr = fb->var.xres_virtual; | ||
171 | size = fb->x_margin * 2; | ||
172 | for (q = fb_base + skip_bytes - fb->x_margin, h = 0; | ||
173 | h <= he; q += incr, h++) | ||
174 | memset (q, attr_bgcol(p,s), size); | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static void sun3fb_disp_setup(struct display *p) | ||
180 | { | ||
181 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
182 | |||
183 | if (fb->setup) | ||
184 | fb->setup(p); | ||
185 | sun3fb_clear_margin(p, 0); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Get the Fixed Part of the Display | ||
190 | */ | ||
191 | |||
192 | static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
193 | struct fb_info *info) | ||
194 | { | ||
195 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
196 | |||
197 | memcpy(fix, &fb->fix, sizeof(struct fb_fix_screeninfo)); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Get the User Defined Part of the Display | ||
203 | */ | ||
204 | |||
205 | static int sun3fb_get_var(struct fb_var_screeninfo *var, int con, | ||
206 | struct fb_info *info) | ||
207 | { | ||
208 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
209 | |||
210 | memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo)); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Set the User Defined Part of the Display | ||
216 | */ | ||
217 | |||
218 | static int sun3fb_set_var(struct fb_var_screeninfo *var, int con, | ||
219 | struct fb_info *info) | ||
220 | { | ||
221 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
222 | |||
223 | if (var->xres > fb->var.xres || var->yres > fb->var.yres || | ||
224 | var->xres_virtual > fb->var.xres_virtual || | ||
225 | var->yres_virtual > fb->var.yres_virtual || | ||
226 | var->bits_per_pixel != fb->var.bits_per_pixel || | ||
227 | var->nonstd || | ||
228 | (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) | ||
229 | return -EINVAL; | ||
230 | memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo)); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * Hardware cursor | ||
236 | */ | ||
237 | |||
238 | static unsigned char hw_cursor_cmap[2] = { 0, 0xff }; | ||
239 | |||
240 | static void | ||
241 | sun3fb_cursor_timer_handler(unsigned long dev_addr) | ||
242 | { | ||
243 | struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)dev_addr; | ||
244 | |||
245 | if (!fb->setcursor) return; | ||
246 | |||
247 | if (fb->cursor.mode & CURSOR_BLINK) { | ||
248 | fb->cursor.enable ^= 1; | ||
249 | fb->setcursor(fb); | ||
250 | } | ||
251 | |||
252 | fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate; | ||
253 | add_timer(&fb->cursor.timer); | ||
254 | } | ||
255 | |||
256 | static void sun3fb_cursor(struct display *p, int mode, int x, int y) | ||
257 | { | ||
258 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
259 | |||
260 | switch (mode) { | ||
261 | case CM_ERASE: | ||
262 | fb->cursor.mode &= ~CURSOR_BLINK; | ||
263 | fb->cursor.enable = 0; | ||
264 | (*fb->setcursor)(fb); | ||
265 | break; | ||
266 | |||
267 | case CM_MOVE: | ||
268 | case CM_DRAW: | ||
269 | if (fb->cursor.mode & CURSOR_SHAPE) { | ||
270 | fb->cursor.size.fbx = fontwidth(p); | ||
271 | fb->cursor.size.fby = fontheight(p); | ||
272 | fb->cursor.chot.fbx = 0; | ||
273 | fb->cursor.chot.fby = 0; | ||
274 | fb->cursor.enable = 1; | ||
275 | memset (fb->cursor.bits, 0, sizeof (fb->cursor.bits)); | ||
276 | fb->cursor.bits[0][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p))); | ||
277 | fb->cursor.bits[1][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p))); | ||
278 | fb->cursor.bits[0][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p))); | ||
279 | fb->cursor.bits[1][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p))); | ||
280 | (*fb->setcursormap) (fb, hw_cursor_cmap, hw_cursor_cmap, hw_cursor_cmap); | ||
281 | (*fb->setcurshape) (fb); | ||
282 | } | ||
283 | fb->cursor.mode = CURSOR_BLINK; | ||
284 | if (fontwidthlog(p)) | ||
285 | fb->cursor.cpos.fbx = (x << fontwidthlog(p)) + fb->x_margin; | ||
286 | else | ||
287 | fb->cursor.cpos.fbx = (x * fontwidth(p)) + fb->x_margin; | ||
288 | if (fontheightlog(p)) | ||
289 | fb->cursor.cpos.fby = (y << fontheightlog(p)) + fb->y_margin; | ||
290 | else | ||
291 | fb->cursor.cpos.fby = (y * fontheight(p)) + fb->y_margin; | ||
292 | (*fb->setcursor)(fb); | ||
293 | break; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | * Get the Colormap | ||
299 | */ | ||
300 | |||
301 | static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
302 | struct fb_info *info) | ||
303 | { | ||
304 | if (con == info->currcon) /* current console? */ | ||
305 | return fb_get_cmap(cmap, kspc, sun3fb_getcolreg, info); | ||
306 | else if (fb_display[con].cmap.len) /* non default colormap? */ | ||
307 | fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); | ||
308 | else | ||
309 | fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2); | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Set the Colormap | ||
315 | */ | ||
316 | |||
317 | static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
318 | struct fb_info *info) | ||
319 | { | ||
320 | int err; | ||
321 | |||
322 | if (!fb_display[con].cmap.len) { /* no colormap allocated? */ | ||
323 | if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0))) | ||
324 | return err; | ||
325 | } | ||
326 | if (con == info->currcon) { /* current console? */ | ||
327 | err = fb_set_cmap(cmap, kspc, info); | ||
328 | if (!err) { | ||
329 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
330 | |||
331 | if (fb->loadcmap) | ||
332 | (*fb->loadcmap)(fb, &fb_display[con], cmap->start, cmap->len); | ||
333 | } | ||
334 | return err; | ||
335 | } else | ||
336 | fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); | ||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | * Setup: parse used options | ||
342 | */ | ||
343 | |||
344 | void __init sun3fb_setup(char *options) | ||
345 | { | ||
346 | char *p; | ||
347 | |||
348 | for (p = options;;) { | ||
349 | if (!strncmp(p, "font=", 5)) { | ||
350 | int i; | ||
351 | |||
352 | for (i = 0; i < sizeof(fontname) - 1; i++) | ||
353 | if (p[i+5] == ' ' || !p[i+5]) | ||
354 | break; | ||
355 | memcpy(fontname, p+5, i); | ||
356 | fontname[i] = 0; | ||
357 | } else if (!strncmp(p, "noblink", 7)) | ||
358 | curblink = 0; | ||
359 | while (*p && *p != ' ' && *p != ',') p++; | ||
360 | if (*p != ',') break; | ||
361 | p++; | ||
362 | } | ||
363 | |||
364 | return; | ||
365 | } | ||
366 | |||
367 | static int sun3fbcon_switch(int con, struct fb_info *info) | ||
368 | { | ||
369 | int x_margin, y_margin; | ||
370 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
371 | int lastconsole; | ||
372 | |||
373 | /* Do we have to save the colormap? */ | ||
374 | if (fb_display[info->currcon].cmap.len) | ||
375 | fb_get_cmap(&fb_display[info->currcon].cmap, 1, sun3fb_getcolreg, info); | ||
376 | |||
377 | if (info->display_fg) { | ||
378 | lastconsole = info->display_fg->vc_num; | ||
379 | if (lastconsole != con && | ||
380 | (fontwidth(&fb_display[lastconsole]) != fontwidth(&fb_display[con]) || | ||
381 | fontheight(&fb_display[lastconsole]) != fontheight(&fb_display[con]))) | ||
382 | fb->cursor.mode |= CURSOR_SHAPE; | ||
383 | } | ||
384 | x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2; | ||
385 | y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2; | ||
386 | if (fb->margins) | ||
387 | fb->margins(fb, &fb_display[con], x_margin, y_margin); | ||
388 | if (fb->graphmode || fb->x_margin != x_margin || fb->y_margin != y_margin) { | ||
389 | fb->x_margin = x_margin; fb->y_margin = y_margin; | ||
390 | sun3fb_clear_margin(&fb_display[con], 0); | ||
391 | } | ||
392 | info->currcon = con; | ||
393 | /* Install new colormap */ | ||
394 | do_install_cmap(con, info); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | /* | ||
399 | * Update the `var' structure (called by fbcon.c) | ||
400 | */ | ||
401 | |||
402 | static int sun3fbcon_updatevar(int con, struct fb_info *info) | ||
403 | { | ||
404 | /* Nothing */ | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | /* | ||
409 | * Blank the display. | ||
410 | */ | ||
411 | |||
412 | static int sun3fb_blank(int blank, struct fb_info *info) | ||
413 | { | ||
414 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
415 | |||
416 | if (blank && fb->blank) | ||
417 | return fb->blank(fb); | ||
418 | else if (!blank && fb->unblank) | ||
419 | return fb->unblank(fb); | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * Read a single color register and split it into | ||
425 | * colors/transparent. Return != 0 for invalid regno. | ||
426 | */ | ||
427 | |||
428 | static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
429 | u_int *transp, struct fb_info *info) | ||
430 | { | ||
431 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
432 | |||
433 | if (!fb->color_map || regno > 255) | ||
434 | return 1; | ||
435 | *red = (fb->color_map CM(regno, 0)<<8) | fb->color_map CM(regno, 0); | ||
436 | *green = (fb->color_map CM(regno, 1)<<8) | fb->color_map CM(regno, 1); | ||
437 | *blue = (fb->color_map CM(regno, 2)<<8) | fb->color_map CM(regno, 2); | ||
438 | *transp = 0; | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | |||
443 | /* | ||
444 | * Set a single color register. The values supplied are already | ||
445 | * rounded down to the hardware's capabilities (according to the | ||
446 | * entries in the var structure). Return != 0 for invalid regno. | ||
447 | */ | ||
448 | |||
449 | static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
450 | u_int transp, struct fb_info *info) | ||
451 | { | ||
452 | struct fb_info_sbusfb *fb = sbusfbinfo(info); | ||
453 | |||
454 | if (!fb->color_map || regno > 255) | ||
455 | return 1; | ||
456 | red >>= 8; | ||
457 | green >>= 8; | ||
458 | blue >>= 8; | ||
459 | fb->color_map CM(regno, 0) = red; | ||
460 | fb->color_map CM(regno, 1) = green; | ||
461 | fb->color_map CM(regno, 2) = blue; | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int sun3fb_set_font(struct display *p, int width, int height) | ||
466 | { | ||
467 | int w = p->var.xres_virtual, h = p->var.yres_virtual; | ||
468 | int depth = p->var.bits_per_pixel; | ||
469 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
470 | int x_margin, y_margin; | ||
471 | |||
472 | if (depth > 8) depth = 8; | ||
473 | x_margin = (w % width) / 2; | ||
474 | y_margin = (h % height) / 2; | ||
475 | |||
476 | p->var.xres = w - 2*x_margin; | ||
477 | p->var.yres = h - 2*y_margin; | ||
478 | |||
479 | fb->cursor.mode |= CURSOR_SHAPE; | ||
480 | |||
481 | if (fb->margins) | ||
482 | fb->margins(fb, p, x_margin, y_margin); | ||
483 | if (fb->x_margin != x_margin || fb->y_margin != y_margin) { | ||
484 | fb->x_margin = x_margin; fb->y_margin = y_margin; | ||
485 | sun3fb_clear_margin(p, 0); | ||
486 | } | ||
487 | |||
488 | return 1; | ||
489 | } | ||
490 | |||
491 | void sun3fb_palette(int enter) | ||
492 | { | ||
493 | int i; | ||
494 | struct display *p; | ||
495 | |||
496 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | ||
497 | p = &fb_display[i]; | ||
498 | if (p->dispsw && p->dispsw->setup == sun3fb_disp_setup && | ||
499 | p->fb_info->display_fg && | ||
500 | p->fb_info->display_fg->vc_num == i) { | ||
501 | struct fb_info_sbusfb *fb = sbusfbinfod(p); | ||
502 | |||
503 | if (fb->restore_palette) { | ||
504 | if (enter) | ||
505 | fb->restore_palette(fb); | ||
506 | else if (vc_cons[i].d->vc_mode != KD_GRAPHICS) | ||
507 | vc_cons[i].d->vc_sw->con_set_palette(vc_cons[i].d, color_table); | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * Initialisation | ||
515 | */ | ||
516 | static int __init sun3fb_init_fb(int fbtype, unsigned long addr) | ||
517 | { | ||
518 | static struct sbus_dev sdb; | ||
519 | struct fb_fix_screeninfo *fix; | ||
520 | struct fb_var_screeninfo *var; | ||
521 | struct display *disp; | ||
522 | struct fb_info_sbusfb *fb; | ||
523 | struct fbtype *type; | ||
524 | int linebytes, w, h, depth; | ||
525 | char *p = NULL; | ||
526 | |||
527 | fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC); | ||
528 | if (!fb) | ||
529 | return -ENOMEM; | ||
530 | |||
531 | memset(fb, 0, sizeof(struct fb_info_sbusfb)); | ||
532 | fix = &fb->fix; | ||
533 | var = &fb->var; | ||
534 | disp = &fb->disp; | ||
535 | type = &fb->type; | ||
536 | |||
537 | sdb.reg_addrs[0].phys_addr = addr; | ||
538 | fb->sbdp = &sdb; | ||
539 | |||
540 | type->fb_type = fbtype; | ||
541 | |||
542 | type->fb_height = h = 900; | ||
543 | type->fb_width = w = 1152; | ||
544 | sizechange: | ||
545 | type->fb_depth = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8; | ||
546 | linebytes = w * depth / 8; | ||
547 | type->fb_size = PAGE_ALIGN((linebytes) * h); | ||
548 | /* | ||
549 | fb->x_margin = (w & 7) / 2; | ||
550 | fb->y_margin = (h & 15) / 2; | ||
551 | */ | ||
552 | fb->x_margin = fb->y_margin = 0; | ||
553 | |||
554 | var->xres_virtual = w; | ||
555 | var->yres_virtual = h; | ||
556 | var->xres = w - 2*fb->x_margin; | ||
557 | var->yres = h - 2*fb->y_margin; | ||
558 | |||
559 | var->bits_per_pixel = depth; | ||
560 | var->height = var->width = -1; | ||
561 | var->pixclock = 10000; | ||
562 | var->vmode = FB_VMODE_NONINTERLACED; | ||
563 | var->red.length = var->green.length = var->blue.length = 8; | ||
564 | |||
565 | fix->line_length = linebytes; | ||
566 | fix->smem_len = type->fb_size; | ||
567 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
568 | fix->visual = FB_VISUAL_PSEUDOCOLOR; | ||
569 | |||
570 | fb->info.fbops = &sun3fb_ops; | ||
571 | fb->info.disp = disp; | ||
572 | fb->info.currcon = -1; | ||
573 | strcpy(fb->info.fontname, fontname); | ||
574 | fb->info.changevar = NULL; | ||
575 | fb->info.switch_con = &sun3fbcon_switch; | ||
576 | fb->info.updatevar = &sun3fbcon_updatevar; | ||
577 | fb->info.flags = FBINFO_FLAG_DEFAULT; | ||
578 | |||
579 | fb->cursor.hwsize.fbx = 32; | ||
580 | fb->cursor.hwsize.fby = 32; | ||
581 | |||
582 | if (depth > 1 && !fb->color_map) { | ||
583 | if((fb->color_map = kmalloc(256 * 3, GFP_ATOMIC))==NULL) | ||
584 | return -ENOMEM; | ||
585 | } | ||
586 | |||
587 | switch(fbtype) { | ||
588 | #ifdef CONFIG_FB_CGSIX | ||
589 | case FBTYPE_SUNFAST_COLOR: | ||
590 | p = cgsixfb_init(fb); break; | ||
591 | #endif | ||
592 | #ifdef CONFIG_FB_BWTWO | ||
593 | case FBTYPE_SUN2BW: | ||
594 | p = bwtwofb_init(fb); break; | ||
595 | #endif | ||
596 | #ifdef CONFIG_FB_CGTHREE | ||
597 | case FBTYPE_SUN4COLOR: | ||
598 | case FBTYPE_SUN3COLOR: | ||
599 | type->fb_size = 0x100000; | ||
600 | p = cgthreefb_init(fb); break; | ||
601 | #endif | ||
602 | } | ||
603 | fix->smem_start = (unsigned long)fb->info.screen_base; // FIXME | ||
604 | |||
605 | if (!p) { | ||
606 | kfree(fb); | ||
607 | return -ENODEV; | ||
608 | } | ||
609 | |||
610 | if (p == SBUSFBINIT_SIZECHANGE) | ||
611 | goto sizechange; | ||
612 | |||
613 | disp->dispsw = &fb->dispsw; | ||
614 | if (fb->setcursor) { | ||
615 | fb->dispsw.cursor = sun3fb_cursor; | ||
616 | if (curblink) { | ||
617 | fb->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE; | ||
618 | init_timer(&fb->cursor.timer); | ||
619 | fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate; | ||
620 | fb->cursor.timer.data = (unsigned long)fb; | ||
621 | fb->cursor.timer.function = sun3fb_cursor_timer_handler; | ||
622 | add_timer(&fb->cursor.timer); | ||
623 | } | ||
624 | } | ||
625 | fb->cursor.mode = CURSOR_SHAPE; | ||
626 | fb->dispsw.set_font = sun3fb_set_font; | ||
627 | fb->setup = fb->dispsw.setup; | ||
628 | fb->dispsw.setup = sun3fb_disp_setup; | ||
629 | fb->dispsw.clear_margins = NULL; | ||
630 | |||
631 | disp->var = *var; | ||
632 | disp->visual = fix->visual; | ||
633 | disp->type = fix->type; | ||
634 | disp->type_aux = fix->type_aux; | ||
635 | disp->line_length = fix->line_length; | ||
636 | |||
637 | if (fb->blank) | ||
638 | disp->can_soft_blank = 1; | ||
639 | |||
640 | sun3fb_set_var(var, -1, &fb->info); | ||
641 | |||
642 | if (register_framebuffer(&fb->info) < 0) { | ||
643 | kfree(fb); | ||
644 | return -EINVAL; | ||
645 | } | ||
646 | printk("fb%d: %s\n", fb->info.node, p); | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | |||
652 | int __init sun3fb_init(void) | ||
653 | { | ||
654 | extern int con_is_present(void); | ||
655 | unsigned long addr; | ||
656 | char p4id; | ||
657 | |||
658 | if (!con_is_present()) return -ENODEV; | ||
659 | #ifdef CONFIG_SUN3 | ||
660 | switch(*(romvec->pv_fbtype)) | ||
661 | { | ||
662 | case FBTYPE_SUN2BW: | ||
663 | addr = 0xfe20000; | ||
664 | return sun3fb_init_fb(FBTYPE_SUN2BW, addr); | ||
665 | case FBTYPE_SUN3COLOR: | ||
666 | case FBTYPE_SUN4COLOR: | ||
667 | if(idprom->id_machtype != (SM_SUN3|SM_3_60)) { | ||
668 | printk("sun3fb: cgthree/four only supported on 3/60\n"); | ||
669 | return -ENODEV; | ||
670 | } | ||
671 | |||
672 | addr = CGFOUR_OBMEM_ADDR; | ||
673 | return sun3fb_init_fb(*(romvec->pv_fbtype), addr); | ||
674 | default: | ||
675 | printk("sun3fb: unsupported framebuffer\n"); | ||
676 | return -ENODEV; | ||
677 | } | ||
678 | #else | ||
679 | addr = SUN3X_VIDEO_BASE; | ||
680 | p4id = *(char *)SUN3X_VIDEO_P4ID; | ||
681 | |||
682 | p4id = (p4id == 0x45) ? p4id : (p4id & 0xf0); | ||
683 | switch (p4id) { | ||
684 | case 0x00: | ||
685 | return sun3fb_init_fb(FBTYPE_SUN2BW, addr); | ||
686 | #if 0 /* not yet */ | ||
687 | case 0x40: | ||
688 | return sun3fb_init_fb(FBTYPE_SUN4COLOR, addr); | ||
689 | break; | ||
690 | case 0x45: | ||
691 | return sun3fb_init_fb(FBTYPE_SUN8COLOR, addr); | ||
692 | break; | ||
693 | #endif | ||
694 | case 0x60: | ||
695 | return sun3fb_init_fb(FBTYPE_SUNFAST_COLOR, addr); | ||
696 | } | ||
697 | #endif | ||
698 | |||
699 | return -ENODEV; | ||
700 | } | ||
701 | |||
702 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c deleted file mode 100644 index b9fb6fb3600..00000000000 --- a/drivers/video/virgefb.c +++ /dev/null | |||
@@ -1,2526 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/virgefb.c -- CyberVision64/3D frame buffer device | ||
3 | * | ||
4 | * Copyright (C) 1997 André Heynatz | ||
5 | * | ||
6 | * | ||
7 | * This file is based on the CyberVision frame buffer device (cyberfb.c): | ||
8 | * | ||
9 | * Copyright (C) 1996 Martin Apel | ||
10 | * Geert Uytterhoeven | ||
11 | * | ||
12 | * Zorro II additions : | ||
13 | * | ||
14 | * Copyright (C) 1998-2000 Christian T. Steigies | ||
15 | * | ||
16 | * Initialization additions : | ||
17 | * | ||
18 | * Copyright (C) 1998-2000 Ken Tyler | ||
19 | * | ||
20 | * Parts of the Initialization code are based on Cyberfb.c by Allan Bair, | ||
21 | * and on the NetBSD CyberVision64 frame buffer driver by Michael Teske who gave | ||
22 | * permission for its use. | ||
23 | * | ||
24 | * Many thanks to Frank Mariak for his assistance with ZORRO 2 access and other | ||
25 | * mysteries. | ||
26 | * | ||
27 | * | ||
28 | * | ||
29 | * This file is subject to the terms and conditions of the GNU General Public | ||
30 | * License. See the file COPYING in the main directory of this archive | ||
31 | * for more details. | ||
32 | */ | ||
33 | |||
34 | #undef VIRGEFBDEBUG | ||
35 | #undef VIRGEFBDUMP | ||
36 | |||
37 | #include <linux/module.h> | ||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/errno.h> | ||
40 | #include <linux/string.h> | ||
41 | #include <linux/mm.h> | ||
42 | #include <linux/slab.h> | ||
43 | #include <linux/delay.h> | ||
44 | #include <linux/zorro.h> | ||
45 | #include <linux/fb.h> | ||
46 | #include <linux/init.h> | ||
47 | #include <asm/uaccess.h> | ||
48 | #include <asm/system.h> | ||
49 | #include <asm/amigahw.h> | ||
50 | #include <asm/io.h> | ||
51 | #include <asm/irq.h> | ||
52 | #include <video/fbcon.h> | ||
53 | #include <video/fbcon-cfb8.h> | ||
54 | #include <video/fbcon-cfb16.h> | ||
55 | #include <video/fbcon-cfb32.h> | ||
56 | |||
57 | #include "virgefb.h" | ||
58 | |||
59 | #ifdef VIRGEFBDEBUG | ||
60 | #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) | ||
61 | #else | ||
62 | #define DPRINTK(fmt, args...) | ||
63 | #endif | ||
64 | |||
65 | #ifdef VIRGEFBDUMP | ||
66 | static void cv64_dump(void); | ||
67 | #define DUMP cv64_dump() | ||
68 | #else | ||
69 | #define DUMP | ||
70 | #endif | ||
71 | |||
72 | /* | ||
73 | * Macros for register access and zorro control | ||
74 | */ | ||
75 | |||
76 | static inline void mb_inline(void) { mb(); } /* for use in comma expressions */ | ||
77 | |||
78 | /* Set zorro 2 map */ | ||
79 | |||
80 | #define SelectIO \ | ||
81 | mb(); \ | ||
82 | if (on_zorro2) { \ | ||
83 | (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x01); \ | ||
84 | mb(); \ | ||
85 | } | ||
86 | |||
87 | #define SelectMMIO \ | ||
88 | mb(); \ | ||
89 | if (on_zorro2) { \ | ||
90 | (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x02); \ | ||
91 | mb(); \ | ||
92 | } | ||
93 | |||
94 | #define SelectCFG \ | ||
95 | mb(); \ | ||
96 | if (on_zorro2) { \ | ||
97 | (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x03); \ | ||
98 | mb(); \ | ||
99 | } | ||
100 | |||
101 | /* Set pass through, 0 = amiga, !=0 = cv64/3d */ | ||
102 | |||
103 | #define SetVSwitch(x) \ | ||
104 | mb(); \ | ||
105 | (*(volatile u16 *)((u8 *)(vcode_switch_base)) = \ | ||
106 | (u16)(x ? 0 : 1)); \ | ||
107 | mb(); | ||
108 | |||
109 | /* Zorro2 endian 'aperture' */ | ||
110 | |||
111 | #define ENDIAN_BYTE 2 | ||
112 | #define ENDIAN_WORD 1 | ||
113 | #define ENDIAN_LONG 0 | ||
114 | |||
115 | #define Select_Zorro2_FrameBuffer(x) \ | ||
116 | do { \ | ||
117 | if (on_zorro2) { \ | ||
118 | mb(); \ | ||
119 | (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x08)) = \ | ||
120 | (x * 0x40)); \ | ||
121 | mb(); \ | ||
122 | } \ | ||
123 | } while (0) | ||
124 | |||
125 | /* SetPortVal - only used for interrupt enable (not yet implemented) */ | ||
126 | |||
127 | #if 0 | ||
128 | #define SetPortVal(x) \ | ||
129 | mb(); \ | ||
130 | (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x0c)) = \ | ||
131 | (u16)x); \ | ||
132 | mb(); | ||
133 | #endif | ||
134 | |||
135 | /* IO access */ | ||
136 | |||
137 | #define byte_access_io(x) (((x) & 0x3ffc) | (((x) & 3)^3) | (((x) & 3) <<14)) | ||
138 | #define byte_access_mmio(x) (((x) & 0xfffc) | (((x) & 3)^3)) | ||
139 | |||
140 | /* Write 8 bit VGA register - used once for chip wakeup */ | ||
141 | |||
142 | #define wb_vgaio(reg, dat) \ | ||
143 | SelectIO; \ | ||
144 | (*(volatile u8 *)(vgaio_regs + ((u32)byte_access_io(reg) & 0xffff)) = \ | ||
145 | (dat & 0xff)); \ | ||
146 | SelectMMIO; | ||
147 | |||
148 | /* Read 8 bit VGA register - only used in dump (SelectIO not needed on read ?) */ | ||
149 | |||
150 | #ifdef VIRGEFBDUMP | ||
151 | #define rb_vgaio(reg) \ | ||
152 | ({ \ | ||
153 | u8 __zzyzx; \ | ||
154 | SelectIO; \ | ||
155 | __zzyzx = (*(volatile u8 *)((vgaio_regs)+(u32)byte_access_io(reg))); \ | ||
156 | SelectMMIO; \ | ||
157 | __zzyzx; \ | ||
158 | }) | ||
159 | #endif | ||
160 | |||
161 | /* MMIO access */ | ||
162 | |||
163 | /* Read 8 bit MMIO register */ | ||
164 | |||
165 | #define rb_mmio(reg) \ | ||
166 | (mb_inline(), \ | ||
167 | (*(volatile u8 *)(mmio_regs + 0x8000 + (u32)byte_access_mmio(reg)))) | ||
168 | |||
169 | /* Write 8 bit MMIO register */ | ||
170 | |||
171 | #define wb_mmio(reg,dat) \ | ||
172 | mb(); \ | ||
173 | (*(volatile u8 *)(mmio_regs + 0x8000 + (byte_access_mmio((reg) & 0xffff))) = \ | ||
174 | (dat & 0xff)); \ | ||
175 | mb(); | ||
176 | |||
177 | /* Read 32 bit MMIO register */ | ||
178 | |||
179 | #define rl_mmio(reg) \ | ||
180 | (mb_inline(), \ | ||
181 | (*((volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg)))))) | ||
182 | |||
183 | /* Write 32 bit MMIO register */ | ||
184 | |||
185 | #define wl_mmio(reg,dat) \ | ||
186 | mb(); \ | ||
187 | ((*(volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg)))) = \ | ||
188 | (u32)(dat)); \ | ||
189 | mb(); | ||
190 | |||
191 | /* Write to virge graphics register */ | ||
192 | |||
193 | #define wgfx(reg, dat) do { wb_mmio(GCT_ADDRESS, (reg)); wb_mmio(GCT_ADDRESS_W, (dat)); } while (0) | ||
194 | |||
195 | /* Write to virge sequencer register */ | ||
196 | |||
197 | #define wseq(reg, dat) do { wb_mmio(SEQ_ADDRESS, (reg)); wb_mmio(SEQ_ADDRESS_W, (dat)); } while (0) | ||
198 | |||
199 | /* Write to virge CRT controller register */ | ||
200 | |||
201 | #define wcrt(reg, dat) do { wb_mmio(CRT_ADDRESS, (reg)); wb_mmio(CRT_ADDRESS_W, (dat)); } while (0) | ||
202 | |||
203 | /* Write to virge attribute register */ | ||
204 | |||
205 | #define watr(reg, dat) \ | ||
206 | do { \ | ||
207 | volatile unsigned char watr_tmp; \ | ||
208 | watr_tmp = rb_mmio(ACT_ADDRESS_RESET); \ | ||
209 | wb_mmio(ACT_ADDRESS_W, (reg)); \ | ||
210 | wb_mmio(ACT_ADDRESS_W, (dat)); \ | ||
211 | udelay(10); \ | ||
212 | } while (0) | ||
213 | |||
214 | /* end of macros */ | ||
215 | |||
216 | struct virgefb_par { | ||
217 | struct fb_var_screeninfo var; | ||
218 | __u32 type; | ||
219 | __u32 type_aux; | ||
220 | __u32 visual; | ||
221 | __u32 line_length; | ||
222 | }; | ||
223 | |||
224 | static struct virgefb_par current_par; | ||
225 | |||
226 | static int current_par_valid = 0; | ||
227 | |||
228 | static struct display disp; | ||
229 | static struct fb_info fb_info; | ||
230 | |||
231 | static union { | ||
232 | #ifdef FBCON_HAS_CFB16 | ||
233 | u16 cfb16[16]; | ||
234 | #endif | ||
235 | #ifdef FBCON_HAS_CFB32 | ||
236 | u32 cfb32[16]; | ||
237 | #endif | ||
238 | } fbcon_cmap; | ||
239 | |||
240 | /* | ||
241 | * Switch for Chipset Independency | ||
242 | */ | ||
243 | |||
244 | static struct fb_hwswitch { | ||
245 | |||
246 | /* Initialisation */ | ||
247 | |||
248 | int (*init)(void); | ||
249 | |||
250 | /* Display Control */ | ||
251 | |||
252 | int (*encode_fix)(struct fb_fix_screeninfo *fix, struct virgefb_par *par); | ||
253 | int (*decode_var)(struct fb_var_screeninfo *var, struct virgefb_par *par); | ||
254 | int (*encode_var)(struct fb_var_screeninfo *var, struct virgefb_par *par); | ||
255 | int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
256 | u_int *transp, struct fb_info *info); | ||
257 | void (*blank)(int blank); | ||
258 | } *fbhw; | ||
259 | |||
260 | static unsigned char blit_maybe_busy = 0; | ||
261 | |||
262 | /* | ||
263 | * Frame Buffer Name | ||
264 | */ | ||
265 | |||
266 | static char virgefb_name[16] = "CyberVision/3D"; | ||
267 | |||
268 | /* | ||
269 | * CyberVision64/3d Graphics Board | ||
270 | */ | ||
271 | |||
272 | static unsigned char virgefb_colour_table [256][3]; | ||
273 | static unsigned long v_ram; | ||
274 | static unsigned long v_ram_size; | ||
275 | static volatile unsigned char *mmio_regs; | ||
276 | static volatile unsigned char *vgaio_regs; | ||
277 | |||
278 | static unsigned long v_ram_phys; | ||
279 | static unsigned long mmio_regs_phys; | ||
280 | static unsigned long vcode_switch_base; | ||
281 | static unsigned char on_zorro2; | ||
282 | |||
283 | /* | ||
284 | * Offsets from start of video ram to appropriate ZIII aperture | ||
285 | */ | ||
286 | |||
287 | #ifdef FBCON_HAS_CFB8 | ||
288 | #define CYBMEM_OFFSET_8 0x800000 /* BGRX */ | ||
289 | #endif | ||
290 | #ifdef FBCON_HAS_CFB16 | ||
291 | #define CYBMEM_OFFSET_16 0x400000 /* GBXR */ | ||
292 | #endif | ||
293 | #ifdef FBCON_HAS_CFB32 | ||
294 | #define CYBMEM_OFFSET_32 0x000000 /* XRGB */ | ||
295 | #endif | ||
296 | |||
297 | /* | ||
298 | * MEMCLOCK was 32MHz, 64MHz works, 72MHz doesn't (on my board) | ||
299 | */ | ||
300 | |||
301 | #define MEMCLOCK 50000000 | ||
302 | |||
303 | /* | ||
304 | * Predefined Video Modes | ||
305 | */ | ||
306 | |||
307 | static struct { | ||
308 | const char *name; | ||
309 | struct fb_var_screeninfo var; | ||
310 | } virgefb_predefined[] __initdata = { | ||
311 | #ifdef FBCON_HAS_CFB8 | ||
312 | { | ||
313 | "640x480-8", { /* Cybervision 8 bpp */ | ||
314 | 640, 480, 640, 480, 0, 0, 8, 0, | ||
315 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
316 | 0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2, | ||
317 | 0, FB_VMODE_NONINTERLACED | ||
318 | } | ||
319 | }, { | ||
320 | "768x576-8", { /* Cybervision 8 bpp */ | ||
321 | 768, 576, 768, 576, 0, 0, 8, 0, | ||
322 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
323 | 0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2, | ||
324 | 0, FB_VMODE_NONINTERLACED | ||
325 | } | ||
326 | }, { | ||
327 | "800x600-8", { /* Cybervision 8 bpp */ | ||
328 | 800, 600, 800, 600, 0, 0, 8, 0, | ||
329 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
330 | 0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2, | ||
331 | 0, FB_VMODE_NONINTERLACED | ||
332 | } | ||
333 | }, { | ||
334 | #if 0 | ||
335 | "1024x768-8", { /* Cybervision 8 bpp */ | ||
336 | 1024, 768, 1024, 768, 0, 0, 8, 0, | ||
337 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
338 | 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1, | ||
339 | 0, FB_VMODE_NONINTERLACED | ||
340 | } | ||
341 | #else | ||
342 | "1024x768-8", { | ||
343 | 1024, 768, 1024, 768, 0, 0, 8, 0, | ||
344 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
345 | #if 0 | ||
346 | 0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1, | ||
347 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
348 | } | ||
349 | #else | ||
350 | 0, 0, -1, -1, FB_ACCELF_TEXT, 12699, 176, 16, 28, 1, 96, 3, | ||
351 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
352 | } | ||
353 | #endif | ||
354 | #endif | ||
355 | }, { | ||
356 | "1152x886-8", { /* Cybervision 8 bpp */ | ||
357 | 1152, 886, 1152, 886, 0, 0, 8, 0, | ||
358 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
359 | 0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10, | ||
360 | 0, FB_VMODE_NONINTERLACED | ||
361 | } | ||
362 | }, { | ||
363 | "1280x1024-8", { /* Cybervision 8 bpp */ | ||
364 | 1280, 1024, 1280, 1024, 0, 0, 8, 0, | ||
365 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
366 | #if 0 | ||
367 | 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12, | ||
368 | } | ||
369 | #else | ||
370 | 0, 0, -1, -1, FB_ACCELF_TEXT, 7414, 232, 64, 38, 1, 112, 3, | ||
371 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
372 | } | ||
373 | #endif | ||
374 | }, { | ||
375 | "1600x1200-8", { /* Cybervision 8 bpp */ | ||
376 | 1600, 1200, 1600, 1200, 0, 0, 8, 0, | ||
377 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
378 | #if 0 | ||
379 | 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12, | ||
380 | 0, FB_VMODE_NONINTERLACED | ||
381 | } | ||
382 | #else | ||
383 | 0, 0, -1, -1, FB_ACCELF_TEXT, 6411, 256, 32, 52, 10, 160, 8, | ||
384 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
385 | } | ||
386 | #endif | ||
387 | }, | ||
388 | #endif | ||
389 | |||
390 | #ifdef FBCON_HAS_CFB16 | ||
391 | { | ||
392 | "640x480-16", { /* Cybervision 16 bpp */ | ||
393 | 640, 480, 640, 480, 0, 0, 16, 0, | ||
394 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
395 | 0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 152, 144, 82, 61, 88, 2, | ||
396 | 0, FB_VMODE_NONINTERLACED | ||
397 | } | ||
398 | }, { | ||
399 | "768x576-16", { /* Cybervision 16 bpp */ | ||
400 | 768, 576, 768, 576, 0, 0, 16, 0, | ||
401 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
402 | 0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2, | ||
403 | 0, FB_VMODE_NONINTERLACED | ||
404 | } | ||
405 | }, { | ||
406 | "800x600-16", { /* Cybervision 16 bpp */ | ||
407 | 800, 600, 800, 600, 0, 0, 16, 0, | ||
408 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
409 | 0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2, | ||
410 | 0, FB_VMODE_NONINTERLACED | ||
411 | } | ||
412 | }, { | ||
413 | #if 0 | ||
414 | "1024x768-16", { /* Cybervision 16 bpp */ | ||
415 | 1024, 768, 1024, 768, 0, 0, 16, 0, | ||
416 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
417 | 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1, | ||
418 | 0, FB_VMODE_NONINTERLACED | ||
419 | } | ||
420 | #else | ||
421 | "1024x768-16", { | ||
422 | 1024, 768, 1024, 768, 0, 0, 16, 0, | ||
423 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
424 | 0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1, | ||
425 | FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
426 | } | ||
427 | #endif | ||
428 | }, { | ||
429 | "1152x886-16", { /* Cybervision 16 bpp */ | ||
430 | 1152, 886, 1152, 886, 0, 0, 16, 0, | ||
431 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
432 | 0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10, | ||
433 | 0, FB_VMODE_NONINTERLACED | ||
434 | } | ||
435 | }, { | ||
436 | "1280x1024-16", { /* Cybervision 16 bpp */ | ||
437 | 1280, 1024, 1280, 1024, 0, 0, 16, 0, | ||
438 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
439 | 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12, | ||
440 | 0, FB_VMODE_NONINTERLACED | ||
441 | } | ||
442 | }, { | ||
443 | "1600x1200-16", { /* Cybervision 16 bpp */ | ||
444 | 1600, 1200, 1600, 1200, 0, 0, 16, 0, | ||
445 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
446 | 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12, | ||
447 | 0, FB_VMODE_NONINTERLACED | ||
448 | } | ||
449 | }, | ||
450 | #endif | ||
451 | |||
452 | #ifdef FBCON_HAS_CFB32 | ||
453 | { | ||
454 | "640x480-32", { /* Cybervision 32 bpp */ | ||
455 | 640, 480, 640, 480, 0, 0, 32, 0, | ||
456 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
457 | 0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2, | ||
458 | 0, FB_VMODE_NONINTERLACED | ||
459 | } | ||
460 | }, { | ||
461 | "768x576-32", { /* Cybervision 32 bpp */ | ||
462 | 768, 576, 768, 576, 0, 0, 32, 0, | ||
463 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
464 | 0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2, | ||
465 | 0, FB_VMODE_NONINTERLACED | ||
466 | } | ||
467 | }, { | ||
468 | "800x600-32", { /* Cybervision 32 bpp */ | ||
469 | 800, 600, 800, 600, 0, 0, 32, 0, | ||
470 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
471 | 0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2, | ||
472 | 0, FB_VMODE_NONINTERLACED | ||
473 | } | ||
474 | }, { | ||
475 | "1024x768-32", { /* Cybervision 32 bpp */ | ||
476 | 1024, 768, 1024, 768, 0, 0, 32, 0, | ||
477 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
478 | 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1, | ||
479 | 0, FB_VMODE_NONINTERLACED | ||
480 | } | ||
481 | }, { | ||
482 | "1152x886-32", { /* Cybervision 32 bpp */ | ||
483 | 1152, 886, 1152, 886, 0, 0, 32, 0, | ||
484 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
485 | 0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10, | ||
486 | 0, FB_VMODE_NONINTERLACED | ||
487 | } | ||
488 | }, { | ||
489 | "1280x1024-32", { /* Cybervision 32 bpp */ | ||
490 | 1280, 1024, 1280, 1024, 0, 0, 32, 0, | ||
491 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
492 | 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12, | ||
493 | 0, FB_VMODE_NONINTERLACED | ||
494 | } | ||
495 | }, { | ||
496 | "1600x1200-32", { /* Cybervision 32 bpp */ | ||
497 | 1600, 1200, 1600, 1200, 0, 0, 32, 0, | ||
498 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
499 | 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12, | ||
500 | 0, FB_VMODE_NONINTERLACED | ||
501 | } | ||
502 | }, | ||
503 | #endif | ||
504 | |||
505 | /* interlaced modes */ | ||
506 | |||
507 | #ifdef FBCON_HAS_CFB8 | ||
508 | { | ||
509 | "1024x768-8i", { /* Cybervision 8 bpp */ | ||
510 | 1024, 768, 1024, 768, 0, 0, 8, 0, | ||
511 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
512 | 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1, | ||
513 | 0, FB_VMODE_INTERLACED | ||
514 | } | ||
515 | }, { | ||
516 | "1280x1024-8i", { /* Cybervision 8 bpp */ | ||
517 | 1280, 1024, 1280, 1024, 0, 0, 8, 0, | ||
518 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
519 | 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12, | ||
520 | 0, FB_VMODE_INTERLACED | ||
521 | } | ||
522 | }, { | ||
523 | "1600x1200-8i", { /* Cybervision 8 bpp */ | ||
524 | 1600, 1200, 1600, 1200, 0, 0, 8, 0, | ||
525 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
526 | 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12, | ||
527 | 0, FB_VMODE_INTERLACED | ||
528 | } | ||
529 | }, | ||
530 | #endif | ||
531 | |||
532 | #ifdef FBCON_HAS_CFB16 | ||
533 | { | ||
534 | "1024x768-16i", { /* Cybervision 16 bpp */ | ||
535 | 1024, 768, 1024, 768, 0, 0, 16, 0, | ||
536 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
537 | 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1, | ||
538 | 0, FB_VMODE_INTERLACED | ||
539 | } | ||
540 | }, { | ||
541 | "1280x1024-16i", { /* Cybervision 16 bpp */ | ||
542 | 1280, 1024, 1280, 1024, 0, 0, 16, 0, | ||
543 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
544 | 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12, | ||
545 | 0, FB_VMODE_INTERLACED | ||
546 | } | ||
547 | }, { | ||
548 | "1600x1200-16i", { /* Cybervision 16 bpp */ | ||
549 | 1600, 1200, 1600, 1200, 0, 0, 16, 0, | ||
550 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
551 | 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12, | ||
552 | 0, FB_VMODE_INTERLACED | ||
553 | } | ||
554 | }, | ||
555 | #endif | ||
556 | |||
557 | #ifdef FBCON_HAS_CFB32 | ||
558 | { | ||
559 | "1024x768-32i", { /* Cybervision 32 bpp */ | ||
560 | 1024, 768, 1024, 768, 0, 0, 32, 0, | ||
561 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
562 | 0, 0, -1, -1, FB_ACCELF_TEXT, 22222, 216, 144, 39, 2, 72, 1, | ||
563 | 0, FB_VMODE_INTERLACED | ||
564 | } | ||
565 | }, { | ||
566 | "1280x1024-32i", { /* Cybervision 32 bpp */ | ||
567 | 1280, 1024, 1280, 1024, 0, 0, 32, 0, | ||
568 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {23, 0, 0}, | ||
569 | 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12, | ||
570 | 0, FB_VMODE_INTERLACED | ||
571 | } | ||
572 | }, { | ||
573 | "1600x1200-32i", { /* Cybervision 32 bpp */ | ||
574 | 1600, 1200, 1600, 1200, 0, 0, 32, 0, | ||
575 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
576 | 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12, | ||
577 | 0, FB_VMODE_INTERLACED | ||
578 | } | ||
579 | }, | ||
580 | #endif | ||
581 | |||
582 | /* doublescan modes */ | ||
583 | |||
584 | #ifdef FBCON_HAS_CFB8 | ||
585 | { | ||
586 | "320x240-8d", { /* Cybervision 8 bpp */ | ||
587 | 320, 240, 320, 240, 0, 0, 8, 0, | ||
588 | {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, | ||
589 | 0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1, | ||
590 | 0, FB_VMODE_DOUBLE | ||
591 | } | ||
592 | }, | ||
593 | #endif | ||
594 | |||
595 | #ifdef FBCON_HAS_CFB16 | ||
596 | { | ||
597 | "320x240-16d", { /* Cybervision 16 bpp */ | ||
598 | 320, 240, 320, 240, 0, 0, 16, 0, | ||
599 | {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, | ||
600 | 0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1, | ||
601 | 0, FB_VMODE_DOUBLE | ||
602 | } | ||
603 | }, | ||
604 | #endif | ||
605 | |||
606 | #ifdef FBCON_HAS_CFB32 | ||
607 | { | ||
608 | "320x240-32d", { /* Cybervision 32 bpp */ | ||
609 | 320, 240, 320, 240, 0, 0, 32, 0, | ||
610 | {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0}, | ||
611 | 0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1, | ||
612 | 0, FB_VMODE_DOUBLE | ||
613 | } | ||
614 | }, | ||
615 | #endif | ||
616 | }; | ||
617 | |||
618 | #define NUM_TOTAL_MODES ARRAY_SIZE(virgefb_predefined) | ||
619 | |||
620 | /* | ||
621 | * Default to 800x600 for video=virge8:, virge16: or virge32: | ||
622 | */ | ||
623 | |||
624 | #ifdef FBCON_HAS_CFB8 | ||
625 | #define VIRGE8_DEFMODE (2) | ||
626 | #endif | ||
627 | |||
628 | #ifdef FBCON_HAS_CFB16 | ||
629 | #define VIRGE16_DEFMODE (9) | ||
630 | #endif | ||
631 | |||
632 | #ifdef FBCON_HAS_CFB32 | ||
633 | #define VIRGE32_DEFMODE (16) | ||
634 | #endif | ||
635 | |||
636 | static struct fb_var_screeninfo virgefb_default; | ||
637 | static int virgefb_inverse = 0; | ||
638 | |||
639 | /* | ||
640 | * Interface used by the world | ||
641 | */ | ||
642 | |||
643 | int virgefb_setup(char*); | ||
644 | static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
645 | struct fb_info *info); | ||
646 | static int virgefb_get_var(struct fb_var_screeninfo *var, int con, | ||
647 | struct fb_info *info); | ||
648 | static int virgefb_set_var(struct fb_var_screeninfo *var, int con, | ||
649 | struct fb_info *info); | ||
650 | static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
651 | struct fb_info *info); | ||
652 | static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
653 | u_int transp, struct fb_info *info); | ||
654 | static int virgefb_blank(int blank, struct fb_info *info); | ||
655 | |||
656 | /* | ||
657 | * Interface to the low level console driver | ||
658 | */ | ||
659 | |||
660 | int virgefb_init(void); | ||
661 | static int virgefb_switch(int con, struct fb_info *info); | ||
662 | static int virgefb_updatevar(int con, struct fb_info *info); | ||
663 | |||
664 | /* | ||
665 | * Text console acceleration | ||
666 | */ | ||
667 | |||
668 | #ifdef FBCON_HAS_CFB8 | ||
669 | static struct display_switch fbcon_virge8; | ||
670 | #endif | ||
671 | |||
672 | #ifdef FBCON_HAS_CFB16 | ||
673 | static struct display_switch fbcon_virge16; | ||
674 | #endif | ||
675 | |||
676 | #ifdef FBCON_HAS_CFB32 | ||
677 | static struct display_switch fbcon_virge32; | ||
678 | #endif | ||
679 | |||
680 | /* | ||
681 | * Hardware Specific Routines | ||
682 | */ | ||
683 | |||
684 | static int virge_init(void); | ||
685 | static int virgefb_encode_fix(struct fb_fix_screeninfo *fix, | ||
686 | struct virgefb_par *par); | ||
687 | static int virgefb_decode_var(struct fb_var_screeninfo *var, | ||
688 | struct virgefb_par *par); | ||
689 | static int virgefb_encode_var(struct fb_var_screeninfo *var, | ||
690 | struct virgefb_par *par); | ||
691 | static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
692 | u_int *transp, struct fb_info *info); | ||
693 | static void virgefb_gfx_on_off(int blank); | ||
694 | static inline void virgefb_wait_for_idle(void); | ||
695 | static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty, | ||
696 | u_short width, u_short height, u_short stride, u_short depth); | ||
697 | static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height, | ||
698 | u_short color, u_short stride, u_short depth); | ||
699 | |||
700 | /* | ||
701 | * Internal routines | ||
702 | */ | ||
703 | |||
704 | static void virgefb_get_par(struct virgefb_par *par); | ||
705 | static void virgefb_set_par(struct virgefb_par *par); | ||
706 | static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive); | ||
707 | static void virgefb_set_disp(int con, struct fb_info *info); | ||
708 | static int virgefb_get_video_mode(const char *name); | ||
709 | static void virgefb_set_video(struct fb_var_screeninfo *var); | ||
710 | |||
711 | /* | ||
712 | * Additions for Initialization | ||
713 | */ | ||
714 | |||
715 | static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode); | ||
716 | static int cv3d_has_4mb(void); | ||
717 | static unsigned short virgefb_compute_clock(unsigned long freq); | ||
718 | static inline unsigned char rattr(short); | ||
719 | static inline unsigned char rseq(short); | ||
720 | static inline unsigned char rcrt(short); | ||
721 | static inline unsigned char rgfx(short); | ||
722 | static inline void gfx_on_off(int toggle); | ||
723 | static void virgefb_pci_init(void); | ||
724 | |||
725 | /* -------------------- Hardware specific routines ------------------------- */ | ||
726 | |||
727 | /* | ||
728 | * Functions for register access | ||
729 | */ | ||
730 | |||
731 | /* Read attribute controller register */ | ||
732 | |||
733 | static inline unsigned char rattr(short idx) | ||
734 | { | ||
735 | volatile unsigned char rattr_tmp; | ||
736 | |||
737 | rattr_tmp = rb_mmio(ACT_ADDRESS_RESET); | ||
738 | wb_mmio(ACT_ADDRESS_W, idx); | ||
739 | return (rb_mmio(ACT_ADDRESS_R)); | ||
740 | } | ||
741 | |||
742 | /* Read sequencer register */ | ||
743 | |||
744 | static inline unsigned char rseq(short idx) | ||
745 | { | ||
746 | wb_mmio(SEQ_ADDRESS, idx); | ||
747 | return (rb_mmio(SEQ_ADDRESS_R)); | ||
748 | } | ||
749 | |||
750 | /* Read CRT controller register */ | ||
751 | |||
752 | static inline unsigned char rcrt(short idx) | ||
753 | { | ||
754 | wb_mmio(CRT_ADDRESS, idx); | ||
755 | return (rb_mmio(CRT_ADDRESS_R)); | ||
756 | } | ||
757 | |||
758 | /* Read graphics controller register */ | ||
759 | |||
760 | static inline unsigned char rgfx(short idx) | ||
761 | { | ||
762 | wb_mmio(GCT_ADDRESS, idx); | ||
763 | return (rb_mmio(GCT_ADDRESS_R)); | ||
764 | } | ||
765 | |||
766 | |||
767 | /* | ||
768 | * Initialization | ||
769 | */ | ||
770 | |||
771 | /* PCI init */ | ||
772 | |||
773 | void virgefb_pci_init(void) { | ||
774 | |||
775 | DPRINTK("ENTER\n"); | ||
776 | |||
777 | SelectCFG; | ||
778 | |||
779 | if (on_zorro2) { | ||
780 | *((short *)(vgaio_regs + 0x00000010)) = 0; | ||
781 | *((long *)(vgaio_regs + 0x00000004)) = 0x02000003; | ||
782 | } else { | ||
783 | *((short *)(vgaio_regs + 0x000e0010)) = 0; | ||
784 | *((long *)(vgaio_regs + 0x000e0004)) = 0x02000003; | ||
785 | } | ||
786 | |||
787 | /* SelectIO is in wb_vgaio macro */ | ||
788 | wb_vgaio(SREG_VIDEO_SUBS_ENABLE, 0x01); | ||
789 | /* SelectMMIO is in wb_vgaio macro */ | ||
790 | |||
791 | DPRINTK("EXIT\n"); | ||
792 | |||
793 | return; | ||
794 | } | ||
795 | |||
796 | /* | ||
797 | * Initalize all mode independent regs, find mem size and clear mem | ||
798 | */ | ||
799 | |||
800 | static int virge_init(void) | ||
801 | { | ||
802 | int i; | ||
803 | unsigned char tmp; | ||
804 | |||
805 | DPRINTK("ENTER\n"); | ||
806 | |||
807 | virgefb_pci_init(); | ||
808 | |||
809 | wb_mmio(GREG_MISC_OUTPUT_W, 0x07); /* colour, ram enable, clk sel */ | ||
810 | |||
811 | wseq(SEQ_ID_UNLOCK_EXT, 0x06); /* unlock extensions */ | ||
812 | tmp = rb_mmio(GREG_MISC_OUTPUT_R); | ||
813 | wcrt(CRT_ID_REGISTER_LOCK_1, 0x48); /* unlock CR2D to CR3F */ | ||
814 | |||
815 | wcrt(CRT_ID_BACKWAD_COMP_1, 0x00); /* irq disable */ | ||
816 | |||
817 | wcrt(CRT_ID_REGISTER_LOCK_2, 0xa5); /* unlock CR40 to CRFF and more */ | ||
818 | wcrt(CRT_ID_REGISTER_LOCK,0x00); /* unlock h and v timing */ | ||
819 | wcrt(CRT_ID_SYSTEM_CONFIG, 0x01); /* unlock enhanced programming registers */ | ||
820 | |||
821 | wb_mmio(GREG_FEATURE_CONTROL_W, 0x00); | ||
822 | |||
823 | wcrt(CRT_ID_EXT_MISC_CNTL, 0x00); /* b2 = 0 to allow VDAC mmio access */ | ||
824 | #if 0 | ||
825 | /* write strap options ... ? */ | ||
826 | wcrt(CRT_ID_CONFIG_1, 0x08); | ||
827 | wcrt(CRT_ID_CONFIG_2, 0xff); /* 0x0x2 bit needs to be set ?? */ | ||
828 | wcrt(CRT_ID_CONFIG_3, 0x0f); | ||
829 | wcrt(CRT_ID_CONFIG_4, 0x1a); | ||
830 | #endif | ||
831 | wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x82); /* PCI DE and software reset S3D engine */ | ||
832 | /* EXT_MISC_CNTL_1, CR66 bit 0 should be the same as bit 0 MR_ADVANCED_FUNCTION_CONTROL - check */ | ||
833 | wl_mmio(MR_ADVANCED_FUNCTION_CONTROL, 0x00000011); /* enhanced mode, linear addressing */ | ||
834 | |||
835 | /* crtc registers */ | ||
836 | |||
837 | wcrt(CRT_ID_PRESET_ROW_SCAN, 0x00); | ||
838 | |||
839 | /* Disable h/w cursor */ | ||
840 | |||
841 | wcrt(CRT_ID_CURSOR_START, 0x00); | ||
842 | wcrt(CRT_ID_CURSOR_END, 0x00); | ||
843 | wcrt(CRT_ID_START_ADDR_HIGH, 0x00); | ||
844 | wcrt(CRT_ID_START_ADDR_LOW, 0x00); | ||
845 | wcrt(CRT_ID_CURSOR_LOC_HIGH, 0x00); | ||
846 | wcrt(CRT_ID_CURSOR_LOC_LOW, 0x00); | ||
847 | wcrt(CRT_ID_EXT_MODE, 0x00); | ||
848 | wcrt(CRT_ID_HWGC_MODE, 0x00); | ||
849 | wcrt(CRT_ID_HWGC_ORIGIN_X_HI, 0x00); | ||
850 | wcrt(CRT_ID_HWGC_ORIGIN_X_LO, 0x00); | ||
851 | wcrt(CRT_ID_HWGC_ORIGIN_Y_HI, 0x00); | ||
852 | wcrt(CRT_ID_HWGC_ORIGIN_Y_LO, 0x00); | ||
853 | i = rcrt(CRT_ID_HWGC_MODE); | ||
854 | wcrt(CRT_ID_HWGC_FG_STACK, 0x00); | ||
855 | wcrt(CRT_ID_HWGC_FG_STACK, 0x00); | ||
856 | wcrt(CRT_ID_HWGC_FG_STACK, 0x00); | ||
857 | wcrt(CRT_ID_HWGC_BG_STACK, 0x00); | ||
858 | wcrt(CRT_ID_HWGC_BG_STACK, 0x00); | ||
859 | wcrt(CRT_ID_HWGC_BG_STACK, 0x00); | ||
860 | wcrt(CRT_ID_HWGC_START_AD_HI, 0x00); | ||
861 | wcrt(CRT_ID_HWGC_START_AD_LO, 0x00); | ||
862 | wcrt(CRT_ID_HWGC_DSTART_X, 0x00); | ||
863 | wcrt(CRT_ID_HWGC_DSTART_Y, 0x00); | ||
864 | |||
865 | wcrt(CRT_ID_UNDERLINE_LOC, 0x00); | ||
866 | |||
867 | wcrt(CRT_ID_MODE_CONTROL, 0xe3); | ||
868 | wcrt(CRT_ID_BACKWAD_COMP_2, 0x22); /* blank bdr bit 5 blanking only on 8 bit */ | ||
869 | |||
870 | wcrt(CRT_ID_EX_SYNC_1, 0x00); | ||
871 | |||
872 | /* memory */ | ||
873 | |||
874 | wcrt(CRT_ID_EXT_SYS_CNTL_3, 0x00); | ||
875 | wcrt(CRT_ID_MEMORY_CONF, 0x08); /* config enhanced map */ | ||
876 | wcrt(CRT_ID_EXT_MEM_CNTL_1, 0x08); /* MMIO Select (0x0c works as well)*/ | ||
877 | wcrt(CRT_ID_EXT_MEM_CNTL_2, 0x02); /* why 02 big endian 00 works ? */ | ||
878 | wcrt(CRT_ID_EXT_MEM_CNTL_4, 0x9f); /* config big endian - 0x00 ? */ | ||
879 | wcrt(CRT_ID_LAW_POS_HI, 0x00); | ||
880 | wcrt(CRT_ID_LAW_POS_LO, 0x00); | ||
881 | wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x81); | ||
882 | wcrt(CRT_ID_MISC_1, 0x90); /* must follow CRT_ID_EXT_MISC_CNTL_1 */ | ||
883 | wcrt(CRT_ID_LAW_CNTL, 0x13); /* force 4 Meg for test */ | ||
884 | if (cv3d_has_4mb()) { | ||
885 | v_ram_size = 0x00400000; | ||
886 | wcrt(CRT_ID_LAW_CNTL, 0x13); /* 4 MB */ | ||
887 | } else { | ||
888 | v_ram_size = 0x00200000; | ||
889 | wcrt(CRT_ID_LAW_CNTL, 0x12); /* 2 MB */ | ||
890 | } | ||
891 | |||
892 | if (on_zorro2) | ||
893 | v_ram_size -= 0x60000; /* we need some space for the registers */ | ||
894 | |||
895 | wcrt(CRT_ID_EXT_SYS_CNTL_4, 0x00); | ||
896 | wcrt(CRT_ID_EXT_DAC_CNTL, 0x00); /* 0x10 for X11 cursor mode */ | ||
897 | |||
898 | /* sequencer registers */ | ||
899 | |||
900 | wseq(SEQ_ID_CLOCKING_MODE, 0x01); /* 8 dot clock */ | ||
901 | wseq(SEQ_ID_MAP_MASK, 0xff); | ||
902 | wseq(SEQ_ID_CHAR_MAP_SELECT, 0x00); | ||
903 | wseq(SEQ_ID_MEMORY_MODE, 0x02); | ||
904 | wseq(SEQ_ID_RAMDAC_CNTL, 0x00); | ||
905 | wseq(SEQ_ID_SIGNAL_SELECT, 0x00); | ||
906 | wseq(SEQ_ID_EXT_SEQ_REG9, 0x00); /* MMIO and PIO reg access enabled */ | ||
907 | wseq(SEQ_ID_EXT_MISC_SEQ, 0x00); | ||
908 | wseq(SEQ_ID_CLKSYN_CNTL_1, 0x00); | ||
909 | wseq(SEQ_ID_EXT_SEQ, 0x00); | ||
910 | |||
911 | /* graphic registers */ | ||
912 | |||
913 | wgfx(GCT_ID_SET_RESET, 0x00); | ||
914 | wgfx(GCT_ID_ENABLE_SET_RESET, 0x00); | ||
915 | wgfx(GCT_ID_COLOR_COMPARE, 0x00); | ||
916 | wgfx(GCT_ID_DATA_ROTATE, 0x00); | ||
917 | wgfx(GCT_ID_READ_MAP_SELECT, 0x00); | ||
918 | wgfx(GCT_ID_GRAPHICS_MODE, 0x40); | ||
919 | wgfx(GCT_ID_MISC, 0x01); | ||
920 | wgfx(GCT_ID_COLOR_XCARE, 0x0f); | ||
921 | wgfx(GCT_ID_BITMASK, 0xff); | ||
922 | |||
923 | /* attribute registers */ | ||
924 | |||
925 | for(i = 0; i <= 15; i++) | ||
926 | watr(ACT_ID_PALETTE0 + i, i); | ||
927 | watr(ACT_ID_ATTR_MODE_CNTL, 0x41); | ||
928 | watr(ACT_ID_OVERSCAN_COLOR, 0xff); | ||
929 | watr(ACT_ID_COLOR_PLANE_ENA, 0x0f); | ||
930 | watr(ACT_ID_HOR_PEL_PANNING, 0x00); | ||
931 | watr(ACT_ID_COLOR_SELECT, 0x00); | ||
932 | |||
933 | wb_mmio(VDAC_MASK, 0xff); | ||
934 | |||
935 | /* init local cmap as greyscale levels */ | ||
936 | |||
937 | for (i = 0; i < 256; i++) { | ||
938 | virgefb_colour_table [i][0] = i; | ||
939 | virgefb_colour_table [i][1] = i; | ||
940 | virgefb_colour_table [i][2] = i; | ||
941 | } | ||
942 | |||
943 | /* clear framebuffer memory */ | ||
944 | |||
945 | memset((char*)v_ram, 0x00, v_ram_size); | ||
946 | |||
947 | DPRINTK("EXIT\n"); | ||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | |||
952 | /* | ||
953 | * This function should fill in the `fix' structure based on the | ||
954 | * values in the `par' structure. | ||
955 | */ | ||
956 | |||
957 | static int virgefb_encode_fix(struct fb_fix_screeninfo *fix, | ||
958 | struct virgefb_par *par) | ||
959 | { | ||
960 | DPRINTK("ENTER set video phys addr\n"); | ||
961 | |||
962 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | ||
963 | strcpy(fix->id, virgefb_name); | ||
964 | if (on_zorro2) | ||
965 | fix->smem_start = v_ram_phys; | ||
966 | switch (par->var.bits_per_pixel) { | ||
967 | #ifdef FBCON_HAS_CFB8 | ||
968 | case 8: | ||
969 | if (on_zorro2) | ||
970 | Select_Zorro2_FrameBuffer(ENDIAN_BYTE); | ||
971 | else | ||
972 | fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_8); | ||
973 | break; | ||
974 | #endif | ||
975 | #ifdef FBCON_HAS_CFB16 | ||
976 | case 16: | ||
977 | if (on_zorro2) | ||
978 | Select_Zorro2_FrameBuffer(ENDIAN_WORD); | ||
979 | else | ||
980 | fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_16); | ||
981 | break; | ||
982 | #endif | ||
983 | #ifdef FBCON_HAS_CFB32 | ||
984 | case 32: | ||
985 | if (on_zorro2) | ||
986 | Select_Zorro2_FrameBuffer(ENDIAN_LONG); | ||
987 | else | ||
988 | fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_32); | ||
989 | break; | ||
990 | #endif | ||
991 | } | ||
992 | |||
993 | fix->smem_len = v_ram_size; | ||
994 | fix->mmio_start = mmio_regs_phys; | ||
995 | fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */ | ||
996 | |||
997 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
998 | fix->type_aux = 0; | ||
999 | if (par->var.bits_per_pixel == 8) | ||
1000 | fix->visual = FB_VISUAL_PSEUDOCOLOR; | ||
1001 | else | ||
1002 | fix->visual = FB_VISUAL_TRUECOLOR; | ||
1003 | |||
1004 | fix->xpanstep = 0; | ||
1005 | fix->ypanstep = 0; | ||
1006 | fix->ywrapstep = 0; | ||
1007 | fix->line_length = par->var.xres_virtual*par->var.bits_per_pixel/8; | ||
1008 | fix->accel = FB_ACCEL_S3_VIRGE; | ||
1009 | DPRINTK("EXIT v_ram_phys = 0x%8.8lx\n", (unsigned long)fix->smem_start); | ||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | |||
1014 | /* | ||
1015 | * Fill the `par' structure based on the values in `var'. | ||
1016 | * TODO: Verify and adjust values, return -EINVAL if bad. | ||
1017 | */ | ||
1018 | |||
1019 | static int virgefb_decode_var(struct fb_var_screeninfo *var, | ||
1020 | struct virgefb_par *par) | ||
1021 | { | ||
1022 | DPRINTK("ENTER\n"); | ||
1023 | par->var.xres = var->xres; | ||
1024 | par->var.yres = var->yres; | ||
1025 | par->var.xres_virtual = var->xres_virtual; | ||
1026 | par->var.yres_virtual = var->yres_virtual; | ||
1027 | /* roundup and validate */ | ||
1028 | par->var.xres = (par->var.xres+7) & ~7; | ||
1029 | par->var.xres_virtual = (par->var.xres_virtual+7) & ~7; | ||
1030 | if (par->var.xres_virtual < par->var.xres) | ||
1031 | par->var.xres_virtual = par->var.xres; | ||
1032 | if (par->var.yres_virtual < par->var.yres) | ||
1033 | par->var.yres_virtual = par->var.yres; | ||
1034 | par->var.xoffset = var->xoffset; | ||
1035 | par->var.yoffset = var->yoffset; | ||
1036 | par->var.bits_per_pixel = var->bits_per_pixel; | ||
1037 | if (par->var.bits_per_pixel <= 8) | ||
1038 | par->var.bits_per_pixel = 8; | ||
1039 | else if (par->var.bits_per_pixel <= 16) | ||
1040 | par->var.bits_per_pixel = 16; | ||
1041 | else | ||
1042 | par->var.bits_per_pixel = 32; | ||
1043 | #ifndef FBCON_HAS_CFB32 | ||
1044 | if (par->var.bits_per_pixel == 32) | ||
1045 | par->var.bits_per_pixel = 16; | ||
1046 | #endif | ||
1047 | #ifndef FBCON_HAS_CFB16 | ||
1048 | if (par->var.bits_per_pixel == 16) | ||
1049 | par->var.bits_per_pixel = 8; | ||
1050 | #endif | ||
1051 | par->var.grayscale = var->grayscale; | ||
1052 | par->var.red = var->red; | ||
1053 | par->var.green = var->green; | ||
1054 | par->var.blue = var->blue; | ||
1055 | par->var.transp = var->transp; | ||
1056 | par->var.nonstd = var->nonstd; | ||
1057 | par->var.activate = var->activate; | ||
1058 | par->var.height = var->height; | ||
1059 | par->var.width = var->width; | ||
1060 | if (var->accel_flags & FB_ACCELF_TEXT) { | ||
1061 | par->var.accel_flags = FB_ACCELF_TEXT; | ||
1062 | } else { | ||
1063 | par->var.accel_flags = 0; | ||
1064 | } | ||
1065 | par->var.pixclock = var->pixclock; | ||
1066 | par->var.left_margin = var->left_margin; | ||
1067 | par->var.right_margin = var->right_margin; | ||
1068 | par->var.upper_margin = var->upper_margin; | ||
1069 | par->var.lower_margin = var->lower_margin; | ||
1070 | par->var.hsync_len = var->hsync_len; | ||
1071 | par->var.vsync_len = var->vsync_len; | ||
1072 | par->var.sync = var->sync; | ||
1073 | par->var.vmode = var->vmode; | ||
1074 | DPRINTK("EXIT\n"); | ||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1078 | /* | ||
1079 | * Fill the `var' structure based on the values in `par' and maybe | ||
1080 | * other values read out of the hardware. | ||
1081 | */ | ||
1082 | |||
1083 | static int virgefb_encode_var(struct fb_var_screeninfo *var, | ||
1084 | struct virgefb_par *par) | ||
1085 | { | ||
1086 | DPRINTK("ENTER\n"); | ||
1087 | memset(var, 0, sizeof(struct fb_var_screeninfo)); /* need this ? */ | ||
1088 | var->xres = par->var.xres; | ||
1089 | var->yres = par->var.yres; | ||
1090 | var->xres_virtual = par->var.xres_virtual; | ||
1091 | var->yres_virtual = par->var.yres_virtual; | ||
1092 | var->xoffset = par->var.xoffset; | ||
1093 | var->yoffset = par->var.yoffset; | ||
1094 | var->bits_per_pixel = par->var.bits_per_pixel; | ||
1095 | var->grayscale = par->var.grayscale; | ||
1096 | var->red = par->var.red; | ||
1097 | var->green = par->var.green; | ||
1098 | var->blue = par->var.blue; | ||
1099 | var->transp = par->var.transp; | ||
1100 | var->nonstd = par->var.nonstd; | ||
1101 | var->activate = par->var.activate; | ||
1102 | var->height = par->var.height; | ||
1103 | var->width = par->var.width; | ||
1104 | var->accel_flags = par->var.accel_flags; | ||
1105 | var->pixclock = par->var.pixclock; | ||
1106 | var->left_margin = par->var.left_margin; | ||
1107 | var->right_margin = par->var.right_margin; | ||
1108 | var->upper_margin = par->var.upper_margin; | ||
1109 | var->lower_margin = par->var.lower_margin; | ||
1110 | var->hsync_len = par->var.hsync_len; | ||
1111 | var->vsync_len = par->var.vsync_len; | ||
1112 | var->sync = par->var.sync; | ||
1113 | var->vmode = par->var.vmode; | ||
1114 | DPRINTK("EXIT\n"); | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | /* | ||
1119 | * Set a single color register. The values supplied are already | ||
1120 | * rounded down to the hardware's capabilities (according to the | ||
1121 | * entries in the var structure). Return != 0 for invalid regno. | ||
1122 | */ | ||
1123 | |||
1124 | static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
1125 | u_int transp, struct fb_info *info) | ||
1126 | { | ||
1127 | DPRINTK("ENTER\n"); | ||
1128 | if (((current_par.var.bits_per_pixel==8) && (regno>255)) || | ||
1129 | ((current_par.var.bits_per_pixel!=8) && (regno>15))) { | ||
1130 | DPRINTK("EXIT\n"); | ||
1131 | return 1; | ||
1132 | } | ||
1133 | if (((current_par.var.bits_per_pixel==8) && (regno<256)) || | ||
1134 | ((current_par.var.bits_per_pixel!=8) && (regno<16))) { | ||
1135 | virgefb_colour_table [regno][0] = red >> 10; | ||
1136 | virgefb_colour_table [regno][1] = green >> 10; | ||
1137 | virgefb_colour_table [regno][2] = blue >> 10; | ||
1138 | } | ||
1139 | |||
1140 | switch (current_par.var.bits_per_pixel) { | ||
1141 | #ifdef FBCON_HAS_CFB8 | ||
1142 | case 8: | ||
1143 | wb_mmio(VDAC_ADDRESS_W, (unsigned char)regno); | ||
1144 | wb_mmio(VDAC_DATA, ((unsigned char)(red >> 10))); | ||
1145 | wb_mmio(VDAC_DATA, ((unsigned char)(green >> 10))); | ||
1146 | wb_mmio(VDAC_DATA, ((unsigned char)(blue >> 10))); | ||
1147 | break; | ||
1148 | #endif | ||
1149 | #ifdef FBCON_HAS_CFB16 | ||
1150 | case 16: | ||
1151 | fbcon_cmap.cfb16[regno] = | ||
1152 | ((red & 0xf800) | | ||
1153 | ((green & 0xfc00) >> 5) | | ||
1154 | ((blue & 0xf800) >> 11)); | ||
1155 | break; | ||
1156 | #endif | ||
1157 | #ifdef FBCON_HAS_CFB32 | ||
1158 | case 32: | ||
1159 | fbcon_cmap.cfb32[regno] = | ||
1160 | /* transp = 0's or 1's ? */ | ||
1161 | (((red & 0xff00) << 8) | | ||
1162 | ((green & 0xff00) >> 0) | | ||
1163 | ((blue & 0xff00) >> 8)); | ||
1164 | break; | ||
1165 | #endif | ||
1166 | } | ||
1167 | DPRINTK("EXIT\n"); | ||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | |||
1172 | /* | ||
1173 | * Read a single color register and split it into | ||
1174 | * colors/transparent. Return != 0 for invalid regno. | ||
1175 | */ | ||
1176 | |||
1177 | static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, | ||
1178 | u_int *transp, struct fb_info *info) | ||
1179 | { | ||
1180 | int t; | ||
1181 | |||
1182 | DPRINTK("ENTER\n"); | ||
1183 | if (regno > 255) { | ||
1184 | DPRINTK("EXIT\n"); | ||
1185 | return 1; | ||
1186 | } | ||
1187 | if (((current_par.var.bits_per_pixel==8) && (regno<256)) || | ||
1188 | ((current_par.var.bits_per_pixel!=8) && (regno<16))) { | ||
1189 | |||
1190 | t = virgefb_colour_table [regno][0]; | ||
1191 | *red = (t<<10) | (t<<4) | (t>>2); | ||
1192 | t = virgefb_colour_table [regno][1]; | ||
1193 | *green = (t<<10) | (t<<4) | (t>>2); | ||
1194 | t = virgefb_colour_table [regno][2]; | ||
1195 | *blue = (t<<10) | (t<<4) | (t>>2); | ||
1196 | } | ||
1197 | *transp = 0; | ||
1198 | DPRINTK("EXIT\n"); | ||
1199 | return 0; | ||
1200 | } | ||
1201 | |||
1202 | |||
1203 | /* | ||
1204 | * (Un)Blank the screen | ||
1205 | */ | ||
1206 | |||
1207 | static void virgefb_gfx_on_off(int blank) | ||
1208 | { | ||
1209 | DPRINTK("ENTER\n"); | ||
1210 | gfx_on_off(blank); | ||
1211 | DPRINTK("EXIT\n"); | ||
1212 | } | ||
1213 | |||
1214 | /* | ||
1215 | * CV3D low-level support | ||
1216 | */ | ||
1217 | |||
1218 | |||
1219 | static inline void wait_3d_fifo_slots(int n) /* WaitQueue */ | ||
1220 | { | ||
1221 | do { | ||
1222 | mb(); | ||
1223 | } while (((rl_mmio(MR_SUBSYSTEM_STATUS_R) >> 8) & 0x1f) < (n + 2)); | ||
1224 | } | ||
1225 | |||
1226 | static inline void virgefb_wait_for_idle(void) /* WaitIdle */ | ||
1227 | { | ||
1228 | while(!(rl_mmio(MR_SUBSYSTEM_STATUS_R) & 0x2000)) ; | ||
1229 | blit_maybe_busy = 0; | ||
1230 | } | ||
1231 | |||
1232 | /* | ||
1233 | * BitBLT - Through the Plane | ||
1234 | */ | ||
1235 | |||
1236 | static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty, | ||
1237 | u_short width, u_short height, u_short stride, u_short depth) | ||
1238 | { | ||
1239 | unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_BLT_COPY; | ||
1240 | |||
1241 | switch (depth) { | ||
1242 | #ifdef FBCON_HAS_CFB8 | ||
1243 | case 8 : | ||
1244 | blitcmd |= S3V_DST_8BPP; | ||
1245 | break; | ||
1246 | #endif | ||
1247 | #ifdef FBCON_HAS_CFB16 | ||
1248 | case 16 : | ||
1249 | blitcmd |= S3V_DST_16BPP; | ||
1250 | break; | ||
1251 | #endif | ||
1252 | #ifdef FBCON_HAS_CFB32 | ||
1253 | case 32 : | ||
1254 | /* 32 bit uses 2 by 16 bit values, see fbcon_virge32_bmove */ | ||
1255 | blitcmd |= S3V_DST_16BPP; | ||
1256 | break; | ||
1257 | #endif | ||
1258 | } | ||
1259 | |||
1260 | /* Set drawing direction */ | ||
1261 | /* -Y, X maj, -X (default) */ | ||
1262 | if (curx > destx) { | ||
1263 | blitcmd |= (1 << 25); /* Drawing direction +X */ | ||
1264 | } else { | ||
1265 | curx += (width - 1); | ||
1266 | destx += (width - 1); | ||
1267 | } | ||
1268 | |||
1269 | if (cury > desty) { | ||
1270 | blitcmd |= (1 << 26); /* Drawing direction +Y */ | ||
1271 | } else { | ||
1272 | cury += (height - 1); | ||
1273 | desty += (height - 1); | ||
1274 | } | ||
1275 | |||
1276 | wait_3d_fifo_slots(8); /* wait on fifo slots for 8 writes */ | ||
1277 | |||
1278 | if (blit_maybe_busy) | ||
1279 | virgefb_wait_for_idle(); | ||
1280 | blit_maybe_busy = 1; | ||
1281 | |||
1282 | wl_mmio(BLT_PATTERN_COLOR, 1); /* pattern fb color */ | ||
1283 | wl_mmio(BLT_MONO_PATTERN_0, ~0); | ||
1284 | wl_mmio(BLT_MONO_PATTERN_1, ~0); | ||
1285 | wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height)); | ||
1286 | wl_mmio(BLT_SRC_X_Y, ((curx << 16) | cury)); | ||
1287 | wl_mmio(BLT_DEST_X_Y, ((destx << 16) | desty)); | ||
1288 | wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */)); /* why is this needed now ? */ | ||
1289 | wl_mmio(BLT_COMMAND_SET, blitcmd); | ||
1290 | } | ||
1291 | |||
1292 | /* | ||
1293 | * Rectangle Fill Solid | ||
1294 | */ | ||
1295 | |||
1296 | static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height, | ||
1297 | u_short color, u_short stride, u_short depth) | ||
1298 | { | ||
1299 | unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW | | ||
1300 | S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25); | ||
1301 | |||
1302 | switch (depth) { | ||
1303 | #ifdef FBCON_HAS_CFB8 | ||
1304 | case 8 : | ||
1305 | blitcmd |= S3V_DST_8BPP; | ||
1306 | break; | ||
1307 | #endif | ||
1308 | #ifdef FBCON_HAS_CFB16 | ||
1309 | case 16 : | ||
1310 | blitcmd |= S3V_DST_16BPP; | ||
1311 | break; | ||
1312 | #endif | ||
1313 | #ifdef FBCON_HAS_CFB32 | ||
1314 | case 32 : | ||
1315 | /* 32 bit uses 2 times 16 bit values, see fbcon_virge32_clear */ | ||
1316 | blitcmd |= S3V_DST_16BPP; | ||
1317 | break; | ||
1318 | #endif | ||
1319 | } | ||
1320 | |||
1321 | wait_3d_fifo_slots(5); /* wait on fifo slots for 5 writes */ | ||
1322 | |||
1323 | if (blit_maybe_busy) | ||
1324 | virgefb_wait_for_idle(); | ||
1325 | blit_maybe_busy = 1; | ||
1326 | |||
1327 | wl_mmio(BLT_PATTERN_COLOR, (color & 0xff)); | ||
1328 | wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height)); | ||
1329 | wl_mmio(BLT_DEST_X_Y, ((x << 16) | y)); | ||
1330 | wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */)); | ||
1331 | wl_mmio(BLT_COMMAND_SET, blitcmd); | ||
1332 | } | ||
1333 | |||
1334 | /* | ||
1335 | * Move cursor to x, y | ||
1336 | */ | ||
1337 | |||
1338 | #if 0 | ||
1339 | static void virgefb_move_cursor(u_short x, u_short y) | ||
1340 | { | ||
1341 | DPRINTK("Yuck .... MoveCursor on a 3D\n"); | ||
1342 | return 0; | ||
1343 | } | ||
1344 | #endif | ||
1345 | |||
1346 | /* -------------------- Interfaces to hardware functions -------------------- */ | ||
1347 | |||
1348 | static struct fb_hwswitch virgefb_hw_switch = { | ||
1349 | .init = virge_init, | ||
1350 | .encode_fix = virgefb_encode_fix, | ||
1351 | .decode_var = virgefb_decode_var, | ||
1352 | .encode_var = virgefb_encode_var, | ||
1353 | .getcolreg = virgefb_getcolreg, | ||
1354 | .blank = virgefb_gfx_on_off | ||
1355 | }; | ||
1356 | |||
1357 | |||
1358 | /* -------------------- Generic routines ------------------------------------ */ | ||
1359 | |||
1360 | |||
1361 | /* | ||
1362 | * Fill the hardware's `par' structure. | ||
1363 | */ | ||
1364 | |||
1365 | static void virgefb_get_par(struct virgefb_par *par) | ||
1366 | { | ||
1367 | DPRINTK("ENTER\n"); | ||
1368 | if (current_par_valid) { | ||
1369 | *par = current_par; | ||
1370 | } else { | ||
1371 | fbhw->decode_var(&virgefb_default, par); | ||
1372 | } | ||
1373 | DPRINTK("EXIT\n"); | ||
1374 | } | ||
1375 | |||
1376 | |||
1377 | static void virgefb_set_par(struct virgefb_par *par) | ||
1378 | { | ||
1379 | DPRINTK("ENTER\n"); | ||
1380 | current_par = *par; | ||
1381 | current_par_valid = 1; | ||
1382 | DPRINTK("EXIT\n"); | ||
1383 | } | ||
1384 | |||
1385 | |||
1386 | static void virgefb_set_video(struct fb_var_screeninfo *var) | ||
1387 | { | ||
1388 | /* Set clipping rectangle to current screen size */ | ||
1389 | |||
1390 | unsigned int clip; | ||
1391 | |||
1392 | DPRINTK("ENTER\n"); | ||
1393 | wait_3d_fifo_slots(4); | ||
1394 | clip = ((0 << 16) | (var->xres - 1)); | ||
1395 | wl_mmio(BLT_CLIP_LEFT_RIGHT, clip); | ||
1396 | clip = ((0 << 16) | (var->yres - 1)); | ||
1397 | wl_mmio(BLT_CLIP_TOP_BOTTOM, clip); | ||
1398 | wl_mmio(BLT_SRC_BASE, 0); /* seems we need to clear these two */ | ||
1399 | wl_mmio(BLT_DEST_BASE, 0); | ||
1400 | |||
1401 | /* Load the video mode defined by the 'var' data */ | ||
1402 | |||
1403 | virgefb_load_video_mode(var); | ||
1404 | DPRINTK("EXIT\n"); | ||
1405 | } | ||
1406 | |||
1407 | /* | ||
1408 | Merge these two functions, Geert's suggestion. | ||
1409 | static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info); | ||
1410 | static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive); | ||
1411 | */ | ||
1412 | |||
1413 | static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive) | ||
1414 | { | ||
1415 | int err, activate; | ||
1416 | struct virgefb_par par; | ||
1417 | |||
1418 | DPRINTK("ENTER\n"); | ||
1419 | if ((err = fbhw->decode_var(var, &par))) { | ||
1420 | DPRINTK("EXIT\n"); | ||
1421 | return (err); | ||
1422 | } | ||
1423 | |||
1424 | activate = var->activate; | ||
1425 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) | ||
1426 | virgefb_set_par(&par); | ||
1427 | fbhw->encode_var(var, &par); | ||
1428 | var->activate = activate; | ||
1429 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) | ||
1430 | virgefb_set_video(var); | ||
1431 | DPRINTK("EXIT\n"); | ||
1432 | return 0; | ||
1433 | } | ||
1434 | |||
1435 | |||
1436 | /* | ||
1437 | * Get the Fixed Part of the Display | ||
1438 | */ | ||
1439 | |||
1440 | static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con, | ||
1441 | struct fb_info *info) | ||
1442 | { | ||
1443 | struct virgefb_par par; | ||
1444 | int error = 0; | ||
1445 | |||
1446 | DPRINTK("ENTER\n"); | ||
1447 | if (con == -1) | ||
1448 | virgefb_get_par(&par); | ||
1449 | else | ||
1450 | error = fbhw->decode_var(&fb_display[con].var, &par); | ||
1451 | |||
1452 | if (!error) | ||
1453 | error = fbhw->encode_fix(fix, &par); | ||
1454 | DPRINTK("EXIT\n"); | ||
1455 | return(error); | ||
1456 | } | ||
1457 | |||
1458 | |||
1459 | /* | ||
1460 | * Get the User Defined Part of the Display | ||
1461 | */ | ||
1462 | |||
1463 | static int virgefb_get_var(struct fb_var_screeninfo *var, int con, | ||
1464 | struct fb_info *info) | ||
1465 | { | ||
1466 | struct virgefb_par par; | ||
1467 | int error = 0; | ||
1468 | |||
1469 | DPRINTK("ENTER\n"); | ||
1470 | if (con == -1) { | ||
1471 | virgefb_get_par(&par); | ||
1472 | error = fbhw->encode_var(var, &par); | ||
1473 | disp.var = *var; /* ++Andre: don't know if this is the right place */ | ||
1474 | } else { | ||
1475 | *var = fb_display[con].var; | ||
1476 | } | ||
1477 | DPRINTK("EXIT\n"); | ||
1478 | return(error); | ||
1479 | } | ||
1480 | |||
1481 | static void virgefb_set_disp(int con, struct fb_info *info) | ||
1482 | { | ||
1483 | struct fb_fix_screeninfo fix; | ||
1484 | struct display *display; | ||
1485 | |||
1486 | DPRINTK("ENTER\n"); | ||
1487 | if (con >= 0) | ||
1488 | display = &fb_display[con]; | ||
1489 | else | ||
1490 | display = &disp; /* used during initialization */ | ||
1491 | |||
1492 | virgefb_get_fix(&fix, con, info); | ||
1493 | if (con == -1) | ||
1494 | con = 0; | ||
1495 | if(on_zorro2) { | ||
1496 | info->screen_base = (char*)v_ram; | ||
1497 | } else { | ||
1498 | switch (display->var.bits_per_pixel) { | ||
1499 | #ifdef FBCON_HAS_CFB8 | ||
1500 | case 8: | ||
1501 | info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_8); | ||
1502 | break; | ||
1503 | #endif | ||
1504 | #ifdef FBCON_HAS_CFB16 | ||
1505 | case 16: | ||
1506 | info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_16); | ||
1507 | break; | ||
1508 | #endif | ||
1509 | #ifdef FBCON_HAS_CFB32 | ||
1510 | case 32: | ||
1511 | info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_32); | ||
1512 | break; | ||
1513 | #endif | ||
1514 | } | ||
1515 | } | ||
1516 | display->visual = fix.visual; | ||
1517 | display->type = fix.type; | ||
1518 | display->type_aux = fix.type_aux; | ||
1519 | display->ypanstep = fix.ypanstep; | ||
1520 | display->ywrapstep = fix.ywrapstep; | ||
1521 | display->can_soft_blank = 1; | ||
1522 | display->inverse = virgefb_inverse; | ||
1523 | display->line_length = display->var.xres_virtual* | ||
1524 | display->var.bits_per_pixel/8; | ||
1525 | |||
1526 | switch (display->var.bits_per_pixel) { | ||
1527 | #ifdef FBCON_HAS_CFB8 | ||
1528 | case 8: | ||
1529 | if (display->var.accel_flags & FB_ACCELF_TEXT) { | ||
1530 | display->dispsw = &fbcon_virge8; | ||
1531 | #warning FIXME: We should reinit the graphics engine here | ||
1532 | } else | ||
1533 | display->dispsw = &fbcon_cfb8; | ||
1534 | break; | ||
1535 | #endif | ||
1536 | #ifdef FBCON_HAS_CFB16 | ||
1537 | case 16: | ||
1538 | if (display->var.accel_flags & FB_ACCELF_TEXT) { | ||
1539 | display->dispsw = &fbcon_virge16; | ||
1540 | } else | ||
1541 | display->dispsw = &fbcon_cfb16; | ||
1542 | display->dispsw_data = &fbcon_cmap.cfb16; | ||
1543 | break; | ||
1544 | #endif | ||
1545 | #ifdef FBCON_HAS_CFB32 | ||
1546 | case 32: | ||
1547 | if (display->var.accel_flags & FB_ACCELF_TEXT) { | ||
1548 | display->dispsw = &fbcon_virge32; | ||
1549 | } else | ||
1550 | display->dispsw = &fbcon_cfb32; | ||
1551 | display->dispsw_data = &fbcon_cmap.cfb32; | ||
1552 | break; | ||
1553 | #endif | ||
1554 | default: | ||
1555 | display->dispsw = &fbcon_dummy; | ||
1556 | break; | ||
1557 | } | ||
1558 | DPRINTK("EXIT v_ram virt = 0x%8.8lx\n",(unsigned long)display->screen_base); | ||
1559 | } | ||
1560 | |||
1561 | |||
1562 | /* | ||
1563 | * Set the User Defined Part of the Display | ||
1564 | */ | ||
1565 | |||
1566 | static int virgefb_set_var(struct fb_var_screeninfo *var, int con, | ||
1567 | struct fb_info *info) | ||
1568 | { | ||
1569 | int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel; | ||
1570 | |||
1571 | DPRINTK("ENTER\n"); | ||
1572 | |||
1573 | if ((err = virgefb_do_fb_set_var(var, con == info->currcon))) { | ||
1574 | DPRINTK("EXIT\n"); | ||
1575 | return(err); | ||
1576 | } | ||
1577 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { | ||
1578 | oldxres = fb_display[con].var.xres; | ||
1579 | oldyres = fb_display[con].var.yres; | ||
1580 | oldvxres = fb_display[con].var.xres_virtual; | ||
1581 | oldvyres = fb_display[con].var.yres_virtual; | ||
1582 | oldbpp = fb_display[con].var.bits_per_pixel; | ||
1583 | oldaccel = fb_display[con].var.accel_flags; | ||
1584 | fb_display[con].var = *var; | ||
1585 | if (oldxres != var->xres || oldyres != var->yres || | ||
1586 | oldvxres != var->xres_virtual || | ||
1587 | oldvyres != var->yres_virtual || | ||
1588 | oldbpp != var->bits_per_pixel || | ||
1589 | oldaccel != var->accel_flags) { | ||
1590 | virgefb_set_disp(con, info); | ||
1591 | if (fb_info.changevar) | ||
1592 | (*fb_info.changevar)(con); | ||
1593 | fb_alloc_cmap(&fb_display[con].cmap, 0, 0); | ||
1594 | do_install_cmap(con, info); | ||
1595 | } | ||
1596 | } | ||
1597 | var->activate = 0; | ||
1598 | DPRINTK("EXIT\n"); | ||
1599 | return 0; | ||
1600 | } | ||
1601 | |||
1602 | |||
1603 | /* | ||
1604 | * Get the Colormap | ||
1605 | */ | ||
1606 | |||
1607 | static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con, | ||
1608 | struct fb_info *info) | ||
1609 | { | ||
1610 | DPRINTK("ENTER\n"); | ||
1611 | if (con == info->currcon) { /* current console? */ | ||
1612 | DPRINTK("EXIT - console is current console, fb_get_cmap\n"); | ||
1613 | return(fb_get_cmap(cmap, kspc, fbhw->getcolreg, info)); | ||
1614 | } else if (fb_display[con].cmap.len) { /* non default colormap? */ | ||
1615 | DPRINTK("Use console cmap\n"); | ||
1616 | fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); | ||
1617 | } else { | ||
1618 | DPRINTK("Use default cmap\n"); | ||
1619 | fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel==8 ? 256 : 16), | ||
1620 | cmap, kspc ? 0 : 2); | ||
1621 | } | ||
1622 | DPRINTK("EXIT\n"); | ||
1623 | return 0; | ||
1624 | } | ||
1625 | |||
1626 | static struct fb_ops virgefb_ops = { | ||
1627 | .owner = THIS_MODULE, | ||
1628 | .fb_get_fix = virgefb_get_fix, | ||
1629 | .fb_get_var = virgefb_get_var, | ||
1630 | .fb_set_var = virgefb_set_var, | ||
1631 | .fb_get_cmap = virgefb_get_cmap, | ||
1632 | .fb_set_cmap = gen_set_cmap, | ||
1633 | .fb_setcolreg = virgefb_setcolreg, | ||
1634 | .fb_blank = virgefb_blank, | ||
1635 | }; | ||
1636 | |||
1637 | int __init virgefb_setup(char *options) | ||
1638 | { | ||
1639 | char *this_opt; | ||
1640 | fb_info.fontname[0] = '\0'; | ||
1641 | |||
1642 | DPRINTK("ENTER\n"); | ||
1643 | if (!options || !*options) { | ||
1644 | DPRINTK("EXIT\n"); | ||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1648 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
1649 | if (!*this_opt) | ||
1650 | continue; | ||
1651 | if (!strcmp(this_opt, "inverse")) { | ||
1652 | virgefb_inverse = 1; | ||
1653 | fb_invert_cmaps(); | ||
1654 | } else if (!strncmp(this_opt, "font:", 5)) | ||
1655 | strcpy(fb_info.fontname, this_opt+5); | ||
1656 | #ifdef FBCON_HAS_CFB8 | ||
1657 | else if (!strcmp (this_opt, "virge8")){ | ||
1658 | virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var; | ||
1659 | } | ||
1660 | #endif | ||
1661 | #ifdef FBCON_HAS_CFB16 | ||
1662 | else if (!strcmp (this_opt, "virge16")){ | ||
1663 | virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var; | ||
1664 | } | ||
1665 | #endif | ||
1666 | #ifdef FBCON_HAS_CFB32 | ||
1667 | else if (!strcmp (this_opt, "virge32")){ | ||
1668 | virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var; | ||
1669 | } | ||
1670 | #endif | ||
1671 | else | ||
1672 | virgefb_get_video_mode(this_opt); | ||
1673 | } | ||
1674 | |||
1675 | printk(KERN_INFO "mode : xres=%d, yres=%d, bpp=%d\n", virgefb_default.xres, | ||
1676 | virgefb_default.yres, virgefb_default.bits_per_pixel); | ||
1677 | DPRINTK("EXIT\n"); | ||
1678 | return 0; | ||
1679 | } | ||
1680 | |||
1681 | |||
1682 | /* | ||
1683 | * Get a Video Mode | ||
1684 | */ | ||
1685 | |||
1686 | static int __init virgefb_get_video_mode(const char *name) | ||
1687 | { | ||
1688 | int i; | ||
1689 | |||
1690 | DPRINTK("ENTER\n"); | ||
1691 | for (i = 0; i < NUM_TOTAL_MODES; i++) { | ||
1692 | if (!strcmp(name, virgefb_predefined[i].name)) { | ||
1693 | virgefb_default = virgefb_predefined[i].var; | ||
1694 | DPRINTK("EXIT\n"); | ||
1695 | return(i); | ||
1696 | } | ||
1697 | } | ||
1698 | /* ++Andre: set virgefb default mode */ | ||
1699 | |||
1700 | /* prefer 16 bit depth, 8 if no 16, if no 8 or 16 use 32 */ | ||
1701 | |||
1702 | #ifdef FBCON_HAS_CFB32 | ||
1703 | virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var; | ||
1704 | #endif | ||
1705 | #ifdef FBCON_HAS_CFB8 | ||
1706 | virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var; | ||
1707 | #endif | ||
1708 | #ifdef FBCON_HAS_CFB16 | ||
1709 | virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var; | ||
1710 | #endif | ||
1711 | DPRINTK("EXIT\n"); | ||
1712 | return 0; | ||
1713 | } | ||
1714 | |||
1715 | /* | ||
1716 | * Initialization | ||
1717 | */ | ||
1718 | |||
1719 | int __init virgefb_init(void) | ||
1720 | { | ||
1721 | struct virgefb_par par; | ||
1722 | unsigned long board_addr, board_size; | ||
1723 | struct zorro_dev *z = NULL; | ||
1724 | |||
1725 | DPRINTK("ENTER\n"); | ||
1726 | |||
1727 | z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, NULL); | ||
1728 | if (!z) | ||
1729 | return -ENODEV; | ||
1730 | |||
1731 | board_addr = z->resource.start; | ||
1732 | if (board_addr < 0x01000000) { | ||
1733 | |||
1734 | /* board running in Z2 space. This includes the video memory | ||
1735 | as well as the S3 register set */ | ||
1736 | |||
1737 | on_zorro2 = 1; | ||
1738 | board_size = 0x00400000; | ||
1739 | |||
1740 | if (!request_mem_region(board_addr, board_size, "S3 ViRGE")) | ||
1741 | return -ENOMEM; | ||
1742 | |||
1743 | v_ram_phys = board_addr; | ||
1744 | v_ram = ZTWO_VADDR(v_ram_phys); | ||
1745 | mmio_regs_phys = (unsigned long)(board_addr + 0x003c0000); | ||
1746 | vgaio_regs = (unsigned char *) ZTWO_VADDR(board_addr + 0x003c0000); | ||
1747 | mmio_regs = (unsigned char *)ZTWO_VADDR(mmio_regs_phys); | ||
1748 | vcode_switch_base = (unsigned long) ZTWO_VADDR(board_addr + 0x003a0000); | ||
1749 | printk(KERN_INFO "CV3D detected running in Z2 mode.\n"); | ||
1750 | |||
1751 | } else { | ||
1752 | |||
1753 | /* board running in Z3 space. Separate video memory (3 apertures) | ||
1754 | and S3 register set */ | ||
1755 | |||
1756 | on_zorro2 = 0; | ||
1757 | board_size = 0x01000000; | ||
1758 | |||
1759 | if (!request_mem_region(board_addr, board_size, "S3 ViRGE")) | ||
1760 | return -ENOMEM; | ||
1761 | |||
1762 | v_ram_phys = board_addr + 0x04000000; | ||
1763 | v_ram = (unsigned long)ioremap(v_ram_phys, 0x01000000); | ||
1764 | mmio_regs_phys = board_addr + 0x05000000; | ||
1765 | vgaio_regs = (unsigned char *)ioremap(board_addr +0x0c000000, 0x00100000); /* includes PCI regs */ | ||
1766 | mmio_regs = ioremap(mmio_regs_phys, 0x00010000); | ||
1767 | vcode_switch_base = (unsigned long)ioremap(board_addr + 0x08000000, 0x1000); | ||
1768 | printk(KERN_INFO "CV3D detected running in Z3 mode\n"); | ||
1769 | } | ||
1770 | |||
1771 | #if defined (VIRGEFBDEBUG) | ||
1772 | DPRINTK("board_addr : 0x%8.8lx\n",board_addr); | ||
1773 | DPRINTK("board_size : 0x%8.8lx\n",board_size); | ||
1774 | DPRINTK("mmio_regs_phy : 0x%8.8lx\n",mmio_regs_phys); | ||
1775 | DPRINTK("v_ram_phys : 0x%8.8lx\n",v_ram_phys); | ||
1776 | DPRINTK("vgaio_regs : 0x%8.8lx\n",(unsigned long)vgaio_regs); | ||
1777 | DPRINTK("mmio_regs : 0x%8.8lx\n",(unsigned long)mmio_regs); | ||
1778 | DPRINTK("v_ram : 0x%8.8lx\n",v_ram); | ||
1779 | DPRINTK("vcode sw base : 0x%8.8lx\n",vcode_switch_base); | ||
1780 | #endif | ||
1781 | fbhw = &virgefb_hw_switch; | ||
1782 | strcpy(fb_info.modename, virgefb_name); | ||
1783 | fb_info.changevar = NULL; | ||
1784 | fb_info.fbops = &virgefb_ops; | ||
1785 | fb_info.disp = &disp; | ||
1786 | fb_info.currcon = -1; | ||
1787 | fb_info.switch_con = &virgefb_switch; | ||
1788 | fb_info.updatevar = &virgefb_updatevar; | ||
1789 | fb_info.flags = FBINFO_FLAG_DEFAULT; | ||
1790 | fbhw->init(); | ||
1791 | fbhw->decode_var(&virgefb_default, &par); | ||
1792 | fbhw->encode_var(&virgefb_default, &par); | ||
1793 | virgefb_do_fb_set_var(&virgefb_default, 1); | ||
1794 | virgefb_get_var(&fb_display[0].var, -1, &fb_info); | ||
1795 | virgefb_set_disp(-1, &fb_info); | ||
1796 | do_install_cmap(0, &fb_info); | ||
1797 | |||
1798 | if (register_framebuffer(&fb_info) < 0) { | ||
1799 | #warning release resources | ||
1800 | printk(KERN_ERR "virgefb.c: register_framebuffer failed\n"); | ||
1801 | DPRINTK("EXIT\n"); | ||
1802 | goto out_unmap; | ||
1803 | } | ||
1804 | |||
1805 | printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n", | ||
1806 | fb_info.node, fb_info.modename, v_ram_size>>10); | ||
1807 | |||
1808 | /* TODO: This driver cannot be unloaded yet */ | ||
1809 | |||
1810 | DPRINTK("EXIT\n"); | ||
1811 | return 0; | ||
1812 | |||
1813 | out_unmap: | ||
1814 | if (board_addr >= 0x01000000) { | ||
1815 | if (v_ram) | ||
1816 | iounmap((void*)v_ram); | ||
1817 | if (vgaio_regs) | ||
1818 | iounmap(vgaio_regs); | ||
1819 | if (mmio_regs) | ||
1820 | iounmap(mmio_regs); | ||
1821 | if (vcode_switch_base) | ||
1822 | iounmap((void*)vcode_switch_base); | ||
1823 | v_ram = vcode_switch_base = 0; | ||
1824 | vgaio_regs = mmio_regs = NULL; | ||
1825 | } | ||
1826 | return -EINVAL; | ||
1827 | } | ||
1828 | |||
1829 | |||
1830 | static int virgefb_switch(int con, struct fb_info *info) | ||
1831 | { | ||
1832 | DPRINTK("ENTER\n"); | ||
1833 | /* Do we have to save the colormap? */ | ||
1834 | if (fb_display[info->currcon].cmap.len) | ||
1835 | fb_get_cmap(&fb_display[info->currcon].cmap, 1, | ||
1836 | fbhw->getcolreg, info); | ||
1837 | virgefb_do_fb_set_var(&fb_display[con].var, 1); | ||
1838 | info->currcon = con; | ||
1839 | /* Install new colormap */ | ||
1840 | do_install_cmap(con, info); | ||
1841 | DPRINTK("EXIT\n"); | ||
1842 | return 0; | ||
1843 | } | ||
1844 | |||
1845 | |||
1846 | /* | ||
1847 | * Update the `var' structure (called by fbcon.c) | ||
1848 | * | ||
1849 | * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. | ||
1850 | * Since it's called by a kernel driver, no range checking is done. | ||
1851 | */ | ||
1852 | |||
1853 | static int virgefb_updatevar(int con, struct fb_info *info) | ||
1854 | { | ||
1855 | DPRINTK("ENTER\n"); | ||
1856 | return 0; | ||
1857 | DPRINTK("EXIT\n"); | ||
1858 | } | ||
1859 | |||
1860 | /* | ||
1861 | * Blank the display. | ||
1862 | */ | ||
1863 | |||
1864 | static int virgefb_blank(int blank, struct fb_info *info) | ||
1865 | { | ||
1866 | DPRINTK("ENTER\n"); | ||
1867 | fbhw->blank(blank); | ||
1868 | DPRINTK("EXIT\n"); | ||
1869 | return 0; | ||
1870 | } | ||
1871 | |||
1872 | |||
1873 | /* | ||
1874 | * Text console acceleration | ||
1875 | */ | ||
1876 | |||
1877 | #ifdef FBCON_HAS_CFB8 | ||
1878 | static void fbcon_virge8_bmove(struct display *p, int sy, int sx, int dy, | ||
1879 | int dx, int height, int width) | ||
1880 | { | ||
1881 | sx *= 8; dx *= 8; width *= 8; | ||
1882 | virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx, | ||
1883 | (u_short)(dy*fontheight(p)), (u_short)width, | ||
1884 | (u_short)(height*fontheight(p)), (u_short)p->next_line, 8); | ||
1885 | } | ||
1886 | |||
1887 | static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy, | ||
1888 | int sx, int height, int width) | ||
1889 | { | ||
1890 | unsigned char bg; | ||
1891 | |||
1892 | sx *= 8; width *= 8; | ||
1893 | bg = attr_bgcol_ec(p,conp); | ||
1894 | virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)), | ||
1895 | (u_short)width, (u_short)(height*fontheight(p)), | ||
1896 | (u_short)bg, (u_short)p->next_line, 8); | ||
1897 | } | ||
1898 | |||
1899 | static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy, | ||
1900 | int xx) | ||
1901 | { | ||
1902 | if (blit_maybe_busy) | ||
1903 | virgefb_wait_for_idle(); | ||
1904 | fbcon_cfb8_putc(conp, p, c, yy, xx); | ||
1905 | } | ||
1906 | |||
1907 | static void fbcon_virge8_putcs(struct vc_data *conp, struct display *p, | ||
1908 | const unsigned short *s, int count, int yy, int xx) | ||
1909 | { | ||
1910 | if (blit_maybe_busy) | ||
1911 | virgefb_wait_for_idle(); | ||
1912 | fbcon_cfb8_putcs(conp, p, s, count, yy, xx); | ||
1913 | } | ||
1914 | |||
1915 | static void fbcon_virge8_revc(struct display *p, int xx, int yy) | ||
1916 | { | ||
1917 | if (blit_maybe_busy) | ||
1918 | virgefb_wait_for_idle(); | ||
1919 | fbcon_cfb8_revc(p, xx, yy); | ||
1920 | } | ||
1921 | |||
1922 | static void fbcon_virge8_clear_margins(struct vc_data *conp, struct display *p, | ||
1923 | int bottom_only) | ||
1924 | { | ||
1925 | if (blit_maybe_busy) | ||
1926 | virgefb_wait_for_idle(); | ||
1927 | fbcon_cfb8_clear_margins(conp, p, bottom_only); | ||
1928 | } | ||
1929 | |||
1930 | static struct display_switch fbcon_virge8 = { | ||
1931 | .setup = fbcon_cfb8_setup, | ||
1932 | .bmove = fbcon_virge8_bmove, | ||
1933 | .clear = fbcon_virge8_clear, | ||
1934 | .putc = fbcon_virge8_putc, | ||
1935 | .putcs = fbcon_virge8_putcs, | ||
1936 | .revc = fbcon_virge8_revc, | ||
1937 | .clear_margins = fbcon_virge8_clear_margins, | ||
1938 | .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) | ||
1939 | }; | ||
1940 | #endif | ||
1941 | |||
1942 | #ifdef FBCON_HAS_CFB16 | ||
1943 | static void fbcon_virge16_bmove(struct display *p, int sy, int sx, int dy, | ||
1944 | int dx, int height, int width) | ||
1945 | { | ||
1946 | sx *= 8; dx *= 8; width *= 8; | ||
1947 | virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx, | ||
1948 | (u_short)(dy*fontheight(p)), (u_short)width, | ||
1949 | (u_short)(height*fontheight(p)), (u_short)p->next_line, 16); | ||
1950 | } | ||
1951 | |||
1952 | static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy, | ||
1953 | int sx, int height, int width) | ||
1954 | { | ||
1955 | unsigned char bg; | ||
1956 | |||
1957 | sx *= 8; width *= 8; | ||
1958 | bg = attr_bgcol_ec(p,conp); | ||
1959 | virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)), | ||
1960 | (u_short)width, (u_short)(height*fontheight(p)), | ||
1961 | (u_short)bg, (u_short)p->next_line, 16); | ||
1962 | } | ||
1963 | |||
1964 | static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy, | ||
1965 | int xx) | ||
1966 | { | ||
1967 | if (blit_maybe_busy) | ||
1968 | virgefb_wait_for_idle(); | ||
1969 | fbcon_cfb16_putc(conp, p, c, yy, xx); | ||
1970 | } | ||
1971 | |||
1972 | static void fbcon_virge16_putcs(struct vc_data *conp, struct display *p, | ||
1973 | const unsigned short *s, int count, int yy, int xx) | ||
1974 | { | ||
1975 | if (blit_maybe_busy) | ||
1976 | virgefb_wait_for_idle(); | ||
1977 | fbcon_cfb16_putcs(conp, p, s, count, yy, xx); | ||
1978 | } | ||
1979 | |||
1980 | static void fbcon_virge16_revc(struct display *p, int xx, int yy) | ||
1981 | { | ||
1982 | if (blit_maybe_busy) | ||
1983 | virgefb_wait_for_idle(); | ||
1984 | fbcon_cfb16_revc(p, xx, yy); | ||
1985 | } | ||
1986 | |||
1987 | static void fbcon_virge16_clear_margins(struct vc_data *conp, struct display *p, | ||
1988 | int bottom_only) | ||
1989 | { | ||
1990 | if (blit_maybe_busy) | ||
1991 | virgefb_wait_for_idle(); | ||
1992 | fbcon_cfb16_clear_margins(conp, p, bottom_only); | ||
1993 | } | ||
1994 | |||
1995 | static struct display_switch fbcon_virge16 = { | ||
1996 | .setup = fbcon_cfb16_setup, | ||
1997 | .bmove = fbcon_virge16_bmove, | ||
1998 | .clear = fbcon_virge16_clear, | ||
1999 | .putc = fbcon_virge16_putc, | ||
2000 | .putcs = fbcon_virge16_putcs, | ||
2001 | .revc = fbcon_virge16_revc, | ||
2002 | .clear_margins = fbcon_virge16_clear_margins, | ||
2003 | .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) | ||
2004 | }; | ||
2005 | #endif | ||
2006 | |||
2007 | #ifdef FBCON_HAS_CFB32 | ||
2008 | static void fbcon_virge32_bmove(struct display *p, int sy, int sx, int dy, | ||
2009 | int dx, int height, int width) | ||
2010 | { | ||
2011 | sx *= 16; dx *= 16; width *= 16; /* doubled these values to do 32 bit blit */ | ||
2012 | virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx, | ||
2013 | (u_short)(dy*fontheight(p)), (u_short)width, | ||
2014 | (u_short)(height*fontheight(p)), (u_short)p->next_line, 16); | ||
2015 | } | ||
2016 | |||
2017 | static void fbcon_virge32_clear(struct vc_data *conp, struct display *p, int sy, | ||
2018 | int sx, int height, int width) | ||
2019 | { | ||
2020 | unsigned char bg; | ||
2021 | |||
2022 | sx *= 16; width *= 16; /* doubled these values to do 32 bit blit */ | ||
2023 | bg = attr_bgcol_ec(p,conp); | ||
2024 | virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)), | ||
2025 | (u_short)width, (u_short)(height*fontheight(p)), | ||
2026 | (u_short)bg, (u_short)p->next_line, 16); | ||
2027 | } | ||
2028 | |||
2029 | static void fbcon_virge32_putc(struct vc_data *conp, struct display *p, int c, int yy, | ||
2030 | int xx) | ||
2031 | { | ||
2032 | if (blit_maybe_busy) | ||
2033 | virgefb_wait_for_idle(); | ||
2034 | fbcon_cfb32_putc(conp, p, c, yy, xx); | ||
2035 | } | ||
2036 | |||
2037 | static void fbcon_virge32_putcs(struct vc_data *conp, struct display *p, | ||
2038 | const unsigned short *s, int count, int yy, int xx) | ||
2039 | { | ||
2040 | if (blit_maybe_busy) | ||
2041 | virgefb_wait_for_idle(); | ||
2042 | fbcon_cfb32_putcs(conp, p, s, count, yy, xx); | ||
2043 | } | ||
2044 | |||
2045 | static void fbcon_virge32_revc(struct display *p, int xx, int yy) | ||
2046 | { | ||
2047 | if (blit_maybe_busy) | ||
2048 | virgefb_wait_for_idle(); | ||
2049 | fbcon_cfb32_revc(p, xx, yy); | ||
2050 | } | ||
2051 | |||
2052 | static void fbcon_virge32_clear_margins(struct vc_data *conp, struct display *p, | ||
2053 | int bottom_only) | ||
2054 | { | ||
2055 | if (blit_maybe_busy) | ||
2056 | virgefb_wait_for_idle(); | ||
2057 | fbcon_cfb32_clear_margins(conp, p, bottom_only); | ||
2058 | } | ||
2059 | |||
2060 | static struct display_switch fbcon_virge32 = { | ||
2061 | .setup = fbcon_cfb32_setup, | ||
2062 | .bmove = fbcon_virge32_bmove, | ||
2063 | .clear = fbcon_virge32_clear, | ||
2064 | .putc = fbcon_virge32_putc, | ||
2065 | .putcs = fbcon_virge32_putcs, | ||
2066 | .revc = fbcon_virge32_revc, | ||
2067 | .clear_margins = fbcon_virge32_clear_margins, | ||
2068 | .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) | ||
2069 | }; | ||
2070 | #endif | ||
2071 | |||
2072 | #ifdef MODULE | ||
2073 | MODULE_LICENSE("GPL"); | ||
2074 | |||
2075 | int init_module(void) | ||
2076 | { | ||
2077 | return virgefb_init(); | ||
2078 | } | ||
2079 | #endif /* MODULE */ | ||
2080 | |||
2081 | static int cv3d_has_4mb(void) | ||
2082 | { | ||
2083 | /* cyberfb version didn't work, neither does this (not reliably) | ||
2084 | forced to return 4MB */ | ||
2085 | #if 0 | ||
2086 | volatile unsigned long *t0, *t2; | ||
2087 | #endif | ||
2088 | DPRINTK("ENTER\n"); | ||
2089 | #if 0 | ||
2090 | /* write patterns in memory and test if they can be read */ | ||
2091 | t0 = (volatile unsigned long *)v_ram; | ||
2092 | t2 = (volatile unsigned long *)(v_ram + 0x00200000); | ||
2093 | *t0 = 0x87654321; | ||
2094 | *t2 = 0x12345678; | ||
2095 | |||
2096 | if (*t0 != 0x87654321) { | ||
2097 | /* read of first location failed */ | ||
2098 | DPRINTK("EXIT - 0MB !\n"); | ||
2099 | return 0; | ||
2100 | } | ||
2101 | |||
2102 | if (*t2 == 0x87654321) { | ||
2103 | /* should read 0x12345678 if 4MB */ | ||
2104 | DPRINTK("EXIT - 2MB(a) \n"); | ||
2105 | return 0; | ||
2106 | } | ||
2107 | |||
2108 | if (*t2 != 0x12345678) { | ||
2109 | /* upper 2MB read back match failed */ | ||
2110 | DPRINTK("EXIT - 2MB(b)\n"); | ||
2111 | return 0; | ||
2112 | } | ||
2113 | |||
2114 | /* may have 4MB */ | ||
2115 | |||
2116 | *t2 = 0xAAAAAAAA; | ||
2117 | |||
2118 | if(*t2 != 0xAAAAAAAA) { | ||
2119 | /* upper 2MB read back match failed */ | ||
2120 | DPRINTK("EXIT - 2MB(c)\n"); | ||
2121 | return 0; | ||
2122 | } | ||
2123 | |||
2124 | *t2 = 0x55555555; | ||
2125 | |||
2126 | if(*t2 != 0x55555555) { | ||
2127 | /* upper 2MB read back match failed */ | ||
2128 | DPRINTK("EXIT - 2MB(d)\n"); | ||
2129 | return 0; | ||
2130 | } | ||
2131 | |||
2132 | #endif | ||
2133 | DPRINTK("EXIT - 4MB\n"); | ||
2134 | return 1; | ||
2135 | } | ||
2136 | |||
2137 | |||
2138 | /* | ||
2139 | * Computes M, N, and R pll params for freq arg. | ||
2140 | * Returns 16 bits - hi 0MMMMMM lo 0RRNNNNN | ||
2141 | */ | ||
2142 | |||
2143 | #define REFCLOCK 14318000 | ||
2144 | |||
2145 | static unsigned short virgefb_compute_clock(unsigned long freq) | ||
2146 | { | ||
2147 | |||
2148 | unsigned char m, n, r, rpwr; | ||
2149 | unsigned long diff, ftry, save = ~0UL; | ||
2150 | unsigned short mnr; | ||
2151 | |||
2152 | DPRINTK("ENTER\n"); | ||
2153 | |||
2154 | for (r = 0, rpwr = 1 ; r < 4 ; r++, rpwr *= 2) { | ||
2155 | if ((135000000 <= (rpwr * freq)) && ((rpwr * freq) <= 270000000)) { | ||
2156 | for (n = 1 ; n < 32 ; n++) { | ||
2157 | m = ((freq * (n + 2) * rpwr)/REFCLOCK) - 2; | ||
2158 | if (m == 0 || m >127) | ||
2159 | break; | ||
2160 | ftry = ((REFCLOCK / (n + 2)) * (m + 2)) / rpwr; | ||
2161 | if (ftry > freq) | ||
2162 | diff = ftry - freq; | ||
2163 | else | ||
2164 | diff = freq - ftry; | ||
2165 | if (diff < save) { | ||
2166 | save = diff; | ||
2167 | mnr = (m << 8) | (r<<5) | (n & 0x7f); | ||
2168 | } | ||
2169 | } | ||
2170 | } | ||
2171 | } | ||
2172 | if (save == ~0UL) | ||
2173 | printk("Can't compute clock PLL values for %ld Hz clock\n", freq); | ||
2174 | DPRINTK("EXIT\n"); | ||
2175 | return(mnr); | ||
2176 | } | ||
2177 | |||
2178 | static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode) | ||
2179 | { | ||
2180 | unsigned char lace, dblscan, tmp; | ||
2181 | unsigned short mnr; | ||
2182 | unsigned short HT, HDE, HBS, HBW, HSS, HSW; | ||
2183 | unsigned short VT, VDE, VBS, VBW, VSS, VSW; | ||
2184 | unsigned short SCO; | ||
2185 | int cr11; | ||
2186 | int cr67; | ||
2187 | int hmul; | ||
2188 | int xres, xres_virtual, hfront, hsync, hback; | ||
2189 | int yres, vfront, vsync, vback; | ||
2190 | int bpp; | ||
2191 | int i; | ||
2192 | long freq; | ||
2193 | |||
2194 | DPRINTK("ENTER : %dx%d-%d\n",video_mode->xres, video_mode->yres, | ||
2195 | video_mode->bits_per_pixel); | ||
2196 | |||
2197 | bpp = video_mode->bits_per_pixel; | ||
2198 | xres = video_mode->xres; | ||
2199 | xres_virtual = video_mode->xres_virtual; | ||
2200 | hfront = video_mode->right_margin; | ||
2201 | hsync = video_mode->hsync_len; | ||
2202 | hback = video_mode->left_margin; | ||
2203 | |||
2204 | lace = 0; | ||
2205 | dblscan = 0; | ||
2206 | |||
2207 | if (video_mode->vmode & FB_VMODE_DOUBLE) { | ||
2208 | yres = video_mode->yres * 2; | ||
2209 | vfront = video_mode->lower_margin * 2; | ||
2210 | vsync = video_mode->vsync_len * 2; | ||
2211 | vback = video_mode->upper_margin * 2; | ||
2212 | dblscan = 1; | ||
2213 | } else if (video_mode->vmode & FB_VMODE_INTERLACED) { | ||
2214 | yres = (video_mode->yres + 1) / 2; | ||
2215 | vfront = (video_mode->lower_margin + 1) / 2; | ||
2216 | vsync = (video_mode->vsync_len + 1) / 2; | ||
2217 | vback = (video_mode->upper_margin + 1) / 2; | ||
2218 | lace = 1; | ||
2219 | } else { | ||
2220 | yres = video_mode->yres; | ||
2221 | vfront = video_mode->lower_margin; | ||
2222 | vsync = video_mode->vsync_len; | ||
2223 | vback = video_mode->upper_margin; | ||
2224 | } | ||
2225 | |||
2226 | switch (bpp) { | ||
2227 | case 8: | ||
2228 | video_mode->red.offset = 0; | ||
2229 | video_mode->green.offset = 0; | ||
2230 | video_mode->blue.offset = 0; | ||
2231 | video_mode->transp.offset = 0; | ||
2232 | video_mode->red.length = 8; | ||
2233 | video_mode->green.length = 8; | ||
2234 | video_mode->blue.length = 8; | ||
2235 | video_mode->transp.length = 0; | ||
2236 | hmul = 1; | ||
2237 | cr67 = 0x00; | ||
2238 | SCO = xres_virtual / 8; | ||
2239 | break; | ||
2240 | case 16: | ||
2241 | video_mode->red.offset = 11; | ||
2242 | video_mode->green.offset = 5; | ||
2243 | video_mode->blue.offset = 0; | ||
2244 | video_mode->transp.offset = 0; | ||
2245 | video_mode->red.length = 5; | ||
2246 | video_mode->green.length = 6; | ||
2247 | video_mode->blue.length = 5; | ||
2248 | video_mode->transp.length = 0; | ||
2249 | hmul = 2; | ||
2250 | cr67 = 0x50; | ||
2251 | SCO = xres_virtual / 4; | ||
2252 | break; | ||
2253 | case 32: | ||
2254 | video_mode->red.offset = 16; | ||
2255 | video_mode->green.offset = 8; | ||
2256 | video_mode->blue.offset = 0; | ||
2257 | video_mode->transp.offset = 24; | ||
2258 | video_mode->red.length = 8; | ||
2259 | video_mode->green.length = 8; | ||
2260 | video_mode->blue.length = 8; | ||
2261 | video_mode->transp.length = 8; | ||
2262 | hmul = 1; | ||
2263 | cr67 = 0xd0; | ||
2264 | SCO = xres_virtual / 2; | ||
2265 | break; | ||
2266 | } | ||
2267 | |||
2268 | HT = (((xres + hfront + hsync + hback) / 8) * hmul) - 5; | ||
2269 | HDE = ((xres / 8) * hmul) - 1; | ||
2270 | HBS = (xres / 8) * hmul; | ||
2271 | HSS = ((xres + hfront) / 8) * hmul; | ||
2272 | HSW = (hsync / 8) * hmul; | ||
2273 | HBW = (((hfront + hsync + hback) / 8) * hmul) - 2; | ||
2274 | |||
2275 | VT = yres + vfront + vsync + vback - 2; | ||
2276 | VDE = yres - 1; | ||
2277 | VBS = yres - 1; | ||
2278 | VSS = yres + vfront; | ||
2279 | VSW = vsync; | ||
2280 | VBW = vfront + vsync + vback - 2; | ||
2281 | |||
2282 | #ifdef VIRGEFBDEBUG | ||
2283 | DPRINTK("HDE : 0x%4.4x, %4.4d\n", HDE, HDE); | ||
2284 | DPRINTK("HBS : 0x%4.4x, %4.4d\n", HBS, HBS); | ||
2285 | DPRINTK("HSS : 0x%4.4x, %4.4d\n", HSS, HSS); | ||
2286 | DPRINTK("HSW : 0x%4.4x, %4.4d\n", HSW, HSW); | ||
2287 | DPRINTK("HBW : 0x%4.4x, %4.4d\n", HBW, HBW); | ||
2288 | DPRINTK("HSS + HSW : 0x%4.4x, %4.4d\n", HSS+HSW, HSS+HSW); | ||
2289 | DPRINTK("HBS + HBW : 0x%4.4x, %4.4d\n", HBS+HBW, HBS+HBW); | ||
2290 | DPRINTK("HT : 0x%4.4x, %4.4d\n", HT, HT); | ||
2291 | DPRINTK("VDE : 0x%4.4x, %4.4d\n", VDE, VDE); | ||
2292 | DPRINTK("VBS : 0x%4.4x, %4.4d\n", VBS, VBS); | ||
2293 | DPRINTK("VSS : 0x%4.4x, %4.4d\n", VSS, VSS); | ||
2294 | DPRINTK("VSW : 0x%4.4x, %4.4d\n", VSW, VSW); | ||
2295 | DPRINTK("VBW : 0x%4.4x, %4.4d\n", VBW, VBW); | ||
2296 | DPRINTK("VT : 0x%4.4x, %4.4d\n", VT, VT); | ||
2297 | #endif | ||
2298 | |||
2299 | /* turn gfx off, don't mess up the display */ | ||
2300 | |||
2301 | gfx_on_off(1); | ||
2302 | |||
2303 | /* H and V sync polarity */ | ||
2304 | |||
2305 | tmp = rb_mmio(GREG_MISC_OUTPUT_R) & 0x2f; /* colour, ram enable, clk sr12/s13 sel */ | ||
2306 | if (!(video_mode->sync & FB_SYNC_HOR_HIGH_ACT)) | ||
2307 | tmp |= 0x40; /* neg H sync polarity */ | ||
2308 | if (!(video_mode->sync & FB_SYNC_VERT_HIGH_ACT)) | ||
2309 | tmp |= 0x80; /* neg V sync polarity */ | ||
2310 | tmp |= 0x0c; /* clk from sr12/sr13 */ | ||
2311 | wb_mmio(GREG_MISC_OUTPUT_W, tmp); | ||
2312 | |||
2313 | /* clocks */ | ||
2314 | |||
2315 | wseq(SEQ_ID_BUS_REQ_CNTL, 0xc0); /* 2 clk mem wr and /RAS1 */ | ||
2316 | wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80); /* b7 is 2 mem clk wr */ | ||
2317 | mnr = virgefb_compute_clock(MEMCLOCK); | ||
2318 | DPRINTK("mem clock %d, m %d, n %d, r %d.\n", MEMCLOCK, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr >> 5)&0x03)); | ||
2319 | wseq(SEQ_ID_MCLK_LO, (mnr & 0x7f)); | ||
2320 | wseq(SEQ_ID_MCLK_HI, ((mnr & 0x7f00) >> 8)); | ||
2321 | freq = (1000000000 / video_mode->pixclock) * 1000; /* pixclock is in ps ... convert to Hz */ | ||
2322 | mnr = virgefb_compute_clock(freq); | ||
2323 | DPRINTK("dot clock %ld, m %d, n %d, r %d.\n", freq, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr>>5)&0x03)); | ||
2324 | wseq(SEQ_ID_DCLK_LO, (mnr & 0x7f)); | ||
2325 | wseq(SEQ_ID_DCLK_HI, ((mnr & 0x7f00) >> 8)); | ||
2326 | wseq(SEQ_ID_CLKSYN_CNTL_2, 0xa0); | ||
2327 | wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80); | ||
2328 | udelay(100); | ||
2329 | |||
2330 | /* load display parameters into board */ | ||
2331 | |||
2332 | /* not sure about sync and blanking extensions bits in cr5d and cr5 */ | ||
2333 | |||
2334 | wcrt(CRT_ID_EXT_HOR_OVF, /* 0x5d */ | ||
2335 | ((HT & 0x100) ? 0x01 : 0x00) | | ||
2336 | ((HDE & 0x100) ? 0x02 : 0x00) | | ||
2337 | ((HBS & 0x100) ? 0x04 : 0x00) | | ||
2338 | /* (((HBS + HBW) & 0x40) ? 0x08 : 0x00) | */ | ||
2339 | ((HSS & 0x100) ? 0x10 : 0x00) | | ||
2340 | /* (((HSS + HSW) & 0x20) ? 0x20 : 0x00) | */ | ||
2341 | ((HSW >= 0x20) ? 0x20 : 0x00) | | ||
2342 | (((HT-5) & 0x100) ? 0x40 : 0x00)); | ||
2343 | |||
2344 | wcrt(CRT_ID_EXT_VER_OVF, /* 0x5e */ | ||
2345 | ((VT & 0x400) ? 0x01 : 0x00) | | ||
2346 | ((VDE & 0x400) ? 0x02 : 0x00) | | ||
2347 | ((VBS & 0x400) ? 0x04 : 0x00) | | ||
2348 | ((VSS & 0x400) ? 0x10 : 0x00) | | ||
2349 | 0x40); /* line compare */ | ||
2350 | |||
2351 | wcrt(CRT_ID_START_VER_RETR, VSS); | ||
2352 | cr11 = rcrt(CRT_ID_END_VER_RETR) | 0x20; /* vert interrupt flag */ | ||
2353 | wcrt(CRT_ID_END_VER_RETR, ((cr11 & 0x20) | ((VSS + VSW) & 0x0f))); /* keeps vert irq enable state, also has unlock bit cr0 to 7 */ | ||
2354 | wcrt(CRT_ID_VER_DISP_ENA_END, VDE); | ||
2355 | wcrt(CRT_ID_START_VER_BLANK, VBS); | ||
2356 | wcrt(CRT_ID_END_VER_BLANK, VBS + VBW); /* might be +/- 1 out */ | ||
2357 | wcrt(CRT_ID_HOR_TOTAL, HT); | ||
2358 | wcrt(CRT_ID_DISPLAY_FIFO, HT - 5); | ||
2359 | wcrt(CRT_ID_BACKWAD_COMP_3, 0x10); /* enable display fifo */ | ||
2360 | wcrt(CRT_ID_HOR_DISP_ENA_END, HDE); | ||
2361 | wcrt(CRT_ID_START_HOR_BLANK , HBS); | ||
2362 | wcrt(CRT_ID_END_HOR_BLANK, (HBS + HBW) & 0x1f); | ||
2363 | wcrt(CRT_ID_START_HOR_RETR, HSS); | ||
2364 | wcrt(CRT_ID_END_HOR_RETR, /* cr5 */ | ||
2365 | ((HSS + HSW) & 0x1f) | | ||
2366 | (((HBS + HBW) & 0x20) ? 0x80 : 0x00)); | ||
2367 | wcrt(CRT_ID_VER_TOTAL, VT); | ||
2368 | wcrt(CRT_ID_OVERFLOW, | ||
2369 | ((VT & 0x100) ? 0x01 : 0x00) | | ||
2370 | ((VDE & 0x100) ? 0x02 : 0x00) | | ||
2371 | ((VSS & 0x100) ? 0x04 : 0x00) | | ||
2372 | ((VBS & 0x100) ? 0x08 : 0x00) | | ||
2373 | 0x10 | | ||
2374 | ((VT & 0x200) ? 0x20 : 0x00) | | ||
2375 | ((VDE & 0x200) ? 0x40 : 0x00) | | ||
2376 | ((VSS & 0x200) ? 0x80 : 0x00)); | ||
2377 | wcrt(CRT_ID_MAX_SCAN_LINE, | ||
2378 | (dblscan ? 0x80 : 0x00) | | ||
2379 | 0x40 | | ||
2380 | ((VBS & 0x200) ? 0x20 : 0x00)); | ||
2381 | wcrt(CRT_ID_LINE_COMPARE, 0xff); | ||
2382 | wcrt(CRT_ID_LACE_RETR_START, HT / 2); /* (HT-5)/2 ? */ | ||
2383 | wcrt(CRT_ID_LACE_CONTROL, (lace ? 0x20 : 0x00)); | ||
2384 | |||
2385 | wcrt(CRT_ID_SCREEN_OFFSET, SCO); | ||
2386 | wcrt(CRT_ID_EXT_SYS_CNTL_2, (SCO >> 4) & 0x30 ); | ||
2387 | |||
2388 | /* wait for vert sync before cr67 update */ | ||
2389 | |||
2390 | for (i=0; i < 10000; i++) { | ||
2391 | udelay(10); | ||
2392 | mb(); | ||
2393 | if (rb_mmio(GREG_INPUT_STATUS1_R) & 0x08) | ||
2394 | break; | ||
2395 | } | ||
2396 | |||
2397 | wl_mmio(0x8200, 0x0000c000); /* fifo control (0x00110400 ?) */ | ||
2398 | wcrt(CRT_ID_EXT_MISC_CNTL_2, cr67); | ||
2399 | |||
2400 | /* enable video */ | ||
2401 | |||
2402 | tmp = rb_mmio(ACT_ADDRESS_RESET); | ||
2403 | wb_mmio(ACT_ADDRESS_W, ((bpp == 8) ? 0x20 : 0x00)); /* set b5, ENB PLT in attr idx reg) */ | ||
2404 | tmp = rb_mmio(ACT_ADDRESS_RESET); | ||
2405 | |||
2406 | /* turn gfx on again */ | ||
2407 | |||
2408 | gfx_on_off(0); | ||
2409 | |||
2410 | /* pass-through */ | ||
2411 | |||
2412 | SetVSwitch(1); /* cv3d */ | ||
2413 | |||
2414 | DUMP; | ||
2415 | DPRINTK("EXIT\n"); | ||
2416 | } | ||
2417 | |||
2418 | static inline void gfx_on_off(int toggle) | ||
2419 | { | ||
2420 | unsigned char tmp; | ||
2421 | |||
2422 | DPRINTK("ENTER gfx %s\n", (toggle ? "off" : "on")); | ||
2423 | |||
2424 | toggle = (toggle & 0x01) << 5; | ||
2425 | tmp = rseq(SEQ_ID_CLOCKING_MODE) & (~(0x01 << 5)); | ||
2426 | wseq(SEQ_ID_CLOCKING_MODE, tmp | toggle); | ||
2427 | |||
2428 | DPRINTK("EXIT\n"); | ||
2429 | } | ||
2430 | |||
2431 | #if defined (VIRGEFBDUMP) | ||
2432 | |||
2433 | /* | ||
2434 | * Dump board registers | ||
2435 | */ | ||
2436 | |||
2437 | static void cv64_dump(void) | ||
2438 | { | ||
2439 | int i; | ||
2440 | u8 c, b; | ||
2441 | u16 w; | ||
2442 | u32 l; | ||
2443 | |||
2444 | /* crt, seq, gfx and atr regs */ | ||
2445 | |||
2446 | SelectMMIO; | ||
2447 | |||
2448 | printk("\n"); | ||
2449 | for (i = 0; i <= 0x6f; i++) { | ||
2450 | wb_mmio(CRT_ADDRESS, i); | ||
2451 | printk("crt idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(CRT_ADDRESS_R)); | ||
2452 | } | ||
2453 | for (i = 0; i <= 0x1c; i++) { | ||
2454 | wb_mmio(SEQ_ADDRESS, i); | ||
2455 | printk("seq idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(SEQ_ADDRESS_R)); | ||
2456 | } | ||
2457 | for (i = 0; i <= 8; i++) { | ||
2458 | wb_mmio(GCT_ADDRESS, i); | ||
2459 | printk("gfx idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(GCT_ADDRESS_R)); | ||
2460 | } | ||
2461 | for (i = 0; i <= 0x14; i++) { | ||
2462 | c = rb_mmio(ACT_ADDRESS_RESET); | ||
2463 | wb_mmio(ACT_ADDRESS_W, i); | ||
2464 | printk("atr idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(ACT_ADDRESS_R)); | ||
2465 | } | ||
2466 | |||
2467 | /* re-enable video access to palette */ | ||
2468 | |||
2469 | c = rb_mmio(ACT_ADDRESS_RESET); | ||
2470 | udelay(10); | ||
2471 | wb_mmio(ACT_ADDRESS_W, 0x20); | ||
2472 | c = rb_mmio(ACT_ADDRESS_RESET); | ||
2473 | udelay(10); | ||
2474 | |||
2475 | /* general regs */ | ||
2476 | |||
2477 | printk("0x3cc(w 0x3c2) : 0x%2.2x\n", rb_mmio(0x3cc)); /* GREG_MISC_OUTPUT READ */ | ||
2478 | printk("0x3c2(-------) : 0x%2.2x\n", rb_mmio(0x3c2)); /* GREG_INPUT_STATUS 0 READ */ | ||
2479 | printk("0x3c3(w 0x3c3) : 0x%2.2x\n", rb_vgaio(0x3c3)); /* GREG_VIDEO_SUBS_ENABLE */ | ||
2480 | printk("0x3ca(w 0x3da) : 0x%2.2x\n", rb_vgaio(0x3ca)); /* GREG_FEATURE_CONTROL read */ | ||
2481 | printk("0x3da(-------) : 0x%2.2x\n", rb_mmio(0x3da)); /* GREG_INPUT_STATUS 1 READ */ | ||
2482 | |||
2483 | /* engine regs */ | ||
2484 | |||
2485 | for (i = 0x8180; i <= 0x8200; i = i + 4) | ||
2486 | printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i)); | ||
2487 | |||
2488 | i = 0x8504; | ||
2489 | printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i)); | ||
2490 | i = 0x850c; | ||
2491 | printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i)); | ||
2492 | for (i = 0xa4d4; i <= 0xa50c; i = i + 4) | ||
2493 | printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i)); | ||
2494 | |||
2495 | /* PCI regs */ | ||
2496 | |||
2497 | SelectCFG; | ||
2498 | |||
2499 | for (c = 0; c < 0x08; c = c + 2) { | ||
2500 | w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2))); | ||
2501 | printk("pci 0x%2.2x : 0x%4.4x\n", c, w); | ||
2502 | } | ||
2503 | c = 8; | ||
2504 | l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000))))); | ||
2505 | printk("pci 0x%2.2x : 0x%8.8x\n", c, l); | ||
2506 | c = 0x0d; | ||
2507 | b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3))); | ||
2508 | printk("pci 0x%2.2x : 0x%2.2x\n", c, b); | ||
2509 | c = 0x10; | ||
2510 | l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000))))); | ||
2511 | printk("pci 0x%2.2x : 0x%8.8x\n", c, l); | ||
2512 | c = 0x30; | ||
2513 | l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000))))); | ||
2514 | printk("pci 0x%2.2x : 0x%8.8x\n", c, l); | ||
2515 | c = 0x3c; | ||
2516 | b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3))); | ||
2517 | printk("pci 0x%2.2x : 0x%2.2x\n", c, b); | ||
2518 | c = 0x3d; | ||
2519 | b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3))); | ||
2520 | printk("pci 0x%2.2x : 0x%2.2x\n", c, b); | ||
2521 | c = 0x3e; | ||
2522 | w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2))); | ||
2523 | printk("pci 0x%2.2x : 0x%4.4x\n", c, w); | ||
2524 | SelectMMIO; | ||
2525 | } | ||
2526 | #endif | ||
diff --git a/drivers/video/virgefb.h b/drivers/video/virgefb.h deleted file mode 100644 index 157d66deb24..00000000000 --- a/drivers/video/virgefb.h +++ /dev/null | |||
@@ -1,288 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/virgefb.h -- CyberVision64 definitions for the | ||
3 | * text console driver. | ||
4 | * | ||
5 | * Copyright (c) 1998 Alan Bair | ||
6 | * | ||
7 | * This file is based on the initial port to Linux of grf_cvreg.h: | ||
8 | * | ||
9 | * Copyright (c) 1997 Antonio Santos | ||
10 | * | ||
11 | * The original work is from the NetBSD CyberVision 64 framebuffer driver | ||
12 | * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c): | ||
13 | * Permission to use the source of this driver was obtained from the | ||
14 | * author Michael Teske by Alan Bair. | ||
15 | * | ||
16 | * Copyright (c) 1995 Michael Teske | ||
17 | * | ||
18 | * History: | ||
19 | * | ||
20 | * | ||
21 | * | ||
22 | * This file is subject to the terms and conditions of the GNU General Public | ||
23 | * License. See the file COPYING in the main directory of this archive | ||
24 | * for more details. | ||
25 | */ | ||
26 | |||
27 | /* Enhanced register mapping (MMIO mode) */ | ||
28 | |||
29 | #define S3_CRTC_ADR 0x03d4 | ||
30 | #define S3_CRTC_DATA 0x03d5 | ||
31 | |||
32 | #define S3_REG_LOCK2 0x39 | ||
33 | #define S3_HGC_MODE 0x45 | ||
34 | |||
35 | #define S3_HWGC_ORGX_H 0x46 | ||
36 | #define S3_HWGC_ORGX_L 0x47 | ||
37 | #define S3_HWGC_ORGY_H 0x48 | ||
38 | #define S3_HWGC_ORGY_L 0x49 | ||
39 | #define S3_HWGC_DX 0x4e | ||
40 | #define S3_HWGC_DY 0x4f | ||
41 | |||
42 | #define S3_LAW_CTL 0x58 | ||
43 | |||
44 | /**************************************************/ | ||
45 | |||
46 | /* | ||
47 | * Defines for the used register addresses (mw) | ||
48 | * | ||
49 | * NOTE: There are some registers that have different addresses when | ||
50 | * in mono or color mode. We only support color mode, and thus | ||
51 | * some addresses won't work in mono-mode! | ||
52 | * | ||
53 | * General and VGA-registers taken from retina driver. Fixed a few | ||
54 | * bugs in it. (SR and GR read address is Port + 1, NOT Port) | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | /* General Registers: */ | ||
59 | #define GREG_MISC_OUTPUT_R 0x03CC | ||
60 | #define GREG_MISC_OUTPUT_W 0x03C2 | ||
61 | #define GREG_FEATURE_CONTROL_R 0x03CA | ||
62 | #define GREG_FEATURE_CONTROL_W 0x03DA | ||
63 | #define GREG_INPUT_STATUS0_R 0x03C2 | ||
64 | #define GREG_INPUT_STATUS1_R 0x03DA | ||
65 | |||
66 | /* Setup Registers: */ | ||
67 | #define SREG_VIDEO_SUBS_ENABLE 0x03C3 /* virge */ | ||
68 | |||
69 | /* Attribute Controller: */ | ||
70 | #define ACT_ADDRESS 0x03C0 | ||
71 | #define ACT_ADDRESS_R 0x03C1 | ||
72 | #define ACT_ADDRESS_W 0x03C0 | ||
73 | #define ACT_ADDRESS_RESET 0x03DA | ||
74 | #define ACT_ID_PALETTE0 0x00 | ||
75 | #define ACT_ID_PALETTE1 0x01 | ||
76 | #define ACT_ID_PALETTE2 0x02 | ||
77 | #define ACT_ID_PALETTE3 0x03 | ||
78 | #define ACT_ID_PALETTE4 0x04 | ||
79 | #define ACT_ID_PALETTE5 0x05 | ||
80 | #define ACT_ID_PALETTE6 0x06 | ||
81 | #define ACT_ID_PALETTE7 0x07 | ||
82 | #define ACT_ID_PALETTE8 0x08 | ||
83 | #define ACT_ID_PALETTE9 0x09 | ||
84 | #define ACT_ID_PALETTE10 0x0A | ||
85 | #define ACT_ID_PALETTE11 0x0B | ||
86 | #define ACT_ID_PALETTE12 0x0C | ||
87 | #define ACT_ID_PALETTE13 0x0D | ||
88 | #define ACT_ID_PALETTE14 0x0E | ||
89 | #define ACT_ID_PALETTE15 0x0F | ||
90 | #define ACT_ID_ATTR_MODE_CNTL 0x10 | ||
91 | #define ACT_ID_OVERSCAN_COLOR 0x11 | ||
92 | #define ACT_ID_COLOR_PLANE_ENA 0x12 | ||
93 | #define ACT_ID_HOR_PEL_PANNING 0x13 | ||
94 | #define ACT_ID_COLOR_SELECT 0x14 /* virge PX_PADD pixel padding register */ | ||
95 | |||
96 | /* Graphics Controller: */ | ||
97 | #define GCT_ADDRESS 0x03CE | ||
98 | #define GCT_ADDRESS_R 0x03CF | ||
99 | #define GCT_ADDRESS_W 0x03CF | ||
100 | #define GCT_ID_SET_RESET 0x00 | ||
101 | #define GCT_ID_ENABLE_SET_RESET 0x01 | ||
102 | #define GCT_ID_COLOR_COMPARE 0x02 | ||
103 | #define GCT_ID_DATA_ROTATE 0x03 | ||
104 | #define GCT_ID_READ_MAP_SELECT 0x04 | ||
105 | #define GCT_ID_GRAPHICS_MODE 0x05 | ||
106 | #define GCT_ID_MISC 0x06 | ||
107 | #define GCT_ID_COLOR_XCARE 0x07 | ||
108 | #define GCT_ID_BITMASK 0x08 | ||
109 | |||
110 | /* Sequencer: */ | ||
111 | #define SEQ_ADDRESS 0x03C4 | ||
112 | #define SEQ_ADDRESS_R 0x03C5 | ||
113 | #define SEQ_ADDRESS_W 0x03C5 | ||
114 | #define SEQ_ID_RESET 0x00 | ||
115 | #define SEQ_ID_CLOCKING_MODE 0x01 | ||
116 | #define SEQ_ID_MAP_MASK 0x02 | ||
117 | #define SEQ_ID_CHAR_MAP_SELECT 0x03 | ||
118 | #define SEQ_ID_MEMORY_MODE 0x04 | ||
119 | #define SEQ_ID_UNKNOWN1 0x05 | ||
120 | #define SEQ_ID_UNKNOWN2 0x06 | ||
121 | #define SEQ_ID_UNKNOWN3 0x07 | ||
122 | /* S3 extensions */ | ||
123 | #define SEQ_ID_UNLOCK_EXT 0x08 | ||
124 | #define SEQ_ID_EXT_SEQ_REG9 0x09 /* b7 = 1 extended reg access by MMIO only */ | ||
125 | #define SEQ_ID_BUS_REQ_CNTL 0x0A | ||
126 | #define SEQ_ID_EXT_MISC_SEQ 0x0B | ||
127 | #define SEQ_ID_UNKNOWN4 0x0C | ||
128 | #define SEQ_ID_EXT_SEQ 0x0D | ||
129 | #define SEQ_ID_UNKNOWN5 0x0E | ||
130 | #define SEQ_ID_UNKNOWN6 0x0F | ||
131 | #define SEQ_ID_MCLK_LO 0x10 | ||
132 | #define SEQ_ID_MCLK_HI 0x11 | ||
133 | #define SEQ_ID_DCLK_LO 0x12 | ||
134 | #define SEQ_ID_DCLK_HI 0x13 | ||
135 | #define SEQ_ID_CLKSYN_CNTL_1 0x14 | ||
136 | #define SEQ_ID_CLKSYN_CNTL_2 0x15 | ||
137 | #define SEQ_ID_CLKSYN_TEST_HI 0x16 /* reserved for S3 testing of the */ | ||
138 | #define SEQ_ID_CLKSYN_TEST_LO 0x17 /* internal clock synthesizer */ | ||
139 | #define SEQ_ID_RAMDAC_CNTL 0x18 | ||
140 | #define SEQ_ID_MORE_MAGIC 0x1A | ||
141 | #define SEQ_ID_SIGNAL_SELECT 0x1C /* new for virge */ | ||
142 | |||
143 | /* CRT Controller: */ | ||
144 | #define CRT_ADDRESS 0x03D4 | ||
145 | #define CRT_ADDRESS_R 0x03D5 | ||
146 | #define CRT_ADDRESS_W 0x03D5 | ||
147 | #define CRT_ID_HOR_TOTAL 0x00 | ||
148 | #define CRT_ID_HOR_DISP_ENA_END 0x01 | ||
149 | #define CRT_ID_START_HOR_BLANK 0x02 | ||
150 | #define CRT_ID_END_HOR_BLANK 0x03 | ||
151 | #define CRT_ID_START_HOR_RETR 0x04 | ||
152 | #define CRT_ID_END_HOR_RETR 0x05 | ||
153 | #define CRT_ID_VER_TOTAL 0x06 | ||
154 | #define CRT_ID_OVERFLOW 0x07 | ||
155 | #define CRT_ID_PRESET_ROW_SCAN 0x08 | ||
156 | #define CRT_ID_MAX_SCAN_LINE 0x09 | ||
157 | #define CRT_ID_CURSOR_START 0x0A | ||
158 | #define CRT_ID_CURSOR_END 0x0B | ||
159 | #define CRT_ID_START_ADDR_HIGH 0x0C | ||
160 | #define CRT_ID_START_ADDR_LOW 0x0D | ||
161 | #define CRT_ID_CURSOR_LOC_HIGH 0x0E | ||
162 | #define CRT_ID_CURSOR_LOC_LOW 0x0F | ||
163 | #define CRT_ID_START_VER_RETR 0x10 | ||
164 | #define CRT_ID_END_VER_RETR 0x11 | ||
165 | #define CRT_ID_VER_DISP_ENA_END 0x12 | ||
166 | #define CRT_ID_SCREEN_OFFSET 0x13 | ||
167 | #define CRT_ID_UNDERLINE_LOC 0x14 | ||
168 | #define CRT_ID_START_VER_BLANK 0x15 | ||
169 | #define CRT_ID_END_VER_BLANK 0x16 | ||
170 | #define CRT_ID_MODE_CONTROL 0x17 | ||
171 | #define CRT_ID_LINE_COMPARE 0x18 | ||
172 | #define CRT_ID_GD_LATCH_RBACK 0x22 | ||
173 | #define CRT_ID_ACT_TOGGLE_RBACK 0x24 | ||
174 | #define CRT_ID_ACT_INDEX_RBACK 0x26 | ||
175 | /* S3 extensions: S3 VGA Registers */ | ||
176 | #define CRT_ID_DEVICE_HIGH 0x2D | ||
177 | #define CRT_ID_DEVICE_LOW 0x2E | ||
178 | #define CRT_ID_REVISION 0x2F | ||
179 | #define CRT_ID_CHIP_ID_REV 0x30 | ||
180 | #define CRT_ID_MEMORY_CONF 0x31 | ||
181 | #define CRT_ID_BACKWAD_COMP_1 0x32 | ||
182 | #define CRT_ID_BACKWAD_COMP_2 0x33 | ||
183 | #define CRT_ID_BACKWAD_COMP_3 0x34 | ||
184 | #define CRT_ID_REGISTER_LOCK 0x35 | ||
185 | #define CRT_ID_CONFIG_1 0x36 | ||
186 | #define CRT_ID_CONFIG_2 0x37 | ||
187 | #define CRT_ID_REGISTER_LOCK_1 0x38 | ||
188 | #define CRT_ID_REGISTER_LOCK_2 0x39 | ||
189 | #define CRT_ID_MISC_1 0x3A | ||
190 | #define CRT_ID_DISPLAY_FIFO 0x3B | ||
191 | #define CRT_ID_LACE_RETR_START 0x3C | ||
192 | /* S3 extensions: System Control Registers */ | ||
193 | #define CRT_ID_SYSTEM_CONFIG 0x40 | ||
194 | #define CRT_ID_BIOS_FLAG 0x41 | ||
195 | #define CRT_ID_LACE_CONTROL 0x42 | ||
196 | #define CRT_ID_EXT_MODE 0x43 | ||
197 | #define CRT_ID_HWGC_MODE 0x45 /* HWGC = Hardware Graphics Cursor */ | ||
198 | #define CRT_ID_HWGC_ORIGIN_X_HI 0x46 | ||
199 | #define CRT_ID_HWGC_ORIGIN_X_LO 0x47 | ||
200 | #define CRT_ID_HWGC_ORIGIN_Y_HI 0x48 | ||
201 | #define CRT_ID_HWGC_ORIGIN_Y_LO 0x49 | ||
202 | #define CRT_ID_HWGC_FG_STACK 0x4A | ||
203 | #define CRT_ID_HWGC_BG_STACK 0x4B | ||
204 | #define CRT_ID_HWGC_START_AD_HI 0x4C | ||
205 | #define CRT_ID_HWGC_START_AD_LO 0x4D | ||
206 | #define CRT_ID_HWGC_DSTART_X 0x4E | ||
207 | #define CRT_ID_HWGC_DSTART_Y 0x4F | ||
208 | /* S3 extensions: System Extension Registers */ | ||
209 | #define CRT_ID_EXT_SYS_CNTL_1 0x50 /* NOT a virge register */ | ||
210 | #define CRT_ID_EXT_SYS_CNTL_2 0x51 | ||
211 | #define CRT_ID_EXT_BIOS_FLAG_1 0x52 | ||
212 | #define CRT_ID_EXT_MEM_CNTL_1 0x53 | ||
213 | #define CRT_ID_EXT_MEM_CNTL_2 0x54 | ||
214 | #define CRT_ID_EXT_DAC_CNTL 0x55 | ||
215 | #define CRT_ID_EX_SYNC_1 0x56 | ||
216 | #define CRT_ID_EX_SYNC_2 0x57 | ||
217 | #define CRT_ID_LAW_CNTL 0x58 /* LAW = Linear Address Window */ | ||
218 | #define CRT_ID_LAW_POS_HI 0x59 | ||
219 | #define CRT_ID_LAW_POS_LO 0x5A | ||
220 | #define CRT_ID_GOUT_PORT 0x5C | ||
221 | #define CRT_ID_EXT_HOR_OVF 0x5D | ||
222 | #define CRT_ID_EXT_VER_OVF 0x5E | ||
223 | #define CRT_ID_EXT_MEM_CNTL_3 0x60 /* NOT a virge register */ | ||
224 | #define CRT_ID_EXT_MEM_CNTL_4 0x61 | ||
225 | #define CRT_ID_EX_SYNC_3 0x63 /* NOT a virge register */ | ||
226 | #define CRT_ID_EXT_MISC_CNTL 0x65 | ||
227 | #define CRT_ID_EXT_MISC_CNTL_1 0x66 | ||
228 | #define CRT_ID_EXT_MISC_CNTL_2 0x67 | ||
229 | #define CRT_ID_CONFIG_3 0x68 | ||
230 | #define CRT_ID_EXT_SYS_CNTL_3 0x69 | ||
231 | #define CRT_ID_EXT_SYS_CNTL_4 0x6A | ||
232 | #define CRT_ID_EXT_BIOS_FLAG_3 0x6B | ||
233 | #define CRT_ID_EXT_BIOS_FLAG_4 0x6C | ||
234 | /* S3 virge extensions: more System Extension Registers */ | ||
235 | #define CRT_ID_EXT_BIOS_FLAG_5 0x6D | ||
236 | #define CRT_ID_EXT_DAC_TEST 0x6E | ||
237 | #define CRT_ID_CONFIG_4 0x6F | ||
238 | |||
239 | /* Video DAC */ | ||
240 | #define VDAC_ADDRESS 0x03c8 | ||
241 | #define VDAC_ADDRESS_W 0x03c8 | ||
242 | #define VDAC_ADDRESS_R 0x03c7 | ||
243 | #define VDAC_STATE 0x03c7 | ||
244 | #define VDAC_DATA 0x03c9 | ||
245 | #define VDAC_MASK 0x03c6 | ||
246 | |||
247 | /* Miscellaneous Registers */ | ||
248 | #define MR_SUBSYSTEM_STATUS_R 0x8504 /* new for virge */ | ||
249 | #define MR_SUBSYSTEM_CNTL_W 0x8504 /* new for virge */ | ||
250 | #define MR_ADVANCED_FUNCTION_CONTROL 0x850C /* new for virge */ | ||
251 | |||
252 | /* Blitter */ | ||
253 | #define BLT_COMMAND_SET 0xA500 | ||
254 | #define BLT_SIZE_X_Y 0xA504 | ||
255 | #define BLT_SRC_X_Y 0xA508 | ||
256 | #define BLT_DEST_X_Y 0xA50C | ||
257 | |||
258 | #define BLT_SRC_BASE 0xa4d4 | ||
259 | #define BLT_DEST_BASE 0xa4d8 | ||
260 | #define BLT_CLIP_LEFT_RIGHT 0xa4dc | ||
261 | #define BLT_CLIP_TOP_BOTTOM 0xa4e0 | ||
262 | #define BLT_SRC_DEST_STRIDE 0xa4e4 | ||
263 | #define BLT_MONO_PATTERN_0 0xa4e8 | ||
264 | #define BLT_MONO_PATTERN_1 0xa4ec | ||
265 | #define BLT_PATTERN_COLOR 0xa4f4 | ||
266 | |||
267 | #define L2D_COMMAND_SET 0xA900 | ||
268 | #define L2D_CLIP_LEFT_RIGHT 0xA8DC | ||
269 | #define L2D_CLIP_TOP_BOTTOM 0xA8E0 | ||
270 | |||
271 | #define P2D_COMMAND_SET 0xAD00 | ||
272 | #define P2D_CLIP_LEFT_RIGHT 0xACDC | ||
273 | #define P2D_CLIP_TOP_BOTTOM 0xACE0 | ||
274 | |||
275 | #define CMD_NOP (0xf << 27) /* %1111 << 27, was 0x07 */ | ||
276 | #define S3V_BITBLT (0x0 << 27) | ||
277 | #define S3V_RECTFILL (0x2 << 27) | ||
278 | #define S3V_AUTOEXE 0x01 | ||
279 | #define S3V_HWCLIP 0x02 | ||
280 | #define S3V_DRAW 0x20 | ||
281 | #define S3V_DST_8BPP 0x00 | ||
282 | #define S3V_DST_16BPP 0x04 | ||
283 | #define S3V_DST_24BPP 0x08 | ||
284 | #define S3V_MONO_PAT 0x100 | ||
285 | |||
286 | #define S3V_BLT_COPY (0xcc<<17) | ||
287 | #define S3V_BLT_CLEAR (0x00<<17) | ||
288 | #define S3V_BLT_SET (0xff<<17) | ||