aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/Kconfig46
-rw-r--r--drivers/video/Makefile4
-rw-r--r--drivers/video/cyberfb.c2295
-rw-r--r--drivers/video/cyberfb.h415
-rw-r--r--drivers/video/retz3fb.c1588
-rw-r--r--drivers/video/retz3fb.h286
-rw-r--r--drivers/video/sun3fb.c702
-rw-r--r--drivers/video/virgefb.c2526
-rw-r--r--drivers/video/virgefb.h288
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
357config 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
371config 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
385config 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
393config FB_FM2 357config 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
628config FB_SUN3
629 bool "Sun3 framebuffer support"
630 depends on (FB = y) && (SUN3 || SUN3X) && BROKEN
631
632config FB_SBUS 592config 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
638config FB_BW2 598config 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
647config FB_CG3 607config 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
656config FB_CG6 616config 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
22obj-$(CONFIG_FB_DDC) += fb_ddc.o 22obj-$(CONFIG_FB_DDC) += fb_ddc.o
23 23
24# Hardware specific drivers go first 24# Hardware specific drivers go first
25obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
26obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o 25obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o
27obj-$(CONFIG_FB_ARC) += arcfb.o 26obj-$(CONFIG_FB_ARC) += arcfb.o
28obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o 27obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
29obj-$(CONFIG_FB_CYBER) += cyberfb.o
30obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o 28obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
31obj-$(CONFIG_FB_PM2) += pm2fb.o 29obj-$(CONFIG_FB_PM2) += pm2fb.o
32obj-$(CONFIG_FB_PM3) += pm3fb.o 30obj-$(CONFIG_FB_PM3) += pm3fb.o
@@ -44,7 +42,6 @@ obj-$(CONFIG_FB_GEODE) += geode/
44obj-$(CONFIG_FB_MBX) += mbx/ 42obj-$(CONFIG_FB_MBX) += mbx/
45obj-$(CONFIG_FB_I810) += vgastate.o 43obj-$(CONFIG_FB_I810) += vgastate.o
46obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o 44obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
47obj-$(CONFIG_FB_VIRGE) += virgefb.o
48obj-$(CONFIG_FB_3DFX) += tdfxfb.o 45obj-$(CONFIG_FB_3DFX) += tdfxfb.o
49obj-$(CONFIG_FB_CONTROL) += controlfb.o 46obj-$(CONFIG_FB_CONTROL) += controlfb.o
50obj-$(CONFIG_FB_PLATINUM) += platinumfb.o 47obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
@@ -77,7 +74,6 @@ obj-$(CONFIG_FB_TGA) += tgafb.o
77obj-$(CONFIG_FB_HP300) += hpfb.o 74obj-$(CONFIG_FB_HP300) += hpfb.o
78obj-$(CONFIG_FB_G364) += g364fb.o 75obj-$(CONFIG_FB_G364) += g364fb.o
79obj-$(CONFIG_FB_SA1100) += sa1100fb.o 76obj-$(CONFIG_FB_SA1100) += sa1100fb.o
80obj-$(CONFIG_FB_SUN3) += sun3fb.o
81obj-$(CONFIG_FB_HIT) += hitfb.o 77obj-$(CONFIG_FB_HIT) += hitfb.o
82obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o 78obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o
83obj-$(CONFIG_FB_PVR2) += pvr2fb.o 79obj-$(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)
104static 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
112struct cyberfb_par {
113 struct fb_var_screeninfo var;
114 __u32 type;
115 __u32 type_aux;
116 __u32 visual;
117 __u32 line_length;
118};
119
120static struct cyberfb_par current_par;
121
122static int current_par_valid = 0;
123
124static struct display disp;
125static struct fb_info fb_info;
126
127
128/*
129 * Frame Buffer Name
130 */
131
132static char cyberfb_name[16] = "Cybervision";
133
134
135/*
136 * CyberVision Graphics Board
137 */
138
139static unsigned char Cyber_colour_table [256][3];
140static unsigned long CyberSize;
141static volatile unsigned char *CyberBase;
142static volatile unsigned char *CyberMem;
143static volatile unsigned char *CyberRegs;
144static unsigned long CyberMem_phys;
145static unsigned long CyberRegs_phys;
146
147/*
148 * Predefined Video Modes
149 */
150
151static 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
220static int Cyberfb_inverse = 0;
221
222/*
223 * Some default modes
224 */
225
226#define CYBER8_DEFMODE (0)
227#define CYBER16_DEFMODE (1)
228
229static struct fb_var_screeninfo cyberfb_default;
230static int cyberfb_usermode __initdata = 0;
231
232/*
233 * Interface used by the world
234 */
235
236int cyberfb_setup(char *options);
237
238static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
239 struct fb_info *info);
240static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
241 struct fb_info *info);
242static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
243 struct fb_info *info);
244static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
245 struct fb_info *info);
246static int cyberfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
247 u_int transp, struct fb_info *info);
248static int cyberfb_blank(int blank, struct fb_info *info);
249
250/*
251 * Interface to the low level console driver
252 */
253
254int cyberfb_init(void);
255static int Cyberfb_switch(int con, struct fb_info *info);
256static int Cyberfb_updatevar(int con, struct fb_info *info);
257
258/*
259 * Text console acceleration
260 */
261
262#ifdef FBCON_HAS_CFB8
263static struct display_switch fbcon_cyber8;
264#endif
265
266/*
267 * Accelerated Functions used by the low level console driver
268 */
269
270static void Cyber_WaitQueue(u_short fifo);
271static void Cyber_WaitBlit(void);
272static 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);
275static 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
278static void Cyber_MoveCursor(u_short x, u_short y);
279#endif
280
281/*
282 * Hardware Specific Routines
283 */
284
285static int Cyber_init(void);
286static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
287 struct cyberfb_par *par);
288static int Cyber_decode_var(struct fb_var_screeninfo *var,
289 struct cyberfb_par *par);
290static int Cyber_encode_var(struct fb_var_screeninfo *var,
291 struct cyberfb_par *par);
292static 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
299static void cyberfb_get_par(struct cyberfb_par *par);
300static void cyberfb_set_par(struct cyberfb_par *par);
301static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
302static void cyberfb_set_disp(int con, struct fb_info *info);
303static int get_video_mode(const char *name);
304
305/* For cvision_core.c */
306static unsigned short cv64_compute_clock(unsigned long);
307static int cv_has_4mb (volatile unsigned char *);
308static void cv64_board_init (void);
309static 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
322static 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
388static 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
424static 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
467static 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
513static 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
548static 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*/
576static 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 */
611static 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 */
625static 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 */
639static 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 */
684static 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 */
714static 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
742static 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
754static 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
763static 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
775static 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
800static 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
821static 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
841static 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
889static 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
928static 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
947static 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
958int __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
999int __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
1074static 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
1099static 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
1110static 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
1132static 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
1143static 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
1160static 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
1169static 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
1179static 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
1187static 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
1201MODULE_LICENSE("GPL");
1202
1203int 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
1220long cv64_memclk = 55000000;
1221#else
1222long cv64_memclk = 50000000;
1223#endif
1224
1225/*********************/
1226
1227static 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 */
1293unsigned 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 */
1316inline 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 */
1325inline 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 */
1333inline 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 */
1341inline 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
1352inline 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 */
1383inline 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 */
1399inline 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 */
1425static 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
1467static 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
1512static 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
1769static 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
2150DPRINTK("EXIT\n");
2151}
2152
2153void 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
2192void 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 */
2212static 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) \
372do { wb_64(ba, GCT_ADDRESS, idx); wb_64(ba, GCT_ADDRESS_W , val); } while (0)
373
374#define WSeq(ba, idx, val) \
375do { wb_64(ba, SEQ_ADDRESS, idx); wb_64(ba, SEQ_ADDRESS_W , val); } while (0)
376
377#define WCrt(ba, idx, val) \
378do { wb_64(ba, CRT_ADDRESS, idx); wb_64(ba, CRT_ADDRESS_W , val); } while (0)
379
380#define WAttr(ba, idx, val) \
381do { \
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) \
389do { \
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
398inline unsigned char RAttr(volatile unsigned char * board, short idx);
399inline unsigned char RSeq(volatile unsigned char * board, short idx);
400inline unsigned char RCrt(volatile unsigned char * board, short idx);
401inline unsigned char RGfx(volatile unsigned char * board, short idx);
402inline void cv64_write_port(unsigned short bits,
403 volatile unsigned char *board);
404inline void cvscreen(int toggle, volatile unsigned char *board);
405inline void gfx_on_off(int toggle, volatile unsigned char *board);
406#if 0
407unsigned short cv64_compute_clock(unsigned long freq);
408int cv_has_4mb(volatile unsigned char * fb);
409void cv64_board_init(void);
410void cv64_load_video_mode(struct fb_var_screeninfo *video_mode);
411#endif
412
413void cvision_bitblt(u_short sx, u_short sy, u_short dx, u_short dy, u_short w,
414 u_short h);
415void 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
58struct 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
84struct 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
99struct 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
115static 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
125static 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 *
132An 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
136The 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
1451) Pixelclock:
146 xfree: in MHz
147 fb: In Picoseconds (ps)
148
149 pixclock = 1000000 / DCF
150
1512) horizontal timings:
152 left_margin = HFL - SH2
153 right_margin = SH1 - HR
154 hsync_len = SH2 - SH1
155
1563) vertical timings:
157 upper_margin = VFL - SV2
158 lower_margin = SV1 - VR
159 vsync_len = SV2 - SV1
160
161Good examples for VESA timings can be found in the XFree86 source tree,
162under "programs/Xserver/hw/xfree86/doc/modeDB.txt".
163*/
164
165/*
166 * Predefined Video Modes
167 */
168
169static 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
254static struct fb_var_screeninfo retz3fb_default;
255
256static int z3fb_inverse = 0;
257static int z3fb_mode __initdata = 0;
258
259
260/*
261 * Interface used by the world
262 */
263
264int retz3fb_setup(char *options);
265
266static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
267 struct fb_info *info);
268static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,
269 struct fb_info *info);
270static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
271 struct fb_info *info);
272static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
273 struct fb_info *info);
274static int retz3fb_setcolreg(unsigned int regno, unsigned int red,
275 unsigned int green, unsigned int blue,
276 unsigned int transp, struct fb_info *info);
277static int retz3fb_blank(int blank, struct fb_info *info);
278
279
280/*
281 * Interface to the low level console driver
282 */
283
284int retz3fb_init(void);
285static int z3fb_switch(int con, struct fb_info *info);
286static int z3fb_updatevar(int con, struct fb_info *info);
287
288
289/*
290 * Text console acceleration
291 */
292
293#ifdef FBCON_HAS_CFB8
294static struct display_switch fbcon_retz3_8;
295#endif
296
297
298/*
299 * Accelerated Functions used by the low level console driver
300 */
301
302static 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
312static int retz3_encode_fix(struct fb_info *info,
313 struct fb_fix_screeninfo *fix,
314 struct retz3fb_par *par);
315static int retz3_decode_var(struct fb_var_screeninfo *var,
316 struct retz3fb_par *par);
317static int retz3_encode_var(struct fb_var_screeninfo *var,
318 struct retz3fb_par *par);
319static 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
327static void retz3fb_get_par(struct fb_info *info, struct retz3fb_par *par);
328static void retz3fb_set_par(struct fb_info *info, struct retz3fb_par *par);
329static int do_fb_set_var(struct fb_info *info,
330 struct fb_var_screeninfo *var, int isactive);
331static void retz3fb_set_disp(int con, struct fb_info *info);
332static int get_video_mode(const char *name);
333
334
335/* -------------------- Hardware specific routines ------------------------- */
336
337static 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
381static 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
775static 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
811static 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
848static 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
894static 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
928static 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
948static 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
963static 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 */
1043static 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
1054static 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
1065static 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
1074static 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
1101static 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
1119static 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
1134static 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
1189static 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
1273static 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
1290static 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
1313static 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
1324int __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
1350int __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
1442static 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
1464static int z3fb_updatevar(int con, struct fb_info *info)
1465{
1466 return 0;
1467}
1468
1469/*
1470 * Get a Video Mode
1471 */
1472
1473static 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
1487MODULE_LICENSE("GPL");
1488
1489int 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
1501static 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
1521static 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
1546static 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
1554static 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
1563static 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
1570static 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
1578static 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
73int sun3fb_init(void);
74void sun3fb_setup(char *options);
75
76static char fontname[40] __initdata = { 0 };
77static int curblink __initdata = 1;
78
79static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
80 struct fb_info *info);
81static int sun3fb_get_var(struct fb_var_screeninfo *var, int con,
82 struct fb_info *info);
83static int sun3fb_set_var(struct fb_var_screeninfo *var, int con,
84 struct fb_info *info);
85static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
86 struct fb_info *info);
87static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
88 struct fb_info *info);
89static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
90 u_int transp, struct fb_info *info);
91static int sun3fb_blank(int blank, struct fb_info *info);
92static void sun3fb_cursor(struct display *p, int mode, int x, int y);
93static void sun3fb_clear_margin(struct display *p, int s);
94
95 /*
96 * Interface to the low level console driver
97 */
98
99static int sun3fbcon_switch(int con, struct fb_info *info);
100static int sun3fbcon_updatevar(int con, struct fb_info *info);
101
102 /*
103 * Internal routines
104 */
105
106static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
107 u_int *transp, struct fb_info *info);
108
109static 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
120static 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
179static 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
192static 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
205static 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
218static 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
238static unsigned char hw_cursor_cmap[2] = { 0, 0xff };
239
240static void
241sun3fb_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
256static 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
301static 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
317static 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
344void __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
367static 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
402static int sun3fbcon_updatevar(int con, struct fb_info *info)
403{
404 /* Nothing */
405 return 0;
406}
407
408 /*
409 * Blank the display.
410 */
411
412static 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
428static 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
449static 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
465static 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
491void 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 */
516static 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;
544sizechange:
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
652int __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
702MODULE_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
66static 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
76static 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
216struct virgefb_par {
217 struct fb_var_screeninfo var;
218 __u32 type;
219 __u32 type_aux;
220 __u32 visual;
221 __u32 line_length;
222};
223
224static struct virgefb_par current_par;
225
226static int current_par_valid = 0;
227
228static struct display disp;
229static struct fb_info fb_info;
230
231static 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
244static 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
260static unsigned char blit_maybe_busy = 0;
261
262/*
263 * Frame Buffer Name
264 */
265
266static char virgefb_name[16] = "CyberVision/3D";
267
268/*
269 * CyberVision64/3d Graphics Board
270 */
271
272static unsigned char virgefb_colour_table [256][3];
273static unsigned long v_ram;
274static unsigned long v_ram_size;
275static volatile unsigned char *mmio_regs;
276static volatile unsigned char *vgaio_regs;
277
278static unsigned long v_ram_phys;
279static unsigned long mmio_regs_phys;
280static unsigned long vcode_switch_base;
281static 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
307static 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
636static struct fb_var_screeninfo virgefb_default;
637static int virgefb_inverse = 0;
638
639/*
640 * Interface used by the world
641 */
642
643int virgefb_setup(char*);
644static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con,
645 struct fb_info *info);
646static int virgefb_get_var(struct fb_var_screeninfo *var, int con,
647 struct fb_info *info);
648static int virgefb_set_var(struct fb_var_screeninfo *var, int con,
649 struct fb_info *info);
650static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
651 struct fb_info *info);
652static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
653 u_int transp, struct fb_info *info);
654static int virgefb_blank(int blank, struct fb_info *info);
655
656/*
657 * Interface to the low level console driver
658 */
659
660int virgefb_init(void);
661static int virgefb_switch(int con, struct fb_info *info);
662static int virgefb_updatevar(int con, struct fb_info *info);
663
664/*
665 * Text console acceleration
666 */
667
668#ifdef FBCON_HAS_CFB8
669static struct display_switch fbcon_virge8;
670#endif
671
672#ifdef FBCON_HAS_CFB16
673static struct display_switch fbcon_virge16;
674#endif
675
676#ifdef FBCON_HAS_CFB32
677static struct display_switch fbcon_virge32;
678#endif
679
680/*
681 * Hardware Specific Routines
682 */
683
684static int virge_init(void);
685static int virgefb_encode_fix(struct fb_fix_screeninfo *fix,
686 struct virgefb_par *par);
687static int virgefb_decode_var(struct fb_var_screeninfo *var,
688 struct virgefb_par *par);
689static int virgefb_encode_var(struct fb_var_screeninfo *var,
690 struct virgefb_par *par);
691static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
692 u_int *transp, struct fb_info *info);
693static void virgefb_gfx_on_off(int blank);
694static inline void virgefb_wait_for_idle(void);
695static 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);
697static 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
704static void virgefb_get_par(struct virgefb_par *par);
705static void virgefb_set_par(struct virgefb_par *par);
706static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
707static void virgefb_set_disp(int con, struct fb_info *info);
708static int virgefb_get_video_mode(const char *name);
709static void virgefb_set_video(struct fb_var_screeninfo *var);
710
711/*
712 * Additions for Initialization
713 */
714
715static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode);
716static int cv3d_has_4mb(void);
717static unsigned short virgefb_compute_clock(unsigned long freq);
718static inline unsigned char rattr(short);
719static inline unsigned char rseq(short);
720static inline unsigned char rcrt(short);
721static inline unsigned char rgfx(short);
722static inline void gfx_on_off(int toggle);
723static 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
733static 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
744static 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
752static 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
760static 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
773void 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
800static 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
957static 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
1019static 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
1083static 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
1124static 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
1177static 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
1207static 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
1219static 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
1226static 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
1236static 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
1296static 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
1339static 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
1348static 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
1365static 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
1377static 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
1386static 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/*
1408Merge these two functions, Geert's suggestion.
1409static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);
1410static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
1411*/
1412
1413static 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
1440static 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
1463static 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
1481static 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
1566static 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
1607static 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
1626static 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
1637int __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
1686static 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
1719int __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
1813out_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
1830static 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
1853static 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
1864static 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
1878static 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
1887static 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
1899static 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
1907static 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
1915static 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
1922static 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
1930static 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
1943static 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
1952static 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
1964static 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
1972static 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
1980static 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
1987static 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
1995static 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
2008static 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
2017static 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
2029static 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
2037static 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
2045static 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
2052static 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
2060static 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
2073MODULE_LICENSE("GPL");
2074
2075int init_module(void)
2076{
2077 return virgefb_init();
2078}
2079#endif /* MODULE */
2080
2081static 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
2145static 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
2178static 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
2418static 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
2437static 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)