blob: bc1cc44b1e3fc95ff7bfd729d216299cd8b79e90 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070084#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
112#define ww_64(regs,reg,dat) (*((volatile unsigned short *)(regs + reg) = dat)
113
114struct cyberfb_par {
115 struct fb_var_screeninfo var;
116 __u32 type;
117 __u32 type_aux;
118 __u32 visual;
119 __u32 line_length;
120};
121
122static struct cyberfb_par current_par;
123
124static int current_par_valid = 0;
125
126static struct display disp;
127static struct fb_info fb_info;
128
129
130/*
131 * Frame Buffer Name
132 */
133
134static char cyberfb_name[16] = "Cybervision";
135
136
137/*
138 * CyberVision Graphics Board
139 */
140
141static unsigned char Cyber_colour_table [256][3];
142static unsigned long CyberSize;
143static volatile unsigned char *CyberBase;
144static volatile unsigned char *CyberMem;
145static volatile unsigned char *CyberRegs;
146static unsigned long CyberMem_phys;
147static unsigned long CyberRegs_phys;
148
149/*
150 * Predefined Video Modes
151 */
152
153static struct {
154 const char *name;
155 struct fb_var_screeninfo var;
156} cyberfb_predefined[] __initdata = {
157 { "640x480-8", { /* Default 8 BPP mode (cyber8) */
158 640, 480, 640, 480, 0, 0, 8, 0,
159 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
160 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
161 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
162 FB_VMODE_NONINTERLACED
163 }},
164 { "640x480-16", { /* Default 16 BPP mode (cyber16) */
165 640, 480, 640, 480, 0, 0, 16, 0,
166 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
167 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
168 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
169 FB_VMODE_NONINTERLACED
170 }},
171 { "640x480-24", { /* Default 24 BPP mode */
172 640, 480, 640, 480, 0, 0, 24, 0,
173 {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0},
174 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
175 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
176 FB_VMODE_NONINTERLACED
177 }},
178 { "800x490-8", { /* Cybervision 8 bpp */
179 /* NO Acceleration */
180 800, 490, 800, 490, 0, 0, 8, 0,
181 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
182 0, 0, -1, -1, FB_ACCEL_NONE, 33333, 80, 24, 23, 1, 56, 8,
183 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
184 FB_VMODE_NONINTERLACED
185 }},
186/* I can't test these with my monitor, but I suspect they will
187 * be OK, since Antonio Santos indicated he had tested them in
188 * his system.
189 */
190 { "800x600-8", { /* Cybervision 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, 72, 2,
194 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
195 FB_VMODE_NONINTERLACED
196 }},
197 { "1024x768-8", { /* Cybervision 8 bpp */
198 1024, 768, 1024, 768, 0, 0, 8, 0,
199 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
200 0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 224, 72, 60, 12, 168, 4,
201 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
202 FB_VMODE_NONINTERLACED
203 }},
204 { "1152x886-8", { /* Cybervision 8 bpp */
205 1152, 886, 1152, 886, 0, 0, 8, 0,
206 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
207 0, 0, -1, -1, FB_ACCELF_TEXT, 15873, 184, 40, 24, 1, 56, 16,
208 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
209 FB_VMODE_NONINTERLACED
210 }},
211 { "1280x1024-8", { /* Cybervision 8 bpp */
212 1280, 1024, 1280, 1024, 0, 0, 8, 0,
213 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
214 0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 256, 48, 50, 12, 72, 4,
215 FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
216 FB_VMODE_INTERLACED
217 }}
218};
219
220#define NUM_TOTAL_MODES ARRAY_SIZE(cyberfb_predefined)
221
222static int Cyberfb_inverse = 0;
223
224/*
225 * Some default modes
226 */
227
228#define CYBER8_DEFMODE (0)
229#define CYBER16_DEFMODE (1)
230
231static struct fb_var_screeninfo cyberfb_default;
232static int cyberfb_usermode __initdata = 0;
233
234/*
235 * Interface used by the world
236 */
237
238int cyberfb_setup(char *options);
239
240static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
241 struct fb_info *info);
242static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
243 struct fb_info *info);
244static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
245 struct fb_info *info);
246static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
247 struct fb_info *info);
248static int cyberfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
249 u_int transp, struct fb_info *info);
250static int cyberfb_blank(int blank, struct fb_info *info);
251
252/*
253 * Interface to the low level console driver
254 */
255
256int cyberfb_init(void);
257static int Cyberfb_switch(int con, struct fb_info *info);
258static int Cyberfb_updatevar(int con, struct fb_info *info);
259
260/*
261 * Text console acceleration
262 */
263
264#ifdef FBCON_HAS_CFB8
265static struct display_switch fbcon_cyber8;
266#endif
267
268/*
269 * Accelerated Functions used by the low level console driver
270 */
271
272static void Cyber_WaitQueue(u_short fifo);
273static void Cyber_WaitBlit(void);
274static void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
275 u_short desty, u_short width, u_short height,
276 u_short mode);
277static void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
278 u_short mode, u_short color);
279#if 0
280static void Cyber_MoveCursor(u_short x, u_short y);
281#endif
282
283/*
284 * Hardware Specific Routines
285 */
286
287static int Cyber_init(void);
288static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
289 struct cyberfb_par *par);
290static int Cyber_decode_var(struct fb_var_screeninfo *var,
291 struct cyberfb_par *par);
292static int Cyber_encode_var(struct fb_var_screeninfo *var,
293 struct cyberfb_par *par);
294static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
295 u_int *transp, struct fb_info *info);
296
297/*
298 * Internal routines
299 */
300
301static void cyberfb_get_par(struct cyberfb_par *par);
302static void cyberfb_set_par(struct cyberfb_par *par);
303static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
304static void cyberfb_set_disp(int con, struct fb_info *info);
305static int get_video_mode(const char *name);
306
307/* For cvision_core.c */
308static unsigned short cv64_compute_clock(unsigned long);
309static int cv_has_4mb (volatile unsigned char *);
310static void cv64_board_init (void);
311static void cv64_load_video_mode (struct fb_var_screeninfo *);
312
313
314/* -------------------- Hardware specific routines ------------------------- */
315
316
317/*
318 * Initialization
319 *
320 * Set the default video mode for this chipset. If a video mode was
321 * specified on the command line, it will override the default mode.
322 */
323
324static int Cyber_init(void)
325{
326 volatile unsigned char *regs = CyberRegs;
327 volatile unsigned long *CursorBase;
328 int i;
329 DPRINTK("ENTER\n");
330
331/* Init local cmap as greyscale levels */
332 for (i = 0; i < 256; i++) {
333 Cyber_colour_table [i][0] = i;
334 Cyber_colour_table [i][1] = i;
335 Cyber_colour_table [i][2] = i;
336 }
337
338/* Initialize the board and determine fbmem size */
339 cv64_board_init();
340#ifdef CYBERFBDEBUG
341 DPRINTK("Register state after initing board\n");
342 cv64_dump();
343#endif
344/* Clear framebuffer memory */
345 DPRINTK("Clear framebuffer memory\n");
346 memset ((char *)CyberMem, 0, CyberSize);
347
348/* Disable hardware cursor */
349 DPRINTK("Disable HW cursor\n");
350 wb_64(regs, S3_CRTC_ADR, S3_REG_LOCK2);
351 wb_64(regs, S3_CRTC_DATA, 0xa0);
352 wb_64(regs, S3_CRTC_ADR, S3_HGC_MODE);
353 wb_64(regs, S3_CRTC_DATA, 0x00);
354 wb_64(regs, S3_CRTC_ADR, S3_HWGC_DX);
355 wb_64(regs, S3_CRTC_DATA, 0x00);
356 wb_64(regs, S3_CRTC_ADR, S3_HWGC_DY);
357 wb_64(regs, S3_CRTC_DATA, 0x00);
358
359/* Initialize hardware cursor */
360 DPRINTK("Init HW cursor\n");
361 CursorBase = (u_long *)((char *)(CyberMem) + CyberSize - 0x400);
362 for (i=0; i < 8; i++)
363 {
364 *(CursorBase +(i*4)) = 0xffffff00;
365 *(CursorBase+1+(i*4)) = 0xffff0000;
366 *(CursorBase+2+(i*4)) = 0xffff0000;
367 *(CursorBase+3+(i*4)) = 0xffff0000;
368 }
369 for (i=8; i < 64; i++)
370 {
371 *(CursorBase +(i*4)) = 0xffff0000;
372 *(CursorBase+1+(i*4)) = 0xffff0000;
373 *(CursorBase+2+(i*4)) = 0xffff0000;
374 *(CursorBase+3+(i*4)) = 0xffff0000;
375 }
376
377 cyberfb_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, NULL /* unused */);
378 cyberfb_setcolreg (254, 0, 0, 0, 0, NULL /* unused */);
379
380 DPRINTK("EXIT\n");
381 return 0;
382}
383
384
385/*
386 * This function should fill in the `fix' structure based on the
387 * values in the `par' structure.
388 */
389
390static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
391 struct cyberfb_par *par)
392{
393 DPRINTK("ENTER\n");
394 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
395 strcpy(fix->id, cyberfb_name);
396 fix->smem_start = CyberMem_phys;
397 fix->smem_len = CyberSize;
398 fix->mmio_start = CyberRegs_phys;
399 fix->mmio_len = 0x10000;
400
401 fix->type = FB_TYPE_PACKED_PIXELS;
402 fix->type_aux = 0;
403 if (par->var.bits_per_pixel == 15 || par->var.bits_per_pixel == 16 ||
404 par->var.bits_per_pixel == 24 || par->var.bits_per_pixel == 32) {
405 fix->visual = FB_VISUAL_DIRECTCOLOR;
406 } else {
407 fix->visual = FB_VISUAL_PSEUDOCOLOR;
408 }
409
410 fix->xpanstep = 0;
411 fix->ypanstep = 0;
412 fix->ywrapstep = 0;
413 fix->line_length = 0;
414 fix->accel = FB_ACCEL_S3_TRIO64;
415
416 DPRINTK("EXIT\n");
417 return(0);
418}
419
420
421/*
422* Fill the `par' structure based on the values in `var'.
423* TODO: Verify and adjust values, return -EINVAL if bad.
424*/
425
426static int Cyber_decode_var(struct fb_var_screeninfo *var,
427 struct cyberfb_par *par)
428{
429 DPRINTK("ENTER\n");
430 par->var.xres = var->xres;
431 par->var.yres = var->yres;
432 par->var.xres_virtual = var->xres_virtual;
433 par->var.yres_virtual = var->yres_virtual;
434 par->var.xoffset = var->xoffset;
435 par->var.yoffset = var->yoffset;
436 par->var.bits_per_pixel = var->bits_per_pixel;
437 par->var.grayscale = var->grayscale;
438 par->var.red = var->red;
439 par->var.green = var->green;
440 par->var.blue = var->blue;
441 par->var.transp = var->transp;
442 par->var.nonstd = var->nonstd;
443 par->var.activate = var->activate;
444 par->var.height = var->height;
445 par->var.width = var->width;
446 if (var->accel_flags & FB_ACCELF_TEXT) {
447 par->var.accel_flags = FB_ACCELF_TEXT;
448 } else {
449 par->var.accel_flags = 0;
450 }
451 par->var.pixclock = var->pixclock;
452 par->var.left_margin = var->left_margin;
453 par->var.right_margin = var->right_margin;
454 par->var.upper_margin = var->upper_margin;
455 par->var.lower_margin = var->lower_margin;
456 par->var.hsync_len = var->hsync_len;
457 par->var.vsync_len = var->vsync_len;
458 par->var.sync = var->sync;
459 par->var.vmode = var->vmode;
460 DPRINTK("EXIT\n");
461 return(0);
462}
463
464/*
465* Fill the `var' structure based on the values in `par' and maybe
466* other values read out of the hardware.
467*/
468
469static int Cyber_encode_var(struct fb_var_screeninfo *var,
470 struct cyberfb_par *par)
471{
472 DPRINTK("ENTER\n");
473 var->xres = par->var.xres;
474 var->yres = par->var.yres;
475 var->xres_virtual = par->var.xres_virtual;
476 var->yres_virtual = par->var.yres_virtual;
477 var->xoffset = par->var.xoffset;
478 var->yoffset = par->var.yoffset;
479
480 var->bits_per_pixel = par->var.bits_per_pixel;
481 var->grayscale = par->var.grayscale;
482
483 var->red = par->var.red;
484 var->green = par->var.green;
485 var->blue = par->var.blue;
486 var->transp = par->var.transp;
487
488 var->nonstd = par->var.nonstd;
489 var->activate = par->var.activate;
490
491 var->height = par->var.height;
492 var->width = par->var.width;
493
494 var->accel_flags = par->var.accel_flags;
495
496 var->pixclock = par->var.pixclock;
497 var->left_margin = par->var.left_margin;
498 var->right_margin = par->var.right_margin;
499 var->upper_margin = par->var.upper_margin;
500 var->lower_margin = par->var.lower_margin;
501 var->hsync_len = par->var.hsync_len;
502 var->vsync_len = par->var.vsync_len;
503 var->sync = par->var.sync;
504 var->vmode = par->var.vmode;
505
506 DPRINTK("EXIT\n");
507 return(0);
508}
509
510
511/*
512 * Set a single color register. Return != 0 for invalid regno.
513 */
514
515static int cyberfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
516 u_int transp, struct fb_info *info)
517{
518 volatile unsigned char *regs = CyberRegs;
519
520 /*DPRINTK("ENTER\n");*/
521 if (regno > 255) {
522 DPRINTK("EXIT - Register # > 255\n");
523 return (1);
524 }
525
526 wb_64(regs, 0x3c8, (unsigned char) regno);
527
528 red >>= 10;
529 green >>= 10;
530 blue >>= 10;
531
532 Cyber_colour_table [regno][0] = red;
533 Cyber_colour_table [regno][1] = green;
534 Cyber_colour_table [regno][2] = blue;
535
536 wb_64(regs, 0x3c9, red);
537 wb_64(regs, 0x3c9, green);
538 wb_64(regs, 0x3c9, blue);
539
540 /*DPRINTK("EXIT\n");*/
541 return (0);
542}
543
544
545/*
546* Read a single color register and split it into
547* colors/transparent. Return != 0 for invalid regno.
548*/
549
550static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
551 u_int *transp, struct fb_info *info)
552{
553 int t;
554
555 /*DPRINTK("ENTER\n");*/
556 if (regno > 255) {
557 DPRINTK("EXIT - Register # > 255\n");
558 return (1);
559 }
560 /* ARB This shifting & oring seems VERY strange */
561 t = Cyber_colour_table [regno][0];
562 *red = (t<<10) | (t<<4) | (t>>2);
563 t = Cyber_colour_table [regno][1];
564 *green = (t<<10) | (t<<4) | (t>>2);
565 t = Cyber_colour_table [regno][2];
566 *blue = (t<<10) | (t<<4) | (t>>2);
567 *transp = 0;
568 /*DPRINTK("EXIT\n");*/
569 return (0);
570}
571
572
573/*
574* (Un)Blank the screen
575* blank: 1 = zero fb cmap
576* 0 = restore fb cmap from local cmap
577*/
578static int cyberfb_blank(int blank, struct fb_info *info)
579{
580 volatile unsigned char *regs = CyberRegs;
581 int i;
582
583 DPRINTK("ENTER\n");
584#if 0
585/* Blank by turning gfx off */
586 gfx_on_off (1, regs);
587#else
588 if (blank) {
589 for (i = 0; i < 256; i++) {
590 wb_64(regs, 0x3c8, (unsigned char) i);
591 /* ARB Pale red to detect this blanking method */
592 wb_64(regs, 0x3c9, 48);
593 wb_64(regs, 0x3c9, 0);
594 wb_64(regs, 0x3c9, 0);
595 }
596 } else {
597 for (i = 0; i < 256; i++) {
598 wb_64(regs, 0x3c8, (unsigned char) i);
599 wb_64(regs, 0x3c9, Cyber_colour_table[i][0]);
600 wb_64(regs, 0x3c9, Cyber_colour_table[i][1]);
601 wb_64(regs, 0x3c9, Cyber_colour_table[i][2]);
602 }
603 }
604#endif
605 DPRINTK("EXIT\n");
606 return 0;
607}
608
609
610/**************************************************************
611 * We are waiting for "fifo" FIFO-slots empty
612 */
613static void Cyber_WaitQueue (u_short fifo)
614{
615 unsigned short status;
616
617 DPRINTK("ENTER\n");
618 do {
619 status = *((u_short volatile *)(CyberRegs + S3_GP_STAT));
620 } while (status & fifo);
621 DPRINTK("EXIT\n");
622}
623
624/**************************************************************
625 * We are waiting for Hardware (Graphics Engine) not busy
626 */
627static void Cyber_WaitBlit (void)
628{
629 unsigned short status;
630
631 DPRINTK("ENTER\n");
632 do {
633 status = *((u_short volatile *)(CyberRegs + S3_GP_STAT));
634 } while (status & S3_HDW_BUSY);
635 DPRINTK("EXIT\n");
636}
637
638/**************************************************************
639 * BitBLT - Through the Plane
640 */
641static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx,
642 u_short desty, u_short width, u_short height,
643 u_short mode)
644{
645 volatile unsigned char *regs = CyberRegs;
646 u_short blitcmd = S3_BITBLT;
647
648 DPRINTK("ENTER\n");
649 /* Set drawing direction */
650 /* -Y, X maj, -X (default) */
651 if (curx > destx) {
652 blitcmd |= 0x0020; /* Drawing direction +X */
653 } else {
654 curx += (width - 1);
655 destx += (width - 1);
656 }
657
658 if (cury > desty) {
659 blitcmd |= 0x0080; /* Drawing direction +Y */
660 } else {
661 cury += (height - 1);
662 desty += (height - 1);
663 }
664
665 Cyber_WaitQueue (0x8000);
666
667 *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000;
668 *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0060 | mode);
669
670 *((u_short volatile *)(regs + S3_CUR_X)) = curx;
671 *((u_short volatile *)(regs + S3_CUR_Y)) = cury;
672
673 *((u_short volatile *)(regs + S3_DESTX_DIASTP)) = destx;
674 *((u_short volatile *)(regs + S3_DESTY_AXSTP)) = desty;
675
676 *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1;
677 *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1;
678
679 *((u_short volatile *)(regs + S3_CMD)) = blitcmd;
680 DPRINTK("EXIT\n");
681}
682
683/**************************************************************
684 * Rectangle Fill Solid
685 */
686static void Cyber_RectFill (u_short x, u_short y, u_short width,
687 u_short height, u_short mode, u_short color)
688{
689 volatile unsigned char *regs = CyberRegs;
690 u_short blitcmd = S3_FILLEDRECT;
691
692 DPRINTK("ENTER\n");
693 Cyber_WaitQueue (0x8000);
694
695 *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000;
696 *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0020 | mode);
697
698 *((u_short volatile *)(regs + S3_MULT_MISC)) = 0xe000;
699 *((u_short volatile *)(regs + S3_FRGD_COLOR)) = color;
700
701 *((u_short volatile *)(regs + S3_CUR_X)) = x;
702 *((u_short volatile *)(regs + S3_CUR_Y)) = y;
703
704 *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1;
705 *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1;
706
707 *((u_short volatile *)(regs + S3_CMD)) = blitcmd;
708 DPRINTK("EXIT\n");
709}
710
711
712#if 0
713/**************************************************************
714 * Move cursor to x, y
715 */
716static void Cyber_MoveCursor (u_short x, u_short y)
717{
718 volatile unsigned char *regs = CyberRegs;
719 DPRINTK("ENTER\n");
720 *(regs + S3_CRTC_ADR) = 0x39;
721 *(regs + S3_CRTC_DATA) = 0xa0;
722
723 *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H;
724 *(regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
725 *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L;
726 *(regs + S3_CRTC_DATA) = (char)(x & 0x00ff);
727
728 *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H;
729 *(regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
730 *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L;
731 *(regs + S3_CRTC_DATA) = (char)(y & 0x00ff);
732 DPRINTK("EXIT\n");
733}
734#endif
735
736
737/* -------------------- Generic routines ---------------------------------- */
738
739
740/*
741 * Fill the hardware's `par' structure.
742 */
743
744static void cyberfb_get_par(struct cyberfb_par *par)
745{
746 DPRINTK("ENTER\n");
747 if (current_par_valid) {
748 *par = current_par;
749 } else {
750 Cyber_decode_var(&cyberfb_default, par);
751 }
752 DPRINTK("EXIT\n");
753}
754
755
756static void cyberfb_set_par(struct cyberfb_par *par)
757{
758 DPRINTK("ENTER\n");
759 current_par = *par;
760 current_par_valid = 1;
761 DPRINTK("EXIT\n");
762}
763
764
765static void cyber_set_video(struct fb_var_screeninfo *var)
766{
767
768 /* Load the video mode defined by the 'var' data */
769 cv64_load_video_mode (var);
770#ifdef CYBERFBDEBUG
771 DPRINTK("Register state after loading video mode\n");
772 cv64_dump();
773#endif
774}
775
776
777static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
778{
779 int err, activate;
780 struct cyberfb_par par;
781
782 DPRINTK("ENTER\n");
783 if ((err = Cyber_decode_var(var, &par))) {
784 DPRINTK("EXIT - decode_var failed\n");
785 return(err);
786 }
787 activate = var->activate;
788 if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
789 cyberfb_set_par(&par);
790 Cyber_encode_var(var, &par);
791 var->activate = activate;
792
793 cyber_set_video(var);
794 DPRINTK("EXIT\n");
795 return 0;
796}
797
798/*
799 * Get the Fixed Part of the Display
800 */
801
802static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
803 struct fb_info *info)
804{
805 struct cyberfb_par par;
806 int error = 0;
807
808 DPRINTK("ENTER\n");
809 if (con == -1) {
810 cyberfb_get_par(&par);
811 } else {
812 error = Cyber_decode_var(&fb_display[con].var, &par);
813 }
814 DPRINTK("EXIT\n");
815 return(error ? error : Cyber_encode_fix(fix, &par));
816}
817
818
819/*
820 * Get the User Defined Part of the Display
821 */
822
823static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
824 struct fb_info *info)
825{
826 struct cyberfb_par par;
827 int error = 0;
828
829 DPRINTK("ENTER\n");
830 if (con == -1) {
831 cyberfb_get_par(&par);
832 error = Cyber_encode_var(var, &par);
833 disp.var = *var; /* ++Andre: don't know if this is the right place */
834 } else {
835 *var = fb_display[con].var;
836 }
837
838 DPRINTK("EXIT\n");
839 return(error);
840}
841
842
843static void cyberfb_set_disp(int con, struct fb_info *info)
844{
845 struct fb_fix_screeninfo fix;
846 struct display *display;
847
848 DPRINTK("ENTER\n");
849 if (con >= 0)
850 display = &fb_display[con];
851 else
852 display = &disp; /* used during initialization */
853
854 cyberfb_get_fix(&fix, con, info);
855 if (con == -1)
856 con = 0;
857 display->visual = fix.visual;
858 display->type = fix.type;
859 display->type_aux = fix.type_aux;
860 display->ypanstep = fix.ypanstep;
861 display->ywrapstep = fix.ywrapstep;
862 display->can_soft_blank = 1;
863 display->inverse = Cyberfb_inverse;
864 switch (display->var.bits_per_pixel) {
865#ifdef FBCON_HAS_CFB8
866 case 8:
867 if (display->var.accel_flags & FB_ACCELF_TEXT) {
868 display->dispsw = &fbcon_cyber8;
869#warning FIXME: We should reinit the graphics engine here
870 } else
871 display->dispsw = &fbcon_cfb8;
872 break;
873#endif
874#ifdef FBCON_HAS_CFB16
875 case 16:
876 display->dispsw = &fbcon_cfb16;
877 break;
878#endif
879 default:
880 display->dispsw = NULL;
881 break;
882 }
883 DPRINTK("EXIT\n");
884}
885
886
887/*
888 * Set the User Defined Part of the Display
889 */
890
891static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
892 struct fb_info *info)
893{
894 int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
895
896 DPRINTK("ENTER\n");
897 if ((err = do_fb_set_var(var, con == info->currcon))) {
898 DPRINTK("EXIT - do_fb_set_var failed\n");
899 return(err);
900 }
901 if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
902 oldxres = fb_display[con].var.xres;
903 oldyres = fb_display[con].var.yres;
904 oldvxres = fb_display[con].var.xres_virtual;
905 oldvyres = fb_display[con].var.yres_virtual;
906 oldbpp = fb_display[con].var.bits_per_pixel;
907 oldaccel = fb_display[con].var.accel_flags;
908 fb_display[con].var = *var;
909 if (oldxres != var->xres || oldyres != var->yres ||
910 oldvxres != var->xres_virtual ||
911 oldvyres != var->yres_virtual ||
912 oldbpp != var->bits_per_pixel ||
913 oldaccel != var->accel_flags) {
914 cyberfb_set_disp(con, info);
915 (*fb_info.changevar)(con);
916 fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
917 do_install_cmap(con, info);
918 }
919 }
920 var->activate = 0;
921 DPRINTK("EXIT\n");
922 return(0);
923}
924
925
926/*
927 * Get the Colormap
928 */
929
930static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
931 struct fb_info *info)
932{
933 DPRINTK("ENTER\n");
934 if (con == info->currcon) { /* current console? */
935 DPRINTK("EXIT - console is current console\n");
936 return(fb_get_cmap(cmap, kspc, Cyber_getcolreg, info));
937 } else if (fb_display[con].cmap.len) { /* non default colormap? */
938 DPRINTK("Use console cmap\n");
939 fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
940 } else {
941 DPRINTK("Use default cmap\n");
942 fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
943 cmap, kspc ? 0 : 2);
944 }
945 DPRINTK("EXIT\n");
946 return(0);
947}
948
949static struct fb_ops cyberfb_ops = {
950 .owner = THIS_MODULE,
951 .fb_get_fix = cyberfb_get_fix,
952 .fb_get_var = cyberfb_get_var,
953 .fb_set_var = cyberfb_set_var,
954 .fb_get_cmap = cyberfb_get_cmap,
955 .fb_set_cmap = gen_set_cmap,
956 .fb_setcolreg = cyberfb_setcolreg,
957 .fb_blank = cyberfb_blank,
958};
959
960int __init cyberfb_setup(char *options)
961{
962 char *this_opt;
963 DPRINTK("ENTER\n");
964
965 fb_info.fontname[0] = '\0';
966
967 if (!options || !*options) {
968 DPRINTK("EXIT - no options\n");
969 return 0;
970 }
971
972 while ((this_opt = strsep(&options, ",")) != NULL) {
973 if (!*this_opt)
974 continue;
975 if (!strcmp(this_opt, "inverse")) {
976 Cyberfb_inverse = 1;
977 fb_invert_cmaps();
978 } else if (!strncmp(this_opt, "font:", 5)) {
979 strcpy(fb_info.fontname, this_opt+5);
980 } else if (!strcmp (this_opt, "cyber8")) {
981 cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
982 cyberfb_usermode = 1;
983 } else if (!strcmp (this_opt, "cyber16")) {
984 cyberfb_default = cyberfb_predefined[CYBER16_DEFMODE].var;
985 cyberfb_usermode = 1;
986 } else get_video_mode(this_opt);
987 }
988
989 DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n",
990 cyberfb_default.xres,
991 cyberfb_default.yres,
992 cyberfb_default.bits_per_pixel);
993 DPRINTK("EXIT\n");
994 return 0;
995}
996
997/*
998 * Initialization
999 */
1000
1001int __init cyberfb_init(void)
1002{
1003 unsigned long board_addr, board_size;
1004 struct cyberfb_par par;
1005 struct zorro_dev *z = NULL;
1006 DPRINTK("ENTER\n");
1007
1008 while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64, z))) {
1009 board_addr = z->resource.start;
1010 board_size = z->resource.end-z->resource.start+1;
1011 CyberMem_phys = board_addr + 0x01400000;
1012 CyberRegs_phys = CyberMem_phys + 0x00c00000;
1013 if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 Trio64"))
1014 continue;
1015 if (!request_mem_region(CyberMem_phys, 0x400000, "RAM")) {
1016 release_mem_region(CyberRegs_phys, 0x10000);
1017 continue;
1018 }
1019 DPRINTK("board_addr=%08lx\n", board_addr);
1020 DPRINTK("board_size=%08lx\n", board_size);
1021
1022 CyberBase = ioremap(board_addr, board_size);
1023 CyberRegs = CyberBase + 0x02000000;
1024 CyberMem = CyberBase + 0x01400000;
1025 DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n",
1026 CyberBase, (long unsigned int)CyberRegs, CyberMem);
1027
1028#ifdef CYBERFBDEBUG
1029 DPRINTK("Register state just after mapping memory\n");
1030 cv64_dump();
1031#endif
1032
1033 strcpy(fb_info.modename, cyberfb_name);
1034 fb_info.changevar = NULL;
1035 fb_info.fbops = &cyberfb_ops;
1036 fb_info.screen_base = (unsigned char *)CyberMem;
1037 fb_info.disp = &disp;
1038 fb_info.currcon = -1;
1039 fb_info.switch_con = &Cyberfb_switch;
1040 fb_info.updatevar = &Cyberfb_updatevar;
1041
1042 Cyber_init();
1043 /* ++Andre: set cyberfb default mode */
1044 if (!cyberfb_usermode) {
1045 cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
1046 DPRINTK("Use default cyber8 mode\n");
1047 }
1048 Cyber_decode_var(&cyberfb_default, &par);
1049 Cyber_encode_var(&cyberfb_default, &par);
1050
1051 do_fb_set_var(&cyberfb_default, 1);
1052 cyberfb_get_var(&fb_display[0].var, -1, &fb_info);
1053 cyberfb_set_disp(-1, &fb_info);
1054 do_install_cmap(0, &fb_info);
1055
1056 if (register_framebuffer(&fb_info) < 0) {
1057 DPRINTK("EXIT - register_framebuffer failed\n");
Amol Ladd02abed2006-12-08 02:40:12 -08001058 if (CyberBase)
1059 iounmap(CyberBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 release_mem_region(CyberMem_phys, 0x400000);
1061 release_mem_region(CyberRegs_phys, 0x10000);
1062 return -EINVAL;
1063 }
1064
1065 printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
1066 fb_info.node, fb_info.modename, CyberSize>>10);
1067
1068 /* TODO: This driver cannot be unloaded yet */
1069 DPRINTK("EXIT\n");
1070 return 0;
1071 }
1072 return -ENXIO;
1073}
1074
1075
1076static int Cyberfb_switch(int con, struct fb_info *info)
1077{
1078 DPRINTK("ENTER\n");
1079 /* Do we have to save the colormap? */
1080 if (fb_display[info->currcon].cmap.len) {
1081 fb_get_cmap(&fb_display[info->currcon].cmap, 1, Cyber_getcolreg,
1082 info);
1083 }
1084
1085 do_fb_set_var(&fb_display[con].var, 1);
1086 info->currcon = con;
1087 /* Install new colormap */
1088 do_install_cmap(con, info);
1089 DPRINTK("EXIT\n");
1090 return(0);
1091}
1092
1093
1094/*
1095 * Update the `var' structure (called by fbcon.c)
1096 *
1097 * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
1098 * Since it's called by a kernel driver, no range checking is done.
1099 */
1100
1101static int Cyberfb_updatevar(int con, struct fb_info *info)
1102{
1103 DPRINTK("Enter - Exit\n");
1104 return(0);
1105}
1106
1107
1108/*
1109 * Get a Video Mode
1110 */
1111
1112static int __init get_video_mode(const char *name)
1113{
1114 int i;
1115
1116 DPRINTK("ENTER\n");
1117 for (i = 0; i < NUM_TOTAL_MODES; i++) {
1118 if (!strcmp(name, cyberfb_predefined[i].name)) {
1119 cyberfb_default = cyberfb_predefined[i].var;
1120 cyberfb_usermode = 1;
1121 DPRINTK("EXIT - Matched predefined mode\n");
1122 return(i);
1123 }
1124 }
1125 return(0);
1126}
1127
1128
1129/*
1130 * Text console acceleration
1131 */
1132
1133#ifdef FBCON_HAS_CFB8
1134static void fbcon_cyber8_bmove(struct display *p, int sy, int sx, int dy,
1135 int dx, int height, int width)
1136{
1137 DPRINTK("ENTER\n");
1138 sx *= 8; dx *= 8; width *= 8;
1139 Cyber_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
1140 (u_short)(dy*fontheight(p)), (u_short)width,
1141 (u_short)(height*fontheight(p)), (u_short)S3_NEW);
1142 DPRINTK("EXIT\n");
1143}
1144
1145static void fbcon_cyber8_clear(struct vc_data *conp, struct display *p, int sy,
1146 int sx, int height, int width)
1147{
1148 unsigned char bg;
1149
1150 DPRINTK("ENTER\n");
1151 sx *= 8; width *= 8;
1152 bg = attr_bgcol_ec(p,conp);
1153 Cyber_RectFill((u_short)sx,
1154 (u_short)(sy*fontheight(p)),
1155 (u_short)width,
1156 (u_short)(height*fontheight(p)),
1157 (u_short)S3_NEW,
1158 (u_short)bg);
1159 DPRINTK("EXIT\n");
1160}
1161
1162static void fbcon_cyber8_putc(struct vc_data *conp, struct display *p, int c,
1163 int yy, int xx)
1164{
1165 DPRINTK("ENTER\n");
1166 Cyber_WaitBlit();
1167 fbcon_cfb8_putc(conp, p, c, yy, xx);
1168 DPRINTK("EXIT\n");
1169}
1170
1171static void fbcon_cyber8_putcs(struct vc_data *conp, struct display *p,
1172 const unsigned short *s, int count,
1173 int yy, int xx)
1174{
1175 DPRINTK("ENTER\n");
1176 Cyber_WaitBlit();
1177 fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
1178 DPRINTK("EXIT\n");
1179}
1180
1181static void fbcon_cyber8_revc(struct display *p, int xx, int yy)
1182{
1183 DPRINTK("ENTER\n");
1184 Cyber_WaitBlit();
1185 fbcon_cfb8_revc(p, xx, yy);
1186 DPRINTK("EXIT\n");
1187}
1188
1189static struct display_switch fbcon_cyber8 = {
1190 .setup = fbcon_cfb8_setup,
1191 .bmove = fbcon_cyber8_bmove,
1192 .clear = fbcon_cyber8_clear,
1193 .putc = fbcon_cyber8_putc,
1194 .putcs = fbcon_cyber8_putcs,
1195 .revc = fbcon_cyber8_revc,
1196 .clear_margins =fbcon_cfb8_clear_margins,
1197 .fontwidthmask =FONTWIDTH(8)
1198};
1199#endif
1200
1201
1202#ifdef MODULE
1203MODULE_LICENSE("GPL");
1204
1205int init_module(void)
1206{
1207 return cyberfb_init();
1208}
1209#endif /* MODULE */
1210
1211/*
1212 *
1213 * Low level initialization routines for the CyberVision64 graphics card
1214 *
1215 * Most of the following code is from cvision_core.c
1216 *
1217 */
1218
1219#define MAXPIXELCLOCK 135000000 /* safety */
1220
1221#ifdef CV_AGGRESSIVE_TIMING
1222long cv64_memclk = 55000000;
1223#else
1224long cv64_memclk = 50000000;
1225#endif
1226
1227/*********************/
1228
1229static unsigned char clocks[]={
1230 0x13, 0x61, 0x6b, 0x6d, 0x51, 0x69, 0x54, 0x69,
1231 0x4f, 0x68, 0x6b, 0x6b, 0x18, 0x61, 0x7b, 0x6c,
1232 0x51, 0x67, 0x24, 0x62, 0x56, 0x67, 0x77, 0x6a,
1233 0x1d, 0x61, 0x53, 0x66, 0x6b, 0x68, 0x79, 0x69,
1234 0x7c, 0x69, 0x7f, 0x69, 0x22, 0x61, 0x54, 0x65,
1235 0x56, 0x65, 0x58, 0x65, 0x67, 0x66, 0x41, 0x63,
1236 0x27, 0x61, 0x13, 0x41, 0x37, 0x62, 0x6b, 0x4d,
1237 0x23, 0x43, 0x51, 0x49, 0x79, 0x66, 0x54, 0x49,
1238 0x7d, 0x66, 0x34, 0x56, 0x4f, 0x63, 0x1f, 0x42,
1239 0x6b, 0x4b, 0x7e, 0x4d, 0x18, 0x41, 0x2a, 0x43,
1240 0x7b, 0x4c, 0x74, 0x4b, 0x51, 0x47, 0x65, 0x49,
1241 0x24, 0x42, 0x68, 0x49, 0x56, 0x47, 0x75, 0x4a,
1242 0x77, 0x4a, 0x31, 0x43, 0x1d, 0x41, 0x71, 0x49,
1243 0x53, 0x46, 0x29, 0x42, 0x6b, 0x48, 0x1f, 0x41,
1244 0x79, 0x49, 0x6f, 0x48, 0x7c, 0x49, 0x38, 0x43,
1245 0x7f, 0x49, 0x5d, 0x46, 0x22, 0x41, 0x53, 0x45,
1246 0x54, 0x45, 0x55, 0x45, 0x56, 0x45, 0x57, 0x45,
1247 0x58, 0x45, 0x25, 0x41, 0x67, 0x46, 0x5b, 0x45,
1248 0x41, 0x43, 0x78, 0x47, 0x27, 0x41, 0x51, 0x44,
1249 0x13, 0x21, 0x7d, 0x47, 0x37, 0x42, 0x71, 0x46,
1250 0x6b, 0x2d, 0x14, 0x21, 0x23, 0x23, 0x7d, 0x2f,
1251 0x51, 0x29, 0x61, 0x2b, 0x79, 0x46, 0x1d, 0x22,
1252 0x54, 0x29, 0x45, 0x27, 0x7d, 0x46, 0x7f, 0x46,
1253 0x4f, 0x43, 0x2f, 0x41, 0x1f, 0x22, 0x6a, 0x2b,
1254 0x6b, 0x2b, 0x5b, 0x29, 0x7e, 0x2d, 0x65, 0x44,
1255 0x18, 0x21, 0x5e, 0x29, 0x2a, 0x23, 0x45, 0x26,
1256 0x7b, 0x2c, 0x19, 0x21, 0x74, 0x2b, 0x75, 0x2b,
1257 0x51, 0x27, 0x3f, 0x25, 0x65, 0x29, 0x40, 0x25,
1258 0x24, 0x22, 0x41, 0x25, 0x68, 0x29, 0x42, 0x25,
1259 0x56, 0x27, 0x7e, 0x2b, 0x75, 0x2a, 0x1c, 0x21,
1260 0x77, 0x2a, 0x4f, 0x26, 0x31, 0x23, 0x6f, 0x29,
1261 0x1d, 0x21, 0x32, 0x23, 0x71, 0x29, 0x72, 0x29,
1262 0x53, 0x26, 0x69, 0x28, 0x29, 0x22, 0x75, 0x29,
1263 0x6b, 0x28, 0x1f, 0x21, 0x1f, 0x21, 0x6d, 0x28,
1264 0x79, 0x29, 0x2b, 0x22, 0x6f, 0x28, 0x59, 0x26,
1265 0x7c, 0x29, 0x7d, 0x29, 0x38, 0x23, 0x21, 0x21,
1266 0x7f, 0x29, 0x39, 0x23, 0x5d, 0x26, 0x75, 0x28,
1267 0x22, 0x21, 0x77, 0x28, 0x53, 0x25, 0x6c, 0x27,
1268 0x54, 0x25, 0x61, 0x26, 0x55, 0x25, 0x30, 0x22,
1269 0x56, 0x25, 0x63, 0x26, 0x57, 0x25, 0x71, 0x27,
1270 0x58, 0x25, 0x7f, 0x28, 0x25, 0x21, 0x74, 0x27,
1271 0x67, 0x26, 0x40, 0x23, 0x5b, 0x25, 0x26, 0x21,
1272 0x41, 0x23, 0x34, 0x22, 0x78, 0x27, 0x6b, 0x26,
1273 0x27, 0x21, 0x35, 0x22, 0x51, 0x24, 0x7b, 0x27,
1274 0x13, 0x1, 0x13, 0x1, 0x7d, 0x27, 0x4c, 0x9,
1275 0x37, 0x22, 0x5b, 0xb, 0x71, 0x26, 0x5c, 0xb,
1276 0x6b, 0xd, 0x47, 0x23, 0x14, 0x1, 0x4f, 0x9,
1277 0x23, 0x3, 0x75, 0x26, 0x7d, 0xf, 0x1c, 0x2,
1278 0x51, 0x9, 0x59, 0x24, 0x61, 0xb, 0x69, 0x25,
1279 0x79, 0x26, 0x34, 0x5, 0x1d, 0x2, 0x6b, 0x25,
1280 0x54, 0x9, 0x35, 0x5, 0x45, 0x7, 0x6d, 0x25,
1281 0x7d, 0x26, 0x16, 0x1, 0x7f, 0x26, 0x77, 0xd,
1282 0x4f, 0x23, 0x78, 0xd, 0x2f, 0x21, 0x27, 0x3,
1283 0x1f, 0x2, 0x59, 0x9, 0x6a, 0xb, 0x73, 0x25,
1284 0x6b, 0xb, 0x63, 0x24, 0x5b, 0x9, 0x20, 0x2,
1285 0x7e, 0xd, 0x4b, 0x7, 0x65, 0x24, 0x43, 0x22,
1286 0x18, 0x1, 0x6f, 0xb, 0x5e, 0x9, 0x70, 0xb,
1287 0x2a, 0x3, 0x33, 0x4, 0x45, 0x6, 0x60, 0x9,
1288 0x7b, 0xc, 0x19, 0x1, 0x19, 0x1, 0x7d, 0xc,
1289 0x74, 0xb, 0x50, 0x7, 0x75, 0xb, 0x63, 0x9,
1290 0x51, 0x7, 0x23, 0x2, 0x3f, 0x5, 0x1a, 0x1,
1291 0x65, 0x9, 0x2d, 0x3, 0x40, 0x5, 0x0, 0x0,
1292};
1293
1294/* Console colors */
1295unsigned char cvconscolors[16][3] = { /* background, foreground, hilite */
1296 /* R G B */
1297 {0x30, 0x30, 0x30},
1298 {0x00, 0x00, 0x00},
1299 {0x80, 0x00, 0x00},
1300 {0x00, 0x80, 0x00},
1301 {0x00, 0x00, 0x80},
1302 {0x80, 0x80, 0x00},
1303 {0x00, 0x80, 0x80},
1304 {0x80, 0x00, 0x80},
1305 {0xff, 0xff, 0xff},
1306 {0x40, 0x40, 0x40},
1307 {0xff, 0x00, 0x00},
1308 {0x00, 0xff, 0x00},
1309 {0x00, 0x00, 0xff},
1310 {0xff, 0xff, 0x00},
1311 {0x00, 0xff, 0xff},
1312 {0x00, 0x00, 0xff}
1313};
1314
1315/* -------------------- Hardware specific routines ------------------------- */
1316
1317/* Read Attribute Controller Register=idx */
1318inline unsigned char RAttr (volatile unsigned char *regs, short idx)
1319{
1320 wb_64 (regs, ACT_ADDRESS_W, idx);
1321 mb();
1322 udelay(100);
1323 return (rb_64(regs, ACT_ADDRESS_R));
1324}
1325
1326/* Read Sequencer Register=idx */
1327inline unsigned char RSeq (volatile unsigned char *regs, short idx)
1328{
1329 wb_64 (regs, SEQ_ADDRESS, idx);
1330 mb();
1331 return (rb_64(regs, SEQ_ADDRESS_R));
1332}
1333
1334/* Read CRT Controller Register=idx */
1335inline unsigned char RCrt (volatile unsigned char *regs, short idx)
1336{
1337 wb_64 (regs, CRT_ADDRESS, idx);
1338 mb();
1339 return (rb_64(regs, CRT_ADDRESS_R));
1340}
1341
1342/* Read Graphics Controller Register=idx */
1343inline unsigned char RGfx (volatile unsigned char *regs, short idx)
1344{
1345 wb_64 (regs, GCT_ADDRESS, idx);
1346 mb();
1347 return (rb_64(regs, GCT_ADDRESS_R));
1348}
1349
1350/*
1351 * Special wakeup/passthrough registers on graphics boards
1352 */
1353
1354inline void cv64_write_port (unsigned short bits,
1355 volatile unsigned char *base)
1356{
1357 volatile unsigned char *addr;
1358 static unsigned char cvportbits = 0; /* Mirror port bits here */
1359 DPRINTK("ENTER\n");
1360
1361 addr = base + 0x40001;
1362 if (bits & 0x8000) {
1363 cvportbits |= bits & 0xff; /* Set bits */
1364 DPRINTK("Set bits: %04x\n", bits);
1365 } else {
1366 bits = bits & 0xff;
1367 bits = (~bits) & 0xff;
1368 cvportbits &= bits; /* Clear bits */
1369 DPRINTK("Clear bits: %04x\n", bits);
1370 }
1371
1372 *addr = cvportbits;
1373 DPRINTK("EXIT\n");
1374}
1375
1376/*
1377 * Monitor switch on CyberVision board
1378 *
1379 * toggle:
1380 * 0 = CyberVision Signal
1381 * 1 = Amiga Signal
1382 * board = board addr
1383 *
1384 */
1385inline void cvscreen (int toggle, volatile unsigned char *board)
1386{
1387 DPRINTK("ENTER\n");
1388 if (toggle == 1) {
1389 DPRINTK("Show Amiga video\n");
1390 cv64_write_port (0x10, board);
1391 } else {
1392 DPRINTK("Show CyberVision video\n");
1393 cv64_write_port (0x8010, board);
1394 }
1395 DPRINTK("EXIT\n");
1396}
1397
1398/* Control screen display */
1399/* toggle: 0 = on, 1 = off */
1400/* board = registerbase */
1401inline void gfx_on_off(int toggle, volatile unsigned char *regs)
1402{
1403 int r;
1404 DPRINTK("ENTER\n");
1405
1406 toggle &= 0x1;
1407 toggle = toggle << 5;
1408 DPRINTK("Turn display %s\n", (toggle ? "off" : "on"));
1409
1410 r = (int) RSeq(regs, SEQ_ID_CLOCKING_MODE);
1411 r &= 0xdf; /* Set bit 5 to 0 */
1412
1413 WSeq (regs, SEQ_ID_CLOCKING_MODE, r | toggle);
1414 DPRINTK("EXIT\n");
1415}
1416
1417/*
1418 * Computes M, N, and R values from
1419 * given input frequency. It uses a table of
1420 * precomputed values, to keep CPU time low.
1421 *
1422 * The return value consist of:
1423 * lower byte: Bits 4-0: N Divider Value
1424 * Bits 5-6: R Value for e.g. SR10 or SR12
1425 * higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13
1426 */
1427static unsigned short cv64_compute_clock(unsigned long freq)
1428{
1429 static unsigned char *mnr, *save; /* M, N + R vals */
1430 unsigned long work_freq, r;
1431 unsigned short erg;
1432 long diff, d2;
1433
1434 DPRINTK("ENTER\n");
1435 if (freq < 12500000 || freq > MAXPIXELCLOCK) {
1436 printk("CV64 driver: Illegal clock frequency %ld, using 25MHz\n",
1437 freq);
1438 freq = 25000000;
1439 }
1440 DPRINTK("Freq = %ld\n", freq);
1441 mnr = clocks; /* there the vals are stored */
1442 d2 = 0x7fffffff;
1443
1444 while (*mnr) { /* mnr vals are 0-terminated */
1445 work_freq = (0x37EE * (mnr[0] + 2)) / ((mnr[1] & 0x1F) + 2);
1446
1447 r = (mnr[1] >> 5) & 0x03;
1448 if (r != 0) {
1449 work_freq = work_freq >> r; /* r is the freq divider */
1450 }
1451
1452 work_freq *= 0x3E8; /* 2nd part of OSC */
1453
1454 diff = abs(freq - work_freq);
1455
1456 if (d2 >= diff) {
1457 d2 = diff;
1458 /* In save are the vals for minimal diff */
1459 save = mnr;
1460 }
1461 mnr += 2;
1462 }
1463 erg = *((unsigned short *)save);
1464
1465 DPRINTK("EXIT\n");
1466 return (erg);
1467}
1468
1469static int cv_has_4mb (volatile unsigned char *fb)
1470{
1471 volatile unsigned long *tr, *tw;
1472 DPRINTK("ENTER\n");
1473
1474 /* write patterns in memory and test if they can be read */
1475 tw = (volatile unsigned long *) fb;
1476 tr = (volatile unsigned long *) (fb + 0x02000000);
1477
1478 *tw = 0x87654321;
1479
1480 if (*tr != 0x87654321) {
1481 DPRINTK("EXIT - <4MB\n");
1482 return (0);
1483 }
1484
1485 /* upper memory region */
1486 tw = (volatile unsigned long *) (fb + 0x00200000);
1487 tr = (volatile unsigned long *) (fb + 0x02200000);
1488
1489 *tw = 0x87654321;
1490
1491 if (*tr != 0x87654321) {
1492 DPRINTK("EXIT - <4MB\n");
1493 return (0);
1494 }
1495
1496 *tw = 0xAAAAAAAA;
1497
1498 if (*tr != 0xAAAAAAAA) {
1499 DPRINTK("EXIT - <4MB\n");
1500 return (0);
1501 }
1502
1503 *tw = 0x55555555;
1504
1505 if (*tr != 0x55555555) {
1506 DPRINTK("EXIT - <4MB\n");
1507 return (0);
1508 }
1509
1510 DPRINTK("EXIT\n");
1511 return (1);
1512}
1513
1514static void cv64_board_init (void)
1515{
1516 volatile unsigned char *regs = CyberRegs;
1517 int i;
1518 unsigned int clockpar;
1519 unsigned char test;
1520
1521 DPRINTK("ENTER\n");
1522
1523 /*
1524 * Special CyberVision 64 board operations
1525 */
1526 /* Reset board */
1527 for (i = 0; i < 6; i++) {
1528 cv64_write_port (0xff, CyberBase);
1529 }
1530 /* Return to operational mode */
1531 cv64_write_port (0x8004, CyberBase);
1532
1533 /*
1534 * Generic (?) S3 chip wakeup
1535 */
1536 /* Disable I/O & memory decoders, video in setup mode */
1537 wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x10);
1538 /* Video responds to cmds, addrs & data */
1539 wb_64 (regs, SREG_OPTION_SELECT, 0x1);
1540 /* Enable I/O & memory decoders, video in operational mode */
1541 wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x8);
1542 /* VGA color emulation, enable cpu access to display mem */
1543 wb_64 (regs, GREG_MISC_OUTPUT_W, 0x03);
1544 /* Unlock S3 VGA regs */
1545 WCrt (regs, CRT_ID_REGISTER_LOCK_1, 0x48);
1546 /* Unlock system control & extension registers */
1547 WCrt (regs, CRT_ID_REGISTER_LOCK_2, 0xA5);
1548/* GRF - Enable interrupts */
1549 /* Enable enhanced regs access, Ready cntl 0 wait states */
1550 test = RCrt (regs, CRT_ID_SYSTEM_CONFIG);
1551 test = test | 0x01; /* enable enhanced register access */
1552 test = test & 0xEF; /* clear bit 4, 0 wait state */
1553 WCrt (regs, CRT_ID_SYSTEM_CONFIG, test);
1554 /*
1555 * bit 0=1: Enable enhaced mode functions
1556 * bit 2=0: Enhanced mode 8+ bits/pixel
1557 * bit 4=1: Enable linear addressing
1558 * bit 5=1: Enable MMIO
1559 */
1560 wb_64 (regs, ECR_ADV_FUNC_CNTL, 0x31);
1561 /*
1562 * bit 0=1: Color emulation
1563 * bit 1=1: Enable CPU access to display memory
1564 * bit 5=1: Select high 64K memory page
1565 */
1566/* GRF - 0xE3 */
1567 wb_64 (regs, GREG_MISC_OUTPUT_W, 0x23);
1568
1569 /* Cpu base addr */
1570 WCrt (regs, CRT_ID_EXT_SYS_CNTL_4, 0x0);
1571
1572 /* Reset. This does nothing on Trio, but standard VGA practice */
1573 /* WSeq (CyberRegs, SEQ_ID_RESET, 0x03); */
1574 /* Character clocks 8 dots wide */
1575 WSeq (regs, SEQ_ID_CLOCKING_MODE, 0x01);
1576 /* Enable cpu write to all color planes */
1577 WSeq (regs, SEQ_ID_MAP_MASK, 0x0F);
1578 /* Font table in 1st 8k of plane 2, font A=B disables swtich */
1579 WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x0);
1580 /* Allow mem access to 256kb */
1581 WSeq (regs, SEQ_ID_MEMORY_MODE, 0x2);
1582 /* Unlock S3 extensions to VGA Sequencer regs */
1583 WSeq (regs, SEQ_ID_UNLOCK_EXT, 0x6);
1584
1585 /* Enable 4MB fast page mode */
1586 test = RSeq (regs, SEQ_ID_BUS_REQ_CNTL);
1587 test = test | 1 << 6;
1588 WSeq (regs, SEQ_ID_BUS_REQ_CNTL, test);
1589
1590 /* Faster LUT write: 1 DCLK LUT write cycle, RAMDAC clk doubled */
1591 WSeq (regs, SEQ_ID_RAMDAC_CNTL, 0xC0);
1592
1593 /* Clear immediate clock load bit */
1594 test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
1595 test = test & 0xDF;
1596 /* If > 55MHz, enable 2 cycle memory write */
1597 if (cv64_memclk >= 55000000) {
1598 test |= 0x80;
1599 }
1600 WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test);
1601
1602 /* Set MCLK value */
1603 clockpar = cv64_compute_clock (cv64_memclk);
1604 test = (clockpar & 0xFF00) >> 8;
1605 WSeq (regs, SEQ_ID_MCLK_HI, test);
1606 test = clockpar & 0xFF;
1607 WSeq (regs, SEQ_ID_MCLK_LO, test);
1608
1609 /* Chip rev specific: Not in my Trio manual!!! */
1610 if (RCrt (regs, CRT_ID_REVISION) == 0x10)
1611 WSeq (regs, SEQ_ID_MORE_MAGIC, test);
1612
1613 /* We now load an 25 MHz, 31kHz, 640x480 standard VGA Mode. */
1614
1615 /* Set DCLK value */
1616 WSeq (regs, SEQ_ID_DCLK_HI, 0x13);
1617 WSeq (regs, SEQ_ID_DCLK_LO, 0x41);
1618
1619 /* Load DCLK (and MCLK?) immediately */
1620 test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
1621 test = test | 0x22;
1622 WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test);
1623
1624 /* Enable loading of DCLK */
1625 test = rb_64(regs, GREG_MISC_OUTPUT_R);
1626 test = test | 0x0C;
1627 wb_64 (regs, GREG_MISC_OUTPUT_W, test);
1628
1629 /* Turn off immediate xCLK load */
1630 WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, 0x2);
1631
1632 /* Horizontal character clock counts */
1633 /* 8 LSB of 9 bits = total line - 5 */
1634 WCrt (regs, CRT_ID_HOR_TOTAL, 0x5F);
1635 /* Active display line */
1636 WCrt (regs, CRT_ID_HOR_DISP_ENA_END, 0x4F);
1637 /* Blank assertion start */
1638 WCrt (regs, CRT_ID_START_HOR_BLANK, 0x50);
1639 /* Blank assertion end */
1640 WCrt (regs, CRT_ID_END_HOR_BLANK, 0x82);
1641 /* HSYNC assertion start */
1642 WCrt (regs, CRT_ID_START_HOR_RETR, 0x54);
1643 /* HSYNC assertion end */
1644 WCrt (regs, CRT_ID_END_HOR_RETR, 0x80);
1645 WCrt (regs, CRT_ID_VER_TOTAL, 0xBF);
1646 WCrt (regs, CRT_ID_OVERFLOW, 0x1F);
1647 WCrt (regs, CRT_ID_PRESET_ROW_SCAN, 0x0);
1648 WCrt (regs, CRT_ID_MAX_SCAN_LINE, 0x40);
1649 WCrt (regs, CRT_ID_CURSOR_START, 0x00);
1650 WCrt (regs, CRT_ID_CURSOR_END, 0x00);
1651 WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00);
1652 WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00);
1653 WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1654 WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
1655 WCrt (regs, CRT_ID_START_VER_RETR, 0x9C);
1656 WCrt (regs, CRT_ID_END_VER_RETR, 0x0E);
1657 WCrt (regs, CRT_ID_VER_DISP_ENA_END, 0x8F);
1658 WCrt (regs, CRT_ID_SCREEN_OFFSET, 0x50);
1659 WCrt (regs, CRT_ID_UNDERLINE_LOC, 0x00);
1660 WCrt (regs, CRT_ID_START_VER_BLANK, 0x96);
1661 WCrt (regs, CRT_ID_END_VER_BLANK, 0xB9);
1662 WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3);
1663 WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF);
1664 WCrt (regs, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
1665 WCrt (regs, CRT_ID_MISC_1, 0x35);
1666 WCrt (regs, CRT_ID_DISPLAY_FIFO, 0x5A);
1667 WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, 0x70);
1668 WCrt (regs, CRT_ID_LAW_POS_LO, 0x40);
1669 WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, 0xFF);
1670
1671 WGfx (regs, GCT_ID_SET_RESET, 0x0);
1672 WGfx (regs, GCT_ID_ENABLE_SET_RESET, 0x0);
1673 WGfx (regs, GCT_ID_COLOR_COMPARE, 0x0);
1674 WGfx (regs, GCT_ID_DATA_ROTATE, 0x0);
1675 WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x0);
1676 WGfx (regs, GCT_ID_GRAPHICS_MODE, 0x40);
1677 WGfx (regs, GCT_ID_MISC, 0x01);
1678 WGfx (regs, GCT_ID_COLOR_XCARE, 0x0F);
1679 WGfx (regs, GCT_ID_BITMASK, 0xFF);
1680
1681 /* Colors for text mode */
1682 for (i = 0; i < 0xf; i++)
1683 WAttr (regs, i, i);
1684
1685 WAttr (regs, ACT_ID_ATTR_MODE_CNTL, 0x41);
1686 WAttr (regs, ACT_ID_OVERSCAN_COLOR, 0x01);
1687 WAttr (regs, ACT_ID_COLOR_PLANE_ENA, 0x0F);
1688 WAttr (regs, ACT_ID_HOR_PEL_PANNING, 0x0);
1689 WAttr (regs, ACT_ID_COLOR_SELECT, 0x0);
1690
1691 wb_64 (regs, VDAC_MASK, 0xFF);
1692
1693 *((unsigned long *) (regs + ECR_FRGD_COLOR)) = 0xFF;
1694 *((unsigned long *) (regs + ECR_BKGD_COLOR)) = 0;
1695
1696 /* Colors initially set to grayscale */
1697
1698 wb_64 (regs, VDAC_ADDRESS_W, 0);
1699 for (i = 255; i >= 0; i--) {
1700 wb_64(regs, VDAC_DATA, i);
1701 wb_64(regs, VDAC_DATA, i);
1702 wb_64(regs, VDAC_DATA, i);
1703 }
1704
1705 /* GFx hardware cursor off */
1706 WCrt (regs, CRT_ID_HWGC_MODE, 0x00);
1707
1708 /* Set first to 4MB, so test will work */
1709 WCrt (regs, CRT_ID_LAW_CNTL, 0x13);
1710 /* Find "correct" size of fbmem of Z3 board */
1711 if (cv_has_4mb (CyberMem)) {
1712 CyberSize = 1024 * 1024 * 4;
1713 WCrt (regs, CRT_ID_LAW_CNTL, 0x13);
1714 DPRINTK("4MB board\n");
1715 } else {
1716 CyberSize = 1024 * 1024 * 2;
1717 WCrt (regs, CRT_ID_LAW_CNTL, 0x12);
1718 DPRINTK("2MB board\n");
1719 }
1720
1721 /* Initialize graphics engine */
1722 Cyber_WaitBlit();
1723 vgaw16 (regs, ECR_FRGD_MIX, 0x27);
1724 vgaw16 (regs, ECR_BKGD_MIX, 0x07);
1725 vgaw16 (regs, ECR_READ_REG_DATA, 0x1000);
1726 udelay(200);
1727 vgaw16 (regs, ECR_READ_REG_DATA, 0x2000);
1728 Cyber_WaitBlit();
1729 vgaw16 (regs, ECR_READ_REG_DATA, 0x3FFF);
1730 Cyber_WaitBlit();
1731 udelay(200);
1732 vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF);
1733 Cyber_WaitBlit();
1734 vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, ~0);
1735 Cyber_WaitBlit();
1736 vgaw16 (regs, ECR_READ_REG_DATA, 0xE000);
1737 vgaw16 (regs, ECR_CURRENT_Y_POS2, 0x00);
1738 vgaw16 (regs, ECR_CURRENT_X_POS2, 0x00);
1739 vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
1740 vgaw16 (regs, ECR_DEST_Y__AX_STEP, 0x00);
1741 vgaw16 (regs, ECR_DEST_Y2__AX_STEP2, 0x00);
1742 vgaw16 (regs, ECR_DEST_X__DIA_STEP, 0x00);
1743 vgaw16 (regs, ECR_DEST_X2__DIA_STEP2, 0x00);
1744 vgaw16 (regs, ECR_SHORT_STROKE, 0x00);
1745 vgaw16 (regs, ECR_DRAW_CMD, 0x01);
1746
1747 Cyber_WaitBlit();
1748
1749 vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF);
1750 vgaw16 (regs, ECR_BKGD_COLOR, 0x01);
1751 vgaw16 (regs, ECR_FRGD_COLOR, 0x00);
1752
1753
1754 /* Enable video display (set bit 5) */
1755/* ARB - Would also seem to write to AR13.
1756 * May want to use parts of WAttr to set JUST bit 5
1757 */
1758 WAttr (regs, 0x33, 0);
1759
1760/* GRF - function code ended here */
1761
1762 /* Turn gfx on again */
1763 gfx_on_off (0, regs);
1764
1765 /* Pass-through */
1766 cvscreen (0, CyberBase);
1767
1768 DPRINTK("EXIT\n");
1769}
1770
1771static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
1772{
1773 volatile unsigned char *regs = CyberRegs;
1774 int fx, fy;
1775 unsigned short mnr;
1776 unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS, VSE, VT;
1777 char LACE, DBLSCAN, TEXT, CONSOLE;
1778 int cr50, sr15, sr18, clock_mode, test;
1779 int m, n;
1780 int tfillm, temptym;
1781 int hmul;
1782
1783 /* ---------------- */
1784 int xres, hfront, hsync, hback;
1785 int yres, vfront, vsync, vback;
1786 int bpp;
1787#if 0
1788 float freq_f;
1789#endif
1790 long freq;
1791 /* ---------------- */
1792
1793 DPRINTK("ENTER\n");
1794 TEXT = 0; /* if depth == 4 */
1795 CONSOLE = 0; /* mode num == 255 (console) */
1796 fx = fy = 8; /* force 8x8 font */
1797
1798/* GRF - Disable interrupts */
1799
1800 gfx_on_off (1, regs);
1801
1802 switch (video_mode->bits_per_pixel) {
1803 case 15:
1804 case 16:
1805 hmul = 2;
1806 break;
1807
1808 default:
1809 hmul = 1;
1810 break;
1811 }
1812
1813 bpp = video_mode->bits_per_pixel;
1814 xres = video_mode->xres;
1815 hfront = video_mode->right_margin;
1816 hsync = video_mode->hsync_len;
1817 hback = video_mode->left_margin;
1818
1819 LACE = 0;
1820 DBLSCAN = 0;
1821
1822 if (video_mode->vmode & FB_VMODE_DOUBLE) {
1823 yres = video_mode->yres * 2;
1824 vfront = video_mode->lower_margin * 2;
1825 vsync = video_mode->vsync_len * 2;
1826 vback = video_mode->upper_margin * 2;
1827 DBLSCAN = 1;
1828 } else if (video_mode->vmode & FB_VMODE_INTERLACED) {
1829 yres = (video_mode->yres + 1) / 2;
1830 vfront = (video_mode->lower_margin + 1) / 2;
1831 vsync = (video_mode->vsync_len + 1) / 2;
1832 vback = (video_mode->upper_margin + 1) / 2;
1833 LACE = 1;
1834 } else {
1835 yres = video_mode->yres;
1836 vfront = video_mode->lower_margin;
1837 vsync = video_mode->vsync_len;
1838 vback = video_mode->upper_margin;
1839 }
1840
1841 /* ARB Dropping custom setup method from cvision.c */
1842#if 0
1843 if (cvision_custom_mode) {
1844 HBS = hbs / 8 * hmul;
1845 HBE = hbe / 8 * hmul;
1846 HSS = hss / 8 * hmul;
1847 HSE = hse / 8 * hmul;
1848 HT = ht / 8 * hmul - 5;
1849
1850 VBS = vbs - 1;
1851 VSS = vss;
1852 VSE = vse;
1853 VBE = vbe;
1854 VT = vt - 2;
1855 } else {
1856#else
1857 {
1858#endif
1859 HBS = hmul * (xres / 8);
1860 HBE = hmul * ((xres/8) + (hfront/8) + (hsync/8) + (hback/8) - 2);
1861 HSS = hmul * ((xres/8) + (hfront/8) + 2);
1862 HSE = hmul * ((xres/8) + (hfront/8) + (hsync/8) + 1);
1863 HT = hmul * ((xres/8) + (hfront/8) + (hsync/8) + (hback/8));
1864
1865 VBS = yres;
1866 VBE = yres + vfront + vsync + vback - 2;
1867 VSS = yres + vfront - 1;
1868 VSE = yres + vfront + vsync - 1;
1869 VT = yres + vfront + vsync + vback - 2;
1870 }
1871
1872 wb_64 (regs, ECR_ADV_FUNC_CNTL, (TEXT ? 0x00 : 0x31));
1873
1874 if (TEXT)
1875 HDE = ((video_mode->xres + fx - 1) / fx) - 1;
1876 else
1877 HDE = (video_mode->xres + 3) * hmul / 8 - 1;
1878
1879 VDE = video_mode->yres - 1;
1880
1881 WCrt (regs, CRT_ID_HWGC_MODE, 0x00);
1882 WCrt (regs, CRT_ID_EXT_DAC_CNTL, 0x00);
1883
1884 WSeq (regs, SEQ_ID_MEMORY_MODE,
1885 (TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x0e);
1886 WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x00);
1887 WSeq (regs, SEQ_ID_MAP_MASK,
1888 (video_mode->bits_per_pixel == 1) ? 0x01 : 0xFF);
1889 WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x00);
1890
1891 /* cv64_compute_clock accepts arguments in Hz */
1892 /* pixclock is in ps ... convert to Hz */
1893
1894#if 0
1895 freq_f = (1.0 / (float) video_mode->pixclock) * 1000000000;
1896 freq = ((long) freq_f) * 1000;
1897#else
1898/* freq = (long) ((long long)1000000000000 / (long long) video_mode->pixclock);
1899 */
1900 freq = (1000000000 / video_mode->pixclock) * 1000;
1901#endif
1902
1903 mnr = cv64_compute_clock (freq);
1904 WSeq (regs, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8));
1905 WSeq (regs, SEQ_ID_DCLK_LO, (mnr & 0xFF));
1906
1907 /* Load display parameters into board */
1908 WCrt (regs, CRT_ID_EXT_HOR_OVF,
1909 ((HT & 0x100) ? 0x01 : 0x00) |
1910 ((HDE & 0x100) ? 0x02 : 0x00) |
1911 ((HBS & 0x100) ? 0x04 : 0x00) |
1912 /* ((HBE & 0x40) ? 0x08 : 0x00) | */
1913 ((HSS & 0x100) ? 0x10 : 0x00) |
1914 /* ((HSE & 0x20) ? 0x20 : 0x00) | */
1915 (((HT-5) & 0x100) ? 0x40 : 0x00)
1916 );
1917
1918 WCrt (regs, CRT_ID_EXT_VER_OVF,
1919 0x40 |
1920 ((VT & 0x400) ? 0x01 : 0x00) |
1921 ((VDE & 0x400) ? 0x02 : 0x00) |
1922 ((VBS & 0x400) ? 0x04 : 0x00) |
1923 ((VSS & 0x400) ? 0x10 : 0x00)
1924 );
1925
1926 WCrt (regs, CRT_ID_HOR_TOTAL, HT);
1927 WCrt (regs, CRT_ID_DISPLAY_FIFO, HT - 5);
1928 WCrt (regs, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
1929 WCrt (regs, CRT_ID_START_HOR_BLANK, HBS);
1930 WCrt (regs, CRT_ID_END_HOR_BLANK, ((HBE & 0x1F) | 0x80));
1931 WCrt (regs, CRT_ID_START_HOR_RETR, HSS);
1932 WCrt (regs, CRT_ID_END_HOR_RETR,
1933 (HSE & 0x1F) |
1934 ((HBE & 0x20) ? 0x80 : 0x00)
1935 );
1936 WCrt (regs, CRT_ID_VER_TOTAL, VT);
1937 WCrt (regs, CRT_ID_OVERFLOW,
1938 0x10 |
1939 ((VT & 0x100) ? 0x01 : 0x00) |
1940 ((VDE & 0x100) ? 0x02 : 0x00) |
1941 ((VSS & 0x100) ? 0x04 : 0x00) |
1942 ((VBS & 0x100) ? 0x08 : 0x00) |
1943 ((VT & 0x200) ? 0x20 : 0x00) |
1944 ((VDE & 0x200) ? 0x40 : 0x00) |
1945 ((VSS & 0x200) ? 0x80 : 0x00)
1946 );
1947 WCrt (regs, CRT_ID_MAX_SCAN_LINE,
1948 0x40 |
1949 (DBLSCAN ? 0x80 : 0x00) |
1950 ((VBS & 0x200) ? 0x20 : 0x00) |
1951 (TEXT ? ((fy - 1) & 0x1F) : 0x00)
1952 );
1953
1954 WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3);
1955
1956 /* Text cursor */
1957
1958 if (TEXT) {
1959#if 1
1960 WCrt (regs, CRT_ID_CURSOR_START, (fy & 0x1f) - 2);
1961 WCrt (regs, CRT_ID_CURSOR_END, (fy & 0x1F) - 1);
1962#else
1963 WCrt (regs, CRT_ID_CURSOR_START, 0x00);
1964 WCrt (regs, CRT_ID_CURSOR_END, fy & 0x1F);
1965#endif
1966 WCrt (regs, CRT_ID_UNDERLINE_LOC, (fy - 1) & 0x1F);
1967 WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1968 WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
1969 }
1970
1971 WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00);
1972 WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00);
1973 WCrt (regs, CRT_ID_START_VER_RETR, VSS);
1974 WCrt (regs, CRT_ID_END_VER_RETR, (VSE & 0x0F));
1975 WCrt (regs, CRT_ID_VER_DISP_ENA_END, VDE);
1976 WCrt (regs, CRT_ID_START_VER_BLANK, VBS);
1977 WCrt (regs, CRT_ID_END_VER_BLANK, VBE);
1978 WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF);
1979 WCrt (regs, CRT_ID_LACE_RETR_START, HT / 2);
1980 WCrt (regs, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
1981 WGfx (regs, GCT_ID_GRAPHICS_MODE,
1982 ((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x00 : 0x40));
1983 WGfx (regs, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
1984 WSeq (regs, SEQ_ID_MEMORY_MODE,
1985 ((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x02));
1986
1987 wb_64 (regs, VDAC_MASK, 0xFF);
1988
1989 /* Blank border */
1990 test = RCrt (regs, CRT_ID_BACKWAD_COMP_2);
1991 WCrt (regs, CRT_ID_BACKWAD_COMP_2, (test | 0x20));
1992
1993 sr15 = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
1994 sr15 &= 0xEF;
1995 sr18 = RSeq (regs, SEQ_ID_RAMDAC_CNTL);
1996 sr18 &= 0x7F;
1997 clock_mode = 0x00;
1998 cr50 = 0x00;
1999
2000 test = RCrt (regs, CRT_ID_EXT_MISC_CNTL_2);
2001 test &= 0xD;
2002
2003 /* Clear roxxler byte-swapping... */
2004 cv64_write_port (0x0040, CyberBase);
2005 cv64_write_port (0x0020, CyberBase);
2006
2007 switch (video_mode->bits_per_pixel) {
2008 case 1:
2009 case 4: /* text */
2010 HDE = video_mode->xres / 16;
2011 break;
2012
2013 case 8:
2014 if (freq > 80000000) {
2015 clock_mode = 0x10 | 0x02;
2016 sr15 |= 0x10;
2017 sr18 |= 0x80;
2018 }
2019 HDE = video_mode->xres / 8;
2020 cr50 |= 0x00;
2021 break;
2022
2023 case 15:
2024 cv64_write_port (0x8020, CyberBase);
2025 clock_mode = 0x30;
2026 HDE = video_mode->xres / 4;
2027 cr50 |= 0x10;
2028 break;
2029
2030 case 16:
2031 cv64_write_port (0x8020, CyberBase);
2032 clock_mode = 0x50;
2033 HDE = video_mode->xres / 4;
2034 cr50 |= 0x10;
2035 break;
2036
2037 case 24:
2038 case 32:
2039 cv64_write_port (0x8040, CyberBase);
2040 clock_mode = 0xD0;
2041 HDE = video_mode->xres / 2;
2042 cr50 |= 0x30;
2043 break;
2044 }
2045
2046 WCrt (regs, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
2047 WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, sr15);
2048 WSeq (regs, SEQ_ID_RAMDAC_CNTL, sr18);
2049 WCrt (regs, CRT_ID_SCREEN_OFFSET, HDE);
2050
2051 WCrt (regs, CRT_ID_MISC_1, (TEXT ? 0x05 : 0x35));
2052
2053 test = RCrt (regs, CRT_ID_EXT_SYS_CNTL_2);
2054 test &= ~0x30;
2055 test |= (HDE >> 4) & 0x30;
2056 WCrt (regs, CRT_ID_EXT_SYS_CNTL_2, test);
2057
2058 /* Set up graphics engine */
2059 switch (video_mode->xres) {
2060 case 1024:
2061 cr50 |= 0x00;
2062 break;
2063
2064 case 640:
2065 cr50 |= 0x40;
2066 break;
2067
2068 case 800:
2069 cr50 |= 0x80;
2070 break;
2071
2072 case 1280:
2073 cr50 |= 0xC0;
2074 break;
2075
2076 case 1152:
2077 cr50 |= 0x01;
2078 break;
2079
2080 case 1600:
2081 cr50 |= 0x81;
2082 break;
2083
2084 default: /* XXX */
2085 break;
2086 }
2087
2088 WCrt (regs, CRT_ID_EXT_SYS_CNTL_1, cr50);
2089
2090 udelay(100);
2091 WAttr (regs, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x08 : 0x41));
2092 udelay(100);
2093 WAttr (regs, ACT_ID_COLOR_PLANE_ENA,
2094 (video_mode->bits_per_pixel == 1) ? 0x01 : 0x0F);
2095 udelay(100);
2096
2097 tfillm = (96 * (cv64_memclk / 1000)) / 240000;
2098
2099 switch (video_mode->bits_per_pixel) {
2100 case 32:
2101 case 24:
2102 temptym = (24 * (cv64_memclk / 1000)) / (freq / 1000);
2103 break;
2104 case 15:
2105 case 16:
2106 temptym = (48 * (cv64_memclk / 1000)) / (freq / 1000);
2107 break;
2108 case 4:
2109 temptym = (192 * (cv64_memclk / 1000)) / (freq / 1000);
2110 break;
2111 default:
2112 temptym = (96 * (cv64_memclk / 1000)) / (freq / 1000);
2113 break;
2114 }
2115
2116 m = (temptym - tfillm - 9) / 2;
2117 if (m < 0)
2118 m = 0;
2119 m = (m & 0x1F) << 3;
2120 if (m < 0x18)
2121 m = 0x18;
2122 n = 0xFF;
2123
2124 WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, m);
2125 WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, n);
2126 udelay(10);
2127
2128 /* Text initialization */
2129
2130 if (TEXT) {
2131 /* Do text initialization here ! */
2132 }
2133
2134 if (CONSOLE) {
2135 int i;
2136 wb_64 (regs, VDAC_ADDRESS_W, 0);
2137 for (i = 0; i < 4; i++) {
2138 wb_64 (regs, VDAC_DATA, cvconscolors [i][0]);
2139 wb_64 (regs, VDAC_DATA, cvconscolors [i][1]);
2140 wb_64 (regs, VDAC_DATA, cvconscolors [i][2]);
2141 }
2142 }
2143
2144 WAttr (regs, 0x33, 0);
2145
2146 /* Turn gfx on again */
2147 gfx_on_off (0, (volatile unsigned char *) regs);
2148
2149 /* Pass-through */
2150 cvscreen (0, CyberBase);
2151
2152DPRINTK("EXIT\n");
2153}
2154
2155void cvision_bitblt (u_short sx, u_short sy, u_short dx, u_short dy,
2156 u_short w, u_short h)
2157{
2158 volatile unsigned char *regs = CyberRegs;
2159 unsigned short drawdir = 0;
2160
2161 DPRINTK("ENTER\n");
2162 if (sx > dx) {
2163 drawdir |= 1 << 5;
2164 } else {
2165 sx += w - 1;
2166 dx += w - 1;
2167 }
2168
2169 if (sy > dy) {
2170 drawdir |= 1 << 7;
2171 } else {
2172 sy += h - 1;
2173 dy += h - 1;
2174 }
2175
2176 Cyber_WaitBlit();
2177 vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
2178 vgaw16 (regs, ECR_BKGD_MIX, 0x7);
2179 vgaw16 (regs, ECR_FRGD_MIX, 0x67);
2180 vgaw16 (regs, ECR_BKGD_COLOR, 0x0);
2181 vgaw16 (regs, ECR_FRGD_COLOR, 0x1);
2182 vgaw16 (regs, ECR_BITPLANE_READ_MASK, 0x1);
2183 vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, 0xFFF);
2184 vgaw16 (regs, ECR_CURRENT_Y_POS, sy);
2185 vgaw16 (regs, ECR_CURRENT_X_POS, sx);
2186 vgaw16 (regs, ECR_DEST_Y__AX_STEP, dy);
2187 vgaw16 (regs, ECR_DEST_X__DIA_STEP, dx);
2188 vgaw16 (regs, ECR_READ_REG_DATA, h - 1);
2189 vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
2190 vgaw16 (regs, ECR_DRAW_CMD, 0xC051 | drawdir);
2191 DPRINTK("EXIT\n");
2192}
2193
2194void cvision_clear (u_short dx, u_short dy, u_short w, u_short h, u_short bg)
2195{
2196 volatile unsigned char *regs = CyberRegs;
2197 DPRINTK("ENTER\n");
2198 Cyber_WaitBlit();
2199 vgaw16 (regs, ECR_FRGD_MIX, 0x0027);
2200 vgaw16 (regs, ECR_FRGD_COLOR, bg);
2201 vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
2202 vgaw16 (regs, ECR_CURRENT_Y_POS, dy);
2203 vgaw16 (regs, ECR_CURRENT_X_POS, dx);
2204 vgaw16 (regs, ECR_READ_REG_DATA, h - 1);
2205 vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
2206 vgaw16 (regs, ECR_DRAW_CMD, 0x40B1);
2207 DPRINTK("EXIT\n");
2208}
2209
2210#ifdef CYBERFBDEBUG
2211/*
2212 * Dump internal settings of CyberVision board
2213 */
2214static void cv64_dump (void)
2215{
2216 volatile unsigned char *regs = CyberRegs;
2217 DPRINTK("ENTER\n");
2218 /* Dump the VGA setup values */
2219 *(regs + S3_CRTC_ADR) = 0x00;
2220 DPRINTK("CR00 = %x\n", *(regs + S3_CRTC_DATA));
2221 *(regs + S3_CRTC_ADR) = 0x01;
2222 DPRINTK("CR01 = %x\n", *(regs + S3_CRTC_DATA));
2223 *(regs + S3_CRTC_ADR) = 0x02;
2224 DPRINTK("CR02 = %x\n", *(regs + S3_CRTC_DATA));
2225 *(regs + S3_CRTC_ADR) = 0x03;
2226 DPRINTK("CR03 = %x\n", *(regs + S3_CRTC_DATA));
2227 *(regs + S3_CRTC_ADR) = 0x04;
2228 DPRINTK("CR04 = %x\n", *(regs + S3_CRTC_DATA));
2229 *(regs + S3_CRTC_ADR) = 0x05;
2230 DPRINTK("CR05 = %x\n", *(regs + S3_CRTC_DATA));
2231 *(regs + S3_CRTC_ADR) = 0x06;
2232 DPRINTK("CR06 = %x\n", *(regs + S3_CRTC_DATA));
2233 *(regs + S3_CRTC_ADR) = 0x07;
2234 DPRINTK("CR07 = %x\n", *(regs + S3_CRTC_DATA));
2235 *(regs + S3_CRTC_ADR) = 0x08;
2236 DPRINTK("CR08 = %x\n", *(regs + S3_CRTC_DATA));
2237 *(regs + S3_CRTC_ADR) = 0x09;
2238 DPRINTK("CR09 = %x\n", *(regs + S3_CRTC_DATA));
2239 *(regs + S3_CRTC_ADR) = 0x10;
2240 DPRINTK("CR10 = %x\n", *(regs + S3_CRTC_DATA));
2241 *(regs + S3_CRTC_ADR) = 0x11;
2242 DPRINTK("CR11 = %x\n", *(regs + S3_CRTC_DATA));
2243 *(regs + S3_CRTC_ADR) = 0x12;
2244 DPRINTK("CR12 = %x\n", *(regs + S3_CRTC_DATA));
2245 *(regs + S3_CRTC_ADR) = 0x13;
2246 DPRINTK("CR13 = %x\n", *(regs + S3_CRTC_DATA));
2247 *(regs + S3_CRTC_ADR) = 0x15;
2248 DPRINTK("CR15 = %x\n", *(regs + S3_CRTC_DATA));
2249 *(regs + S3_CRTC_ADR) = 0x16;
2250 DPRINTK("CR16 = %x\n", *(regs + S3_CRTC_DATA));
2251 *(regs + S3_CRTC_ADR) = 0x36;
2252 DPRINTK("CR36 = %x\n", *(regs + S3_CRTC_DATA));
2253 *(regs + S3_CRTC_ADR) = 0x37;
2254 DPRINTK("CR37 = %x\n", *(regs + S3_CRTC_DATA));
2255 *(regs + S3_CRTC_ADR) = 0x42;
2256 DPRINTK("CR42 = %x\n", *(regs + S3_CRTC_DATA));
2257 *(regs + S3_CRTC_ADR) = 0x43;
2258 DPRINTK("CR43 = %x\n", *(regs + S3_CRTC_DATA));
2259 *(regs + S3_CRTC_ADR) = 0x50;
2260 DPRINTK("CR50 = %x\n", *(regs + S3_CRTC_DATA));
2261 *(regs + S3_CRTC_ADR) = 0x51;
2262 DPRINTK("CR51 = %x\n", *(regs + S3_CRTC_DATA));
2263 *(regs + S3_CRTC_ADR) = 0x53;
2264 DPRINTK("CR53 = %x\n", *(regs + S3_CRTC_DATA));
2265 *(regs + S3_CRTC_ADR) = 0x58;
2266 DPRINTK("CR58 = %x\n", *(regs + S3_CRTC_DATA));
2267 *(regs + S3_CRTC_ADR) = 0x59;
2268 DPRINTK("CR59 = %x\n", *(regs + S3_CRTC_DATA));
2269 *(regs + S3_CRTC_ADR) = 0x5A;
2270 DPRINTK("CR5A = %x\n", *(regs + S3_CRTC_DATA));
2271 *(regs + S3_CRTC_ADR) = 0x5D;
2272 DPRINTK("CR5D = %x\n", *(regs + S3_CRTC_DATA));
2273 *(regs + S3_CRTC_ADR) = 0x5E;
2274 DPRINTK("CR5E = %x\n", *(regs + S3_CRTC_DATA));
2275 DPRINTK("MISC = %x\n", *(regs + GREG_MISC_OUTPUT_R));
2276 *(regs + SEQ_ADDRESS) = 0x01;
2277 DPRINTK("SR01 = %x\n", *(regs + SEQ_ADDRESS_R));
2278 *(regs + SEQ_ADDRESS) = 0x02;
2279 DPRINTK("SR02 = %x\n", *(regs + SEQ_ADDRESS_R));
2280 *(regs + SEQ_ADDRESS) = 0x03;
2281 DPRINTK("SR03 = %x\n", *(regs + SEQ_ADDRESS_R));
2282 *(regs + SEQ_ADDRESS) = 0x09;
2283 DPRINTK("SR09 = %x\n", *(regs + SEQ_ADDRESS_R));
2284 *(regs + SEQ_ADDRESS) = 0x10;
2285 DPRINTK("SR10 = %x\n", *(regs + SEQ_ADDRESS_R));
2286 *(regs + SEQ_ADDRESS) = 0x11;
2287 DPRINTK("SR11 = %x\n", *(regs + SEQ_ADDRESS_R));
2288 *(regs + SEQ_ADDRESS) = 0x12;
2289 DPRINTK("SR12 = %x\n", *(regs + SEQ_ADDRESS_R));
2290 *(regs + SEQ_ADDRESS) = 0x13;
2291 DPRINTK("SR13 = %x\n", *(regs + SEQ_ADDRESS_R));
2292 *(regs + SEQ_ADDRESS) = 0x15;
2293 DPRINTK("SR15 = %x\n", *(regs + SEQ_ADDRESS_R));
2294
2295 return;
2296}
2297#endif