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