1 /* 2 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets 3 * 4 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> 5 * 6 * Contributors (thanks, all!) 7 * 8 * David Eger: 9 * Overhaul for Linux 2.6 10 * 11 * Jeff Rugen: 12 * Major contributions; Motorola PowerStack (PPC and PCI) support, 13 * GD54xx, 1280x1024 mode support, change MCLK based on VCLK. 14 * 15 * Geert Uytterhoeven: 16 * Excellent code review. 17 * 18 * Lars Hecking: 19 * Amiga updates and testing. 20 * 21 * Original cirrusfb author: Frank Neumann 22 * 23 * Based on retz3fb.c and cirrusfb.c: 24 * Copyright (C) 1997 Jes Sorensen 25 * Copyright (C) 1996 Frank Neumann 26 * 27 *************************************************************** 28 * 29 * Format this code with GNU indent '-kr -i8 -pcs' options. 30 * 31 * This file is subject to the terms and conditions of the GNU General Public 32 * License. See the file COPYING in the main directory of this archive 33 * for more details. 34 * 35 */ 36 37 #include <linux/aperture.h> 38 #include <linux/module.h> 39 #include <linux/kernel.h> 40 #include <linux/errno.h> 41 #include <linux/string.h> 42 #include <linux/mm.h> 43 #include <linux/delay.h> 44 #include <linux/fb.h> 45 #include <linux/init.h> 46 47 #ifdef CONFIG_ZORRO 48 #include <linux/zorro.h> 49 #endif 50 #ifdef CONFIG_PCI 51 #include <linux/pci.h> 52 #endif 53 #ifdef CONFIG_AMIGA 54 #include <asm/amigahw.h> 55 #endif 56 57 #include <video/vga.h> 58 #include <video/cirrus.h> 59 60 /***************************************************************** 61 * 62 * debugging and utility macros 63 * 64 */ 65 66 /* disable runtime assertions? */ 67 /* #define CIRRUSFB_NDEBUG */ 68 69 /* debugging assertions */ 70 #ifndef CIRRUSFB_NDEBUG 71 #define assert(expr) \ 72 if (!(expr)) { \ 73 printk("Assertion failed! %s,%s,%s,line=%d\n", \ 74 #expr, __FILE__, __func__, __LINE__); \ 75 } 76 #else 77 #define assert(expr) 78 #endif 79 80 #define MB_ (1024 * 1024) 81 82 /***************************************************************** 83 * 84 * chipset information 85 * 86 */ 87 88 /* board types */ 89 enum cirrus_board { 90 BT_NONE = 0, 91 BT_SD64, /* GD5434 */ 92 BT_PICCOLO, /* GD5426 */ 93 BT_PICASSO, /* GD5426 or GD5428 */ 94 BT_SPECTRUM, /* GD5426 or GD5428 */ 95 BT_PICASSO4, /* GD5446 */ 96 BT_ALPINE, /* GD543x/4x */ 97 BT_GD5480, 98 BT_LAGUNA, /* GD5462/64 */ 99 BT_LAGUNAB, /* GD5465 */ 100 }; 101 102 /* 103 * per-board-type information, used for enumerating and abstracting 104 * chip-specific information 105 * NOTE: MUST be in the same order as enum cirrus_board in order to 106 * use direct indexing on this array 107 * NOTE: '__initdata' cannot be used as some of this info 108 * is required at runtime. Maybe separate into an init-only and 109 * a run-time table? 110 */ 111 static const struct cirrusfb_board_info_rec { 112 char *name; /* ASCII name of chipset */ 113 long maxclock[5]; /* maximum video clock */ 114 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ 115 bool init_sr07 : 1; /* init SR07 during init_vgachip() */ 116 bool init_sr1f : 1; /* write SR1F during init_vgachip() */ 117 /* construct bit 19 of screen start address */ 118 bool scrn_start_bit19 : 1; 119 120 /* initial SR07 value, then for each mode */ 121 unsigned char sr07; 122 unsigned char sr07_1bpp; 123 unsigned char sr07_1bpp_mux; 124 unsigned char sr07_8bpp; 125 unsigned char sr07_8bpp_mux; 126 127 unsigned char sr1f; /* SR1F VGA initial register value */ 128 } cirrusfb_board_info[] = { 129 [BT_SD64] = { 130 .name = "CL SD64", 131 .maxclock = { 132 /* guess */ 133 /* the SD64/P4 have a higher max. videoclock */ 134 135100, 135100, 85500, 85500, 0 135 }, 136 .init_sr07 = true, 137 .init_sr1f = true, 138 .scrn_start_bit19 = true, 139 .sr07 = 0xF0, 140 .sr07_1bpp = 0xF0, 141 .sr07_1bpp_mux = 0xF6, 142 .sr07_8bpp = 0xF1, 143 .sr07_8bpp_mux = 0xF7, 144 .sr1f = 0x1E 145 }, 146 [BT_PICCOLO] = { 147 .name = "CL Piccolo", 148 .maxclock = { 149 /* guess */ 150 90000, 90000, 90000, 90000, 90000 151 }, 152 .init_sr07 = true, 153 .init_sr1f = true, 154 .scrn_start_bit19 = false, 155 .sr07 = 0x80, 156 .sr07_1bpp = 0x80, 157 .sr07_8bpp = 0x81, 158 .sr1f = 0x22 159 }, 160 [BT_PICASSO] = { 161 .name = "CL Picasso", 162 .maxclock = { 163 /* guess */ 164 90000, 90000, 90000, 90000, 90000 165 }, 166 .init_sr07 = true, 167 .init_sr1f = true, 168 .scrn_start_bit19 = false, 169 .sr07 = 0x20, 170 .sr07_1bpp = 0x20, 171 .sr07_8bpp = 0x21, 172 .sr1f = 0x22 173 }, 174 [BT_SPECTRUM] = { 175 .name = "CL Spectrum", 176 .maxclock = { 177 /* guess */ 178 90000, 90000, 90000, 90000, 90000 179 }, 180 .init_sr07 = true, 181 .init_sr1f = true, 182 .scrn_start_bit19 = false, 183 .sr07 = 0x80, 184 .sr07_1bpp = 0x80, 185 .sr07_8bpp = 0x81, 186 .sr1f = 0x22 187 }, 188 [BT_PICASSO4] = { 189 .name = "CL Picasso4", 190 .maxclock = { 191 135100, 135100, 85500, 85500, 0 192 }, 193 .init_sr07 = true, 194 .init_sr1f = false, 195 .scrn_start_bit19 = true, 196 .sr07 = 0xA0, 197 .sr07_1bpp = 0xA0, 198 .sr07_1bpp_mux = 0xA6, 199 .sr07_8bpp = 0xA1, 200 .sr07_8bpp_mux = 0xA7, 201 .sr1f = 0 202 }, 203 [BT_ALPINE] = { 204 .name = "CL Alpine", 205 .maxclock = { 206 /* for the GD5430. GD5446 can do more... */ 207 85500, 85500, 50000, 28500, 0 208 }, 209 .init_sr07 = true, 210 .init_sr1f = true, 211 .scrn_start_bit19 = true, 212 .sr07 = 0xA0, 213 .sr07_1bpp = 0xA0, 214 .sr07_1bpp_mux = 0xA6, 215 .sr07_8bpp = 0xA1, 216 .sr07_8bpp_mux = 0xA7, 217 .sr1f = 0x1C 218 }, 219 [BT_GD5480] = { 220 .name = "CL GD5480", 221 .maxclock = { 222 135100, 200000, 200000, 135100, 135100 223 }, 224 .init_sr07 = true, 225 .init_sr1f = true, 226 .scrn_start_bit19 = true, 227 .sr07 = 0x10, 228 .sr07_1bpp = 0x11, 229 .sr07_8bpp = 0x11, 230 .sr1f = 0x1C 231 }, 232 [BT_LAGUNA] = { 233 .name = "CL Laguna", 234 .maxclock = { 235 /* taken from X11 code */ 236 170000, 170000, 170000, 170000, 135100, 237 }, 238 .init_sr07 = false, 239 .init_sr1f = false, 240 .scrn_start_bit19 = true, 241 }, 242 [BT_LAGUNAB] = { 243 .name = "CL Laguna AGP", 244 .maxclock = { 245 /* taken from X11 code */ 246 170000, 250000, 170000, 170000, 135100, 247 }, 248 .init_sr07 = false, 249 .init_sr1f = false, 250 .scrn_start_bit19 = true, 251 } 252 }; 253 254 #ifdef CONFIG_PCI 255 #define CHIP(id, btype) \ 256 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } 257 258 static struct pci_device_id cirrusfb_pci_table[] = { 259 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), 260 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64), 261 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64), 262 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ 263 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), 264 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), 265 CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */ 266 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */ 267 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */ 268 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */ 269 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/ 270 { 0, } 271 }; 272 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); 273 #undef CHIP 274 #endif /* CONFIG_PCI */ 275 276 #ifdef CONFIG_ZORRO 277 struct zorrocl { 278 enum cirrus_board type; /* Board type */ 279 u32 regoffset; /* Offset of registers in first Zorro device */ 280 u32 ramsize; /* Size of video RAM in first Zorro device */ 281 /* If zero, use autoprobe on RAM device */ 282 u32 ramoffset; /* Offset of video RAM in first Zorro device */ 283 zorro_id ramid; /* Zorro ID of RAM device */ 284 zorro_id ramid2; /* Zorro ID of optional second RAM device */ 285 }; 286 287 static const struct zorrocl zcl_sd64 = { 288 .type = BT_SD64, 289 .ramid = ZORRO_PROD_HELFRICH_SD64_RAM, 290 }; 291 292 static const struct zorrocl zcl_piccolo = { 293 .type = BT_PICCOLO, 294 .ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM, 295 }; 296 297 static const struct zorrocl zcl_picasso = { 298 .type = BT_PICASSO, 299 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, 300 }; 301 302 static const struct zorrocl zcl_spectrum = { 303 .type = BT_SPECTRUM, 304 .ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, 305 }; 306 307 static const struct zorrocl zcl_picasso4_z3 = { 308 .type = BT_PICASSO4, 309 .regoffset = 0x00600000, 310 .ramsize = 4 * MB_, 311 .ramoffset = 0x01000000, /* 0x02000000 for 64 MiB boards */ 312 }; 313 314 static const struct zorrocl zcl_picasso4_z2 = { 315 .type = BT_PICASSO4, 316 .regoffset = 0x10000, 317 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1, 318 .ramid2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2, 319 }; 320 321 322 static const struct zorro_device_id cirrusfb_zorro_table[] = { 323 { 324 .id = ZORRO_PROD_HELFRICH_SD64_REG, 325 .driver_data = (unsigned long)&zcl_sd64, 326 }, { 327 .id = ZORRO_PROD_HELFRICH_PICCOLO_REG, 328 .driver_data = (unsigned long)&zcl_piccolo, 329 }, { 330 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, 331 .driver_data = (unsigned long)&zcl_picasso, 332 }, { 333 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, 334 .driver_data = (unsigned long)&zcl_spectrum, 335 }, { 336 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, 337 .driver_data = (unsigned long)&zcl_picasso4_z3, 338 }, { 339 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG, 340 .driver_data = (unsigned long)&zcl_picasso4_z2, 341 }, 342 { 0 } 343 }; 344 MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table); 345 #endif /* CONFIG_ZORRO */ 346 347 #ifdef CIRRUSFB_DEBUG 348 enum cirrusfb_dbg_reg_class { 349 CRT, 350 SEQ 351 }; 352 #endif /* CIRRUSFB_DEBUG */ 353 354 /* info about board */ 355 struct cirrusfb_info { 356 u8 __iomem *regbase; 357 u8 __iomem *laguna_mmio; 358 enum cirrus_board btype; 359 unsigned char SFR; /* Shadow of special function register */ 360 361 int multiplexing; 362 int doubleVCLK; 363 int blank_mode; 364 u32 pseudo_palette[16]; 365 366 void (*unmap)(struct fb_info *info); 367 }; 368 369 static bool noaccel; 370 static char *mode_option = "640x480@60"; 371 372 /****************************************************************************/ 373 /**** BEGIN PROTOTYPES ******************************************************/ 374 375 /*--- Interface used by the world ------------------------------------------*/ 376 static int cirrusfb_pan_display(struct fb_var_screeninfo *var, 377 struct fb_info *info); 378 379 /*--- Internal routines ----------------------------------------------------*/ 380 static void init_vgachip(struct fb_info *info); 381 static void switch_monitor(struct cirrusfb_info *cinfo, int on); 382 static void WGen(const struct cirrusfb_info *cinfo, 383 int regnum, unsigned char val); 384 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum); 385 static void AttrOn(const struct cirrusfb_info *cinfo); 386 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val); 387 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val); 388 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val); 389 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, 390 unsigned char red, unsigned char green, unsigned char blue); 391 #if 0 392 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, 393 unsigned char *red, unsigned char *green, 394 unsigned char *blue); 395 #endif 396 static void cirrusfb_WaitBLT(u8 __iomem *regbase); 397 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, 398 u_short curx, u_short cury, 399 u_short destx, u_short desty, 400 u_short width, u_short height, 401 u_short line_length); 402 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, 403 u_short x, u_short y, 404 u_short width, u_short height, 405 u32 fg_color, u32 bg_color, 406 u_short line_length, u_char blitmode); 407 408 static void bestclock(long freq, int *nom, int *den, int *div); 409 410 #ifdef CIRRUSFB_DEBUG 411 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase); 412 static void cirrusfb_dbg_print_regs(struct fb_info *info, 413 caddr_t regbase, 414 enum cirrusfb_dbg_reg_class reg_class, ...); 415 #endif /* CIRRUSFB_DEBUG */ 416 417 /*** END PROTOTYPES ********************************************************/ 418 /*****************************************************************************/ 419 /*** BEGIN Interface Used by the World ***************************************/ 420 421 static inline int is_laguna(const struct cirrusfb_info *cinfo) 422 { 423 return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB; 424 } 425 426 static int opencount; 427 428 /*--- Open /dev/fbx ---------------------------------------------------------*/ 429 static int cirrusfb_open(struct fb_info *info, int user) 430 { 431 if (opencount++ == 0) 432 switch_monitor(info->par, 1); 433 return 0; 434 } 435 436 /*--- Close /dev/fbx --------------------------------------------------------*/ 437 static int cirrusfb_release(struct fb_info *info, int user) 438 { 439 if (--opencount == 0) 440 switch_monitor(info->par, 0); 441 return 0; 442 } 443 444 /**** END Interface used by the World *************************************/ 445 /****************************************************************************/ 446 /**** BEGIN Hardware specific Routines **************************************/ 447 448 /* Check if the MCLK is not a better clock source */ 449 static int cirrusfb_check_mclk(struct fb_info *info, long freq) 450 { 451 struct cirrusfb_info *cinfo = info->par; 452 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f; 453 454 /* Read MCLK value */ 455 mclk = (14318 * mclk) >> 3; 456 dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk); 457 458 /* Determine if we should use MCLK instead of VCLK, and if so, what we 459 * should divide it by to get VCLK 460 */ 461 462 if (abs(freq - mclk) < 250) { 463 dev_dbg(info->device, "Using VCLK = MCLK\n"); 464 return 1; 465 } else if (abs(freq - (mclk / 2)) < 250) { 466 dev_dbg(info->device, "Using VCLK = MCLK/2\n"); 467 return 2; 468 } 469 470 return 0; 471 } 472 473 static int cirrusfb_check_pixclock(struct fb_var_screeninfo *var, 474 struct fb_info *info) 475 { 476 long freq; 477 long maxclock; 478 struct cirrusfb_info *cinfo = info->par; 479 unsigned maxclockidx = var->bits_per_pixel >> 3; 480 481 /* convert from ps to kHz */ 482 freq = PICOS2KHZ(var->pixclock ? : 1); 483 484 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; 485 cinfo->multiplexing = 0; 486 487 /* If the frequency is greater than we can support, we might be able 488 * to use multiplexing for the video mode */ 489 if (freq > maxclock) { 490 var->pixclock = KHZ2PICOS(maxclock); 491 492 while ((freq = PICOS2KHZ(var->pixclock)) > maxclock) 493 var->pixclock++; 494 } 495 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq); 496 497 /* 498 * Additional constraint: 8bpp uses DAC clock doubling to allow maximum 499 * pixel clock 500 */ 501 if (var->bits_per_pixel == 8) { 502 switch (cinfo->btype) { 503 case BT_ALPINE: 504 case BT_SD64: 505 case BT_PICASSO4: 506 if (freq > 85500) 507 cinfo->multiplexing = 1; 508 break; 509 case BT_GD5480: 510 if (freq > 135100) 511 cinfo->multiplexing = 1; 512 break; 513 514 default: 515 break; 516 } 517 } 518 519 /* If we have a 1MB 5434, we need to put ourselves in a mode where 520 * the VCLK is double the pixel clock. */ 521 cinfo->doubleVCLK = 0; 522 if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ && 523 var->bits_per_pixel == 16) { 524 cinfo->doubleVCLK = 1; 525 } 526 527 return 0; 528 } 529 530 static int cirrusfb_check_var(struct fb_var_screeninfo *var, 531 struct fb_info *info) 532 { 533 int yres; 534 /* memory size in pixels */ 535 unsigned int pixels; 536 struct cirrusfb_info *cinfo = info->par; 537 538 switch (var->bits_per_pixel) { 539 case 1: 540 var->red.offset = 0; 541 var->red.length = 1; 542 var->green = var->red; 543 var->blue = var->red; 544 break; 545 546 case 8: 547 var->red.offset = 0; 548 var->red.length = 8; 549 var->green = var->red; 550 var->blue = var->red; 551 break; 552 553 case 16: 554 var->red.offset = 11; 555 var->green.offset = 5; 556 var->blue.offset = 0; 557 var->red.length = 5; 558 var->green.length = 6; 559 var->blue.length = 5; 560 break; 561 562 case 24: 563 var->red.offset = 16; 564 var->green.offset = 8; 565 var->blue.offset = 0; 566 var->red.length = 8; 567 var->green.length = 8; 568 var->blue.length = 8; 569 break; 570 571 default: 572 dev_dbg(info->device, 573 "Unsupported bpp size: %d\n", var->bits_per_pixel); 574 return -EINVAL; 575 } 576 577 pixels = info->screen_size * 8 / var->bits_per_pixel; 578 if (var->xres_virtual < var->xres) 579 var->xres_virtual = var->xres; 580 /* use highest possible virtual resolution */ 581 if (var->yres_virtual == -1) { 582 var->yres_virtual = pixels / var->xres_virtual; 583 584 dev_info(info->device, 585 "virtual resolution set to maximum of %dx%d\n", 586 var->xres_virtual, var->yres_virtual); 587 } 588 if (var->yres_virtual < var->yres) 589 var->yres_virtual = var->yres; 590 591 if (var->xres_virtual * var->yres_virtual > pixels) { 592 dev_err(info->device, "mode %dx%dx%d rejected... " 593 "virtual resolution too high to fit into video memory!\n", 594 var->xres_virtual, var->yres_virtual, 595 var->bits_per_pixel); 596 return -EINVAL; 597 } 598 599 /* truncate xoffset and yoffset to maximum if too high */ 600 if (var->xoffset > var->xres_virtual - var->xres) 601 var->xoffset = var->xres_virtual - var->xres - 1; 602 if (var->yoffset > var->yres_virtual - var->yres) 603 var->yoffset = var->yres_virtual - var->yres - 1; 604 605 var->red.msb_right = 606 var->green.msb_right = 607 var->blue.msb_right = 608 var->transp.offset = 609 var->transp.length = 610 var->transp.msb_right = 0; 611 612 yres = var->yres; 613 if (var->vmode & FB_VMODE_DOUBLE) 614 yres *= 2; 615 else if (var->vmode & FB_VMODE_INTERLACED) 616 yres = (yres + 1) / 2; 617 618 if (yres >= 1280) { 619 dev_err(info->device, "ERROR: VerticalTotal >= 1280; " 620 "special treatment required! (TODO)\n"); 621 return -EINVAL; 622 } 623 624 if (cirrusfb_check_pixclock(var, info)) 625 return -EINVAL; 626 627 if (!is_laguna(cinfo)) 628 var->accel_flags = FB_ACCELF_TEXT; 629 630 return 0; 631 } 632 633 static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div) 634 { 635 struct cirrusfb_info *cinfo = info->par; 636 unsigned char old1f, old1e; 637 638 assert(cinfo != NULL); 639 old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40; 640 641 if (div) { 642 dev_dbg(info->device, "Set %s as pixclock source.\n", 643 (div == 2) ? "MCLK/2" : "MCLK"); 644 old1f |= 0x40; 645 old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1; 646 if (div == 2) 647 old1e |= 1; 648 649 vga_wseq(cinfo->regbase, CL_SEQR1E, old1e); 650 } 651 vga_wseq(cinfo->regbase, CL_SEQR1F, old1f); 652 } 653 654 /************************************************************************* 655 cirrusfb_set_par_foo() 656 657 actually writes the values for a new video mode into the hardware, 658 **************************************************************************/ 659 static int cirrusfb_set_par_foo(struct fb_info *info) 660 { 661 struct cirrusfb_info *cinfo = info->par; 662 struct fb_var_screeninfo *var = &info->var; 663 u8 __iomem *regbase = cinfo->regbase; 664 unsigned char tmp; 665 int pitch; 666 const struct cirrusfb_board_info_rec *bi; 667 int hdispend, hsyncstart, hsyncend, htotal; 668 int yres, vdispend, vsyncstart, vsyncend, vtotal; 669 long freq; 670 int nom, den, div; 671 unsigned int control = 0, format = 0, threshold = 0; 672 673 dev_dbg(info->device, "Requested mode: %dx%dx%d\n", 674 var->xres, var->yres, var->bits_per_pixel); 675 676 switch (var->bits_per_pixel) { 677 case 1: 678 info->fix.line_length = var->xres_virtual / 8; 679 info->fix.visual = FB_VISUAL_MONO10; 680 break; 681 682 case 8: 683 info->fix.line_length = var->xres_virtual; 684 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 685 break; 686 687 case 16: 688 case 24: 689 info->fix.line_length = var->xres_virtual * 690 var->bits_per_pixel >> 3; 691 info->fix.visual = FB_VISUAL_TRUECOLOR; 692 break; 693 } 694 info->fix.type = FB_TYPE_PACKED_PIXELS; 695 696 init_vgachip(info); 697 698 bi = &cirrusfb_board_info[cinfo->btype]; 699 700 hsyncstart = var->xres + var->right_margin; 701 hsyncend = hsyncstart + var->hsync_len; 702 htotal = (hsyncend + var->left_margin) / 8; 703 hdispend = var->xres / 8; 704 hsyncstart = hsyncstart / 8; 705 hsyncend = hsyncend / 8; 706 707 vdispend = var->yres; 708 vsyncstart = vdispend + var->lower_margin; 709 vsyncend = vsyncstart + var->vsync_len; 710 vtotal = vsyncend + var->upper_margin; 711 712 if (var->vmode & FB_VMODE_DOUBLE) { 713 vdispend *= 2; 714 vsyncstart *= 2; 715 vsyncend *= 2; 716 vtotal *= 2; 717 } else if (var->vmode & FB_VMODE_INTERLACED) { 718 vdispend = (vdispend + 1) / 2; 719 vsyncstart = (vsyncstart + 1) / 2; 720 vsyncend = (vsyncend + 1) / 2; 721 vtotal = (vtotal + 1) / 2; 722 } 723 yres = vdispend; 724 if (yres >= 1024) { 725 vtotal /= 2; 726 vsyncstart /= 2; 727 vsyncend /= 2; 728 vdispend /= 2; 729 } 730 731 vdispend -= 1; 732 vsyncstart -= 1; 733 vsyncend -= 1; 734 vtotal -= 2; 735 736 if (cinfo->multiplexing) { 737 htotal /= 2; 738 hsyncstart /= 2; 739 hsyncend /= 2; 740 hdispend /= 2; 741 } 742 743 htotal -= 5; 744 hdispend -= 1; 745 hsyncstart += 1; 746 hsyncend += 1; 747 748 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ 749 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ 750 751 /* if debugging is enabled, all parameters get output before writing */ 752 dev_dbg(info->device, "CRT0: %d\n", htotal); 753 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal); 754 755 dev_dbg(info->device, "CRT1: %d\n", hdispend); 756 vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend); 757 758 dev_dbg(info->device, "CRT2: %d\n", var->xres / 8); 759 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8); 760 761 /* + 128: Compatible read */ 762 dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32); 763 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, 764 128 + ((htotal + 5) % 32)); 765 766 dev_dbg(info->device, "CRT4: %d\n", hsyncstart); 767 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart); 768 769 tmp = hsyncend % 32; 770 if ((htotal + 5) & 32) 771 tmp += 128; 772 dev_dbg(info->device, "CRT5: %d\n", tmp); 773 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); 774 775 dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff); 776 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff); 777 778 tmp = 16; /* LineCompare bit #9 */ 779 if (vtotal & 256) 780 tmp |= 1; 781 if (vdispend & 256) 782 tmp |= 2; 783 if (vsyncstart & 256) 784 tmp |= 4; 785 if ((vdispend + 1) & 256) 786 tmp |= 8; 787 if (vtotal & 512) 788 tmp |= 32; 789 if (vdispend & 512) 790 tmp |= 64; 791 if (vsyncstart & 512) 792 tmp |= 128; 793 dev_dbg(info->device, "CRT7: %d\n", tmp); 794 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); 795 796 tmp = 0x40; /* LineCompare bit #8 */ 797 if ((vdispend + 1) & 512) 798 tmp |= 0x20; 799 if (var->vmode & FB_VMODE_DOUBLE) 800 tmp |= 0x80; 801 dev_dbg(info->device, "CRT9: %d\n", tmp); 802 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); 803 804 dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff); 805 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff); 806 807 dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16); 808 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32); 809 810 dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff); 811 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff); 812 813 dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff); 814 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff); 815 816 dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff); 817 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff); 818 819 dev_dbg(info->device, "CRT18: 0xff\n"); 820 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); 821 822 tmp = 0; 823 if (var->vmode & FB_VMODE_INTERLACED) 824 tmp |= 1; 825 if ((htotal + 5) & 64) 826 tmp |= 16; 827 if ((htotal + 5) & 128) 828 tmp |= 32; 829 if (vtotal & 256) 830 tmp |= 64; 831 if (vtotal & 512) 832 tmp |= 128; 833 834 dev_dbg(info->device, "CRT1a: %d\n", tmp); 835 vga_wcrt(regbase, CL_CRT1A, tmp); 836 837 freq = PICOS2KHZ(var->pixclock); 838 if (var->bits_per_pixel == 24) 839 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) 840 freq *= 3; 841 if (cinfo->multiplexing) 842 freq /= 2; 843 if (cinfo->doubleVCLK) 844 freq *= 2; 845 846 bestclock(freq, &nom, &den, &div); 847 848 dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n", 849 freq, nom, den, div); 850 851 /* set VCLK0 */ 852 /* hardware RefClock: 14.31818 MHz */ 853 /* formula: VClk = (OSC * N) / (D * (1+P)) */ 854 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ 855 856 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 || 857 cinfo->btype == BT_SD64) { 858 /* if freq is close to mclk or mclk/2 select mclk 859 * as clock source 860 */ 861 int divMCLK = cirrusfb_check_mclk(info, freq); 862 if (divMCLK) 863 nom = 0; 864 cirrusfb_set_mclk_as_source(info, divMCLK); 865 } 866 if (is_laguna(cinfo)) { 867 long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc); 868 unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407); 869 unsigned short tile_control; 870 871 if (cinfo->btype == BT_LAGUNAB) { 872 tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4); 873 tile_control &= ~0x80; 874 fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4); 875 } 876 877 fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc); 878 fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407); 879 control = fb_readw(cinfo->laguna_mmio + 0x402); 880 threshold = fb_readw(cinfo->laguna_mmio + 0xea); 881 control &= ~0x6800; 882 format = 0; 883 threshold &= 0xffc0 & 0x3fbf; 884 } 885 if (nom) { 886 tmp = den << 1; 887 if (div != 0) 888 tmp |= 1; 889 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ 890 if ((cinfo->btype == BT_SD64) || 891 (cinfo->btype == BT_ALPINE) || 892 (cinfo->btype == BT_GD5480)) 893 tmp |= 0x80; 894 895 /* Laguna chipset has reversed clock registers */ 896 if (is_laguna(cinfo)) { 897 vga_wseq(regbase, CL_SEQRE, tmp); 898 vga_wseq(regbase, CL_SEQR1E, nom); 899 } else { 900 vga_wseq(regbase, CL_SEQRE, nom); 901 vga_wseq(regbase, CL_SEQR1E, tmp); 902 } 903 } 904 905 if (yres >= 1024) 906 /* 1280x1024 */ 907 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7); 908 else 909 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit 910 * address wrap, no compat. */ 911 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3); 912 913 /* don't know if it would hurt to also program this if no interlaced */ 914 /* mode is used, but I feel better this way.. :-) */ 915 if (var->vmode & FB_VMODE_INTERLACED) 916 vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2); 917 else 918 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ 919 920 /* adjust horizontal/vertical sync type (low/high), use VCLK3 */ 921 /* enable display memory & CRTC I/O address for color mode */ 922 tmp = 0x03 | 0xc; 923 if (var->sync & FB_SYNC_HOR_HIGH_ACT) 924 tmp |= 0x40; 925 if (var->sync & FB_SYNC_VERT_HIGH_ACT) 926 tmp |= 0x80; 927 WGen(cinfo, VGA_MIS_W, tmp); 928 929 /* text cursor on and start line */ 930 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0); 931 /* text cursor end line */ 932 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31); 933 934 /****************************************************** 935 * 936 * 1 bpp 937 * 938 */ 939 940 /* programming for different color depths */ 941 if (var->bits_per_pixel == 1) { 942 dev_dbg(info->device, "preparing for 1 bit deep display\n"); 943 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */ 944 945 /* SR07 */ 946 switch (cinfo->btype) { 947 case BT_SD64: 948 case BT_PICCOLO: 949 case BT_PICASSO: 950 case BT_SPECTRUM: 951 case BT_PICASSO4: 952 case BT_ALPINE: 953 case BT_GD5480: 954 vga_wseq(regbase, CL_SEQR7, 955 cinfo->multiplexing ? 956 bi->sr07_1bpp_mux : bi->sr07_1bpp); 957 break; 958 959 case BT_LAGUNA: 960 case BT_LAGUNAB: 961 vga_wseq(regbase, CL_SEQR7, 962 vga_rseq(regbase, CL_SEQR7) & ~0x01); 963 break; 964 965 default: 966 dev_warn(info->device, "unknown Board\n"); 967 break; 968 } 969 970 /* Extended Sequencer Mode */ 971 switch (cinfo->btype) { 972 973 case BT_PICCOLO: 974 case BT_SPECTRUM: 975 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */ 976 vga_wseq(regbase, CL_SEQRF, 0xb0); 977 break; 978 979 case BT_PICASSO: 980 /* ## vorher d0 avoid FIFO underruns..? */ 981 vga_wseq(regbase, CL_SEQRF, 0xd0); 982 break; 983 984 case BT_SD64: 985 case BT_PICASSO4: 986 case BT_ALPINE: 987 case BT_GD5480: 988 case BT_LAGUNA: 989 case BT_LAGUNAB: 990 /* do nothing */ 991 break; 992 993 default: 994 dev_warn(info->device, "unknown Board\n"); 995 break; 996 } 997 998 /* pixel mask: pass-through for first plane */ 999 WGen(cinfo, VGA_PEL_MSK, 0x01); 1000 if (cinfo->multiplexing) 1001 /* hidden dac reg: 1280x1024 */ 1002 WHDR(cinfo, 0x4a); 1003 else 1004 /* hidden dac: nothing */ 1005 WHDR(cinfo, 0); 1006 /* memory mode: odd/even, ext. memory */ 1007 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06); 1008 /* plane mask: only write to first plane */ 1009 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01); 1010 } 1011 1012 /****************************************************** 1013 * 1014 * 8 bpp 1015 * 1016 */ 1017 1018 else if (var->bits_per_pixel == 8) { 1019 dev_dbg(info->device, "preparing for 8 bit deep display\n"); 1020 switch (cinfo->btype) { 1021 case BT_SD64: 1022 case BT_PICCOLO: 1023 case BT_PICASSO: 1024 case BT_SPECTRUM: 1025 case BT_PICASSO4: 1026 case BT_ALPINE: 1027 case BT_GD5480: 1028 vga_wseq(regbase, CL_SEQR7, 1029 cinfo->multiplexing ? 1030 bi->sr07_8bpp_mux : bi->sr07_8bpp); 1031 break; 1032 1033 case BT_LAGUNA: 1034 case BT_LAGUNAB: 1035 vga_wseq(regbase, CL_SEQR7, 1036 vga_rseq(regbase, CL_SEQR7) | 0x01); 1037 threshold |= 0x10; 1038 break; 1039 1040 default: 1041 dev_warn(info->device, "unknown Board\n"); 1042 break; 1043 } 1044 1045 switch (cinfo->btype) { 1046 case BT_PICCOLO: 1047 case BT_PICASSO: 1048 case BT_SPECTRUM: 1049 /* Fast Page-Mode writes */ 1050 vga_wseq(regbase, CL_SEQRF, 0xb0); 1051 break; 1052 1053 case BT_PICASSO4: 1054 #ifdef CONFIG_ZORRO 1055 /* ### INCOMPLETE!! */ 1056 vga_wseq(regbase, CL_SEQRF, 0xb8); 1057 #endif 1058 case BT_ALPINE: 1059 case BT_SD64: 1060 case BT_GD5480: 1061 case BT_LAGUNA: 1062 case BT_LAGUNAB: 1063 /* do nothing */ 1064 break; 1065 1066 default: 1067 dev_warn(info->device, "unknown board\n"); 1068 break; 1069 } 1070 1071 /* mode register: 256 color mode */ 1072 vga_wgfx(regbase, VGA_GFX_MODE, 64); 1073 if (cinfo->multiplexing) 1074 /* hidden dac reg: 1280x1024 */ 1075 WHDR(cinfo, 0x4a); 1076 else 1077 /* hidden dac: nothing */ 1078 WHDR(cinfo, 0); 1079 } 1080 1081 /****************************************************** 1082 * 1083 * 16 bpp 1084 * 1085 */ 1086 1087 else if (var->bits_per_pixel == 16) { 1088 dev_dbg(info->device, "preparing for 16 bit deep display\n"); 1089 switch (cinfo->btype) { 1090 case BT_PICCOLO: 1091 case BT_SPECTRUM: 1092 vga_wseq(regbase, CL_SEQR7, 0x87); 1093 /* Fast Page-Mode writes */ 1094 vga_wseq(regbase, CL_SEQRF, 0xb0); 1095 break; 1096 1097 case BT_PICASSO: 1098 vga_wseq(regbase, CL_SEQR7, 0x27); 1099 /* Fast Page-Mode writes */ 1100 vga_wseq(regbase, CL_SEQRF, 0xb0); 1101 break; 1102 1103 case BT_SD64: 1104 case BT_PICASSO4: 1105 case BT_ALPINE: 1106 /* Extended Sequencer Mode: 256c col. mode */ 1107 vga_wseq(regbase, CL_SEQR7, 1108 cinfo->doubleVCLK ? 0xa3 : 0xa7); 1109 break; 1110 1111 case BT_GD5480: 1112 vga_wseq(regbase, CL_SEQR7, 0x17); 1113 /* We already set SRF and SR1F */ 1114 break; 1115 1116 case BT_LAGUNA: 1117 case BT_LAGUNAB: 1118 vga_wseq(regbase, CL_SEQR7, 1119 vga_rseq(regbase, CL_SEQR7) & ~0x01); 1120 control |= 0x2000; 1121 format |= 0x1400; 1122 threshold |= 0x10; 1123 break; 1124 1125 default: 1126 dev_warn(info->device, "unknown Board\n"); 1127 break; 1128 } 1129 1130 /* mode register: 256 color mode */ 1131 vga_wgfx(regbase, VGA_GFX_MODE, 64); 1132 #ifdef CONFIG_PCI 1133 WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1); 1134 #elif defined(CONFIG_ZORRO) 1135 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ 1136 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */ 1137 #endif 1138 } 1139 1140 /****************************************************** 1141 * 1142 * 24 bpp 1143 * 1144 */ 1145 1146 else if (var->bits_per_pixel == 24) { 1147 dev_dbg(info->device, "preparing for 24 bit deep display\n"); 1148 switch (cinfo->btype) { 1149 case BT_PICCOLO: 1150 case BT_SPECTRUM: 1151 vga_wseq(regbase, CL_SEQR7, 0x85); 1152 /* Fast Page-Mode writes */ 1153 vga_wseq(regbase, CL_SEQRF, 0xb0); 1154 break; 1155 1156 case BT_PICASSO: 1157 vga_wseq(regbase, CL_SEQR7, 0x25); 1158 /* Fast Page-Mode writes */ 1159 vga_wseq(regbase, CL_SEQRF, 0xb0); 1160 break; 1161 1162 case BT_SD64: 1163 case BT_PICASSO4: 1164 case BT_ALPINE: 1165 /* Extended Sequencer Mode: 256c col. mode */ 1166 vga_wseq(regbase, CL_SEQR7, 0xa5); 1167 break; 1168 1169 case BT_GD5480: 1170 vga_wseq(regbase, CL_SEQR7, 0x15); 1171 /* We already set SRF and SR1F */ 1172 break; 1173 1174 case BT_LAGUNA: 1175 case BT_LAGUNAB: 1176 vga_wseq(regbase, CL_SEQR7, 1177 vga_rseq(regbase, CL_SEQR7) & ~0x01); 1178 control |= 0x4000; 1179 format |= 0x2400; 1180 threshold |= 0x20; 1181 break; 1182 1183 default: 1184 dev_warn(info->device, "unknown Board\n"); 1185 break; 1186 } 1187 1188 /* mode register: 256 color mode */ 1189 vga_wgfx(regbase, VGA_GFX_MODE, 64); 1190 /* hidden dac reg: 8-8-8 mode (24 or 32) */ 1191 WHDR(cinfo, 0xc5); 1192 } 1193 1194 /****************************************************** 1195 * 1196 * unknown/unsupported bpp 1197 * 1198 */ 1199 1200 else 1201 dev_err(info->device, 1202 "What's this? requested color depth == %d.\n", 1203 var->bits_per_pixel); 1204 1205 pitch = info->fix.line_length >> 3; 1206 vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff); 1207 tmp = 0x22; 1208 if (pitch & 0x100) 1209 tmp |= 0x10; /* offset overflow bit */ 1210 1211 /* screen start addr #16-18, fastpagemode cycles */ 1212 vga_wcrt(regbase, CL_CRT1B, tmp); 1213 1214 /* screen start address bit 19 */ 1215 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) 1216 vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1); 1217 1218 if (is_laguna(cinfo)) { 1219 tmp = 0; 1220 if ((htotal + 5) & 256) 1221 tmp |= 128; 1222 if (hdispend & 256) 1223 tmp |= 64; 1224 if (hsyncstart & 256) 1225 tmp |= 48; 1226 if (vtotal & 1024) 1227 tmp |= 8; 1228 if (vdispend & 1024) 1229 tmp |= 4; 1230 if (vsyncstart & 1024) 1231 tmp |= 3; 1232 1233 vga_wcrt(regbase, CL_CRT1E, tmp); 1234 dev_dbg(info->device, "CRT1e: %d\n", tmp); 1235 } 1236 1237 /* pixel panning */ 1238 vga_wattr(regbase, CL_AR33, 0); 1239 1240 /* [ EGS: SetOffset(); ] */ 1241 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */ 1242 AttrOn(cinfo); 1243 1244 if (is_laguna(cinfo)) { 1245 /* no tiles */ 1246 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402); 1247 fb_writew(format, cinfo->laguna_mmio + 0xc0); 1248 fb_writew(threshold, cinfo->laguna_mmio + 0xea); 1249 } 1250 /* finally, turn on everything - turn off "FullBandwidth" bit */ 1251 /* also, set "DotClock%2" bit where requested */ 1252 tmp = 0x01; 1253 1254 /*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ? 1255 if (var->vmode & FB_VMODE_CLOCK_HALVE) 1256 tmp |= 0x08; 1257 */ 1258 1259 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp); 1260 dev_dbg(info->device, "CL_SEQR1: %d\n", tmp); 1261 1262 #ifdef CIRRUSFB_DEBUG 1263 cirrusfb_dbg_reg_dump(info, NULL); 1264 #endif 1265 1266 return 0; 1267 } 1268 1269 /* for some reason incomprehensible to me, cirrusfb requires that you write 1270 * the registers twice for the settings to take..grr. -dte */ 1271 static int cirrusfb_set_par(struct fb_info *info) 1272 { 1273 cirrusfb_set_par_foo(info); 1274 return cirrusfb_set_par_foo(info); 1275 } 1276 1277 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1278 unsigned blue, unsigned transp, 1279 struct fb_info *info) 1280 { 1281 struct cirrusfb_info *cinfo = info->par; 1282 1283 if (regno > 255) 1284 return -EINVAL; 1285 1286 if (info->fix.visual == FB_VISUAL_TRUECOLOR) { 1287 u32 v; 1288 red >>= (16 - info->var.red.length); 1289 green >>= (16 - info->var.green.length); 1290 blue >>= (16 - info->var.blue.length); 1291 1292 if (regno >= 16) 1293 return 1; 1294 v = (red << info->var.red.offset) | 1295 (green << info->var.green.offset) | 1296 (blue << info->var.blue.offset); 1297 1298 cinfo->pseudo_palette[regno] = v; 1299 return 0; 1300 } 1301 1302 if (info->var.bits_per_pixel == 8) 1303 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10); 1304 1305 return 0; 1306 1307 } 1308 1309 /************************************************************************* 1310 cirrusfb_pan_display() 1311 1312 performs display panning - provided hardware permits this 1313 **************************************************************************/ 1314 static int cirrusfb_pan_display(struct fb_var_screeninfo *var, 1315 struct fb_info *info) 1316 { 1317 int xoffset; 1318 unsigned long base; 1319 unsigned char tmp, xpix; 1320 struct cirrusfb_info *cinfo = info->par; 1321 1322 /* no range checks for xoffset and yoffset, */ 1323 /* as fb_pan_display has already done this */ 1324 if (var->vmode & FB_VMODE_YWRAP) 1325 return -EINVAL; 1326 1327 xoffset = var->xoffset * info->var.bits_per_pixel / 8; 1328 1329 base = var->yoffset * info->fix.line_length + xoffset; 1330 1331 if (info->var.bits_per_pixel == 1) { 1332 /* base is already correct */ 1333 xpix = (unsigned char) (var->xoffset % 8); 1334 } else { 1335 base /= 4; 1336 xpix = (unsigned char) ((xoffset % 4) * 2); 1337 } 1338 1339 if (!is_laguna(cinfo)) 1340 cirrusfb_WaitBLT(cinfo->regbase); 1341 1342 /* lower 8 + 8 bits of screen start address */ 1343 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff); 1344 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff); 1345 1346 /* 0xf2 is %11110010, exclude tmp bits */ 1347 tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2; 1348 /* construct bits 16, 17 and 18 of screen start address */ 1349 if (base & 0x10000) 1350 tmp |= 0x01; 1351 if (base & 0x20000) 1352 tmp |= 0x04; 1353 if (base & 0x40000) 1354 tmp |= 0x08; 1355 1356 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp); 1357 1358 /* construct bit 19 of screen start address */ 1359 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) { 1360 tmp = vga_rcrt(cinfo->regbase, CL_CRT1D); 1361 if (is_laguna(cinfo)) 1362 tmp = (tmp & ~0x18) | ((base >> 16) & 0x18); 1363 else 1364 tmp = (tmp & ~0x80) | ((base >> 12) & 0x80); 1365 vga_wcrt(cinfo->regbase, CL_CRT1D, tmp); 1366 } 1367 1368 /* write pixel panning value to AR33; this does not quite work in 8bpp 1369 * 1370 * ### Piccolo..? Will this work? 1371 */ 1372 if (info->var.bits_per_pixel == 1) 1373 vga_wattr(cinfo->regbase, CL_AR33, xpix); 1374 1375 return 0; 1376 } 1377 1378 static int cirrusfb_blank(int blank_mode, struct fb_info *info) 1379 { 1380 /* 1381 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL 1382 * then the caller blanks by setting the CLUT (Color Look Up Table) 1383 * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking 1384 * failed due to e.g. a video mode which doesn't support it. 1385 * Implements VESA suspend and powerdown modes on hardware that 1386 * supports disabling hsync/vsync: 1387 * blank_mode == 2: suspend vsync 1388 * blank_mode == 3: suspend hsync 1389 * blank_mode == 4: powerdown 1390 */ 1391 unsigned char val; 1392 struct cirrusfb_info *cinfo = info->par; 1393 int current_mode = cinfo->blank_mode; 1394 1395 dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode); 1396 1397 if (info->state != FBINFO_STATE_RUNNING || 1398 current_mode == blank_mode) { 1399 dev_dbg(info->device, "EXIT, returning 0\n"); 1400 return 0; 1401 } 1402 1403 /* Undo current */ 1404 if (current_mode == FB_BLANK_NORMAL || 1405 current_mode == FB_BLANK_UNBLANK) 1406 /* clear "FullBandwidth" bit */ 1407 val = 0; 1408 else 1409 /* set "FullBandwidth" bit */ 1410 val = 0x20; 1411 1412 val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf; 1413 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val); 1414 1415 switch (blank_mode) { 1416 case FB_BLANK_UNBLANK: 1417 case FB_BLANK_NORMAL: 1418 val = 0x00; 1419 break; 1420 case FB_BLANK_VSYNC_SUSPEND: 1421 val = 0x04; 1422 break; 1423 case FB_BLANK_HSYNC_SUSPEND: 1424 val = 0x02; 1425 break; 1426 case FB_BLANK_POWERDOWN: 1427 val = 0x06; 1428 break; 1429 default: 1430 dev_dbg(info->device, "EXIT, returning 1\n"); 1431 return 1; 1432 } 1433 1434 vga_wgfx(cinfo->regbase, CL_GRE, val); 1435 1436 cinfo->blank_mode = blank_mode; 1437 dev_dbg(info->device, "EXIT, returning 0\n"); 1438 1439 /* Let fbcon do a soft blank for us */ 1440 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; 1441 } 1442 1443 /**** END Hardware specific Routines **************************************/ 1444 /****************************************************************************/ 1445 /**** BEGIN Internal Routines ***********************************************/ 1446 1447 static void init_vgachip(struct fb_info *info) 1448 { 1449 struct cirrusfb_info *cinfo = info->par; 1450 const struct cirrusfb_board_info_rec *bi; 1451 1452 assert(cinfo != NULL); 1453 1454 bi = &cirrusfb_board_info[cinfo->btype]; 1455 1456 /* reset board globally */ 1457 switch (cinfo->btype) { 1458 case BT_PICCOLO: 1459 WSFR(cinfo, 0x01); 1460 udelay(500); 1461 WSFR(cinfo, 0x51); 1462 udelay(500); 1463 break; 1464 case BT_PICASSO: 1465 WSFR2(cinfo, 0xff); 1466 udelay(500); 1467 break; 1468 case BT_SD64: 1469 case BT_SPECTRUM: 1470 WSFR(cinfo, 0x1f); 1471 udelay(500); 1472 WSFR(cinfo, 0x4f); 1473 udelay(500); 1474 break; 1475 case BT_PICASSO4: 1476 /* disable flickerfixer */ 1477 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00); 1478 mdelay(100); 1479 /* mode */ 1480 vga_wgfx(cinfo->regbase, CL_GR31, 0x00); 1481 fallthrough; 1482 case BT_GD5480: 1483 /* from Klaus' NetBSD driver: */ 1484 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); 1485 fallthrough; 1486 case BT_ALPINE: 1487 /* put blitter into 542x compat */ 1488 vga_wgfx(cinfo->regbase, CL_GR33, 0x00); 1489 break; 1490 1491 case BT_LAGUNA: 1492 case BT_LAGUNAB: 1493 /* Nothing to do to reset the board. */ 1494 break; 1495 1496 default: 1497 dev_err(info->device, "Warning: Unknown board type\n"); 1498 break; 1499 } 1500 1501 /* make sure RAM size set by this point */ 1502 assert(info->screen_size > 0); 1503 1504 /* the P4 is not fully initialized here; I rely on it having been */ 1505 /* inited under AmigaOS already, which seems to work just fine */ 1506 /* (Klaus advised to do it this way) */ 1507 1508 if (cinfo->btype != BT_PICASSO4) { 1509 WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */ 1510 WGen(cinfo, CL_POS102, 0x01); 1511 WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */ 1512 1513 if (cinfo->btype != BT_SD64) 1514 WGen(cinfo, CL_VSSM2, 0x01); 1515 1516 /* reset sequencer logic */ 1517 vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03); 1518 1519 /* FullBandwidth (video off) and 8/9 dot clock */ 1520 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); 1521 1522 /* "magic cookie" - doesn't make any sense to me.. */ 1523 /* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */ 1524 /* unlock all extension registers */ 1525 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12); 1526 1527 switch (cinfo->btype) { 1528 case BT_GD5480: 1529 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98); 1530 break; 1531 case BT_ALPINE: 1532 case BT_LAGUNA: 1533 case BT_LAGUNAB: 1534 break; 1535 case BT_SD64: 1536 #ifdef CONFIG_ZORRO 1537 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); 1538 #endif 1539 break; 1540 default: 1541 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); 1542 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0); 1543 break; 1544 } 1545 } 1546 /* plane mask: nothing */ 1547 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); 1548 /* character map select: doesn't even matter in gx mode */ 1549 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); 1550 /* memory mode: chain4, ext. memory */ 1551 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a); 1552 1553 /* controller-internal base address of video memory */ 1554 if (bi->init_sr07) 1555 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07); 1556 1557 /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */ 1558 /* EEPROM control: shouldn't be necessary to write to this at all.. */ 1559 1560 /* graphics cursor X position (incomplete; position gives rem. 3 bits */ 1561 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00); 1562 /* graphics cursor Y position (..."... ) */ 1563 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00); 1564 /* graphics cursor attributes */ 1565 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00); 1566 /* graphics cursor pattern address */ 1567 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00); 1568 1569 /* writing these on a P4 might give problems.. */ 1570 if (cinfo->btype != BT_PICASSO4) { 1571 /* configuration readback and ext. color */ 1572 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00); 1573 /* signature generator */ 1574 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02); 1575 } 1576 1577 /* Screen A preset row scan: none */ 1578 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); 1579 /* Text cursor start: disable text cursor */ 1580 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); 1581 /* Text cursor end: - */ 1582 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); 1583 /* text cursor location high: 0 */ 1584 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); 1585 /* text cursor location low: 0 */ 1586 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00); 1587 1588 /* Underline Row scanline: - */ 1589 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); 1590 /* ### add 0x40 for text modes with > 30 MHz pixclock */ 1591 /* ext. display controls: ext.adr. wrap */ 1592 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); 1593 1594 /* Set/Reset registers: - */ 1595 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00); 1596 /* Set/Reset enable: - */ 1597 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00); 1598 /* Color Compare: - */ 1599 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00); 1600 /* Data Rotate: - */ 1601 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00); 1602 /* Read Map Select: - */ 1603 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00); 1604 /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */ 1605 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00); 1606 /* Miscellaneous: memory map base address, graphics mode */ 1607 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01); 1608 /* Color Don't care: involve all planes */ 1609 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); 1610 /* Bit Mask: no mask at all */ 1611 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); 1612 1613 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 || 1614 is_laguna(cinfo)) 1615 /* (5434 can't have bit 3 set for bitblt) */ 1616 vga_wgfx(cinfo->regbase, CL_GRB, 0x20); 1617 else 1618 /* Graphics controller mode extensions: finer granularity, 1619 * 8byte data latches 1620 */ 1621 vga_wgfx(cinfo->regbase, CL_GRB, 0x28); 1622 1623 vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */ 1624 vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */ 1625 vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */ 1626 /* Background color byte 1: - */ 1627 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */ 1628 /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */ 1629 1630 /* Attribute Controller palette registers: "identity mapping" */ 1631 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00); 1632 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01); 1633 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02); 1634 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03); 1635 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04); 1636 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05); 1637 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06); 1638 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07); 1639 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08); 1640 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09); 1641 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a); 1642 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b); 1643 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c); 1644 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d); 1645 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e); 1646 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f); 1647 1648 /* Attribute Controller mode: graphics mode */ 1649 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01); 1650 /* Overscan color reg.: reg. 0 */ 1651 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); 1652 /* Color Plane enable: Enable all 4 planes */ 1653 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); 1654 /* Color Select: - */ 1655 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); 1656 1657 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ 1658 1659 /* BLT Start/status: Blitter reset */ 1660 vga_wgfx(cinfo->regbase, CL_GR31, 0x04); 1661 /* - " - : "end-of-reset" */ 1662 vga_wgfx(cinfo->regbase, CL_GR31, 0x00); 1663 1664 /* misc... */ 1665 WHDR(cinfo, 0); /* Hidden DAC register: - */ 1666 return; 1667 } 1668 1669 static void switch_monitor(struct cirrusfb_info *cinfo, int on) 1670 { 1671 #ifdef CONFIG_ZORRO /* only works on Zorro boards */ 1672 static int IsOn = 0; /* XXX not ok for multiple boards */ 1673 1674 if (cinfo->btype == BT_PICASSO4) 1675 return; /* nothing to switch */ 1676 if (cinfo->btype == BT_ALPINE) 1677 return; /* nothing to switch */ 1678 if (cinfo->btype == BT_GD5480) 1679 return; /* nothing to switch */ 1680 if (cinfo->btype == BT_PICASSO) { 1681 if ((on && !IsOn) || (!on && IsOn)) 1682 WSFR(cinfo, 0xff); 1683 return; 1684 } 1685 if (on) { 1686 switch (cinfo->btype) { 1687 case BT_SD64: 1688 WSFR(cinfo, cinfo->SFR | 0x21); 1689 break; 1690 case BT_PICCOLO: 1691 WSFR(cinfo, cinfo->SFR | 0x28); 1692 break; 1693 case BT_SPECTRUM: 1694 WSFR(cinfo, 0x6f); 1695 break; 1696 default: /* do nothing */ break; 1697 } 1698 } else { 1699 switch (cinfo->btype) { 1700 case BT_SD64: 1701 WSFR(cinfo, cinfo->SFR & 0xde); 1702 break; 1703 case BT_PICCOLO: 1704 WSFR(cinfo, cinfo->SFR & 0xd7); 1705 break; 1706 case BT_SPECTRUM: 1707 WSFR(cinfo, 0x4f); 1708 break; 1709 default: /* do nothing */ 1710 break; 1711 } 1712 } 1713 #endif /* CONFIG_ZORRO */ 1714 } 1715 1716 /******************************************/ 1717 /* Linux 2.6-style accelerated functions */ 1718 /******************************************/ 1719 1720 static int cirrusfb_sync(struct fb_info *info) 1721 { 1722 struct cirrusfb_info *cinfo = info->par; 1723 1724 if (!is_laguna(cinfo)) { 1725 while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03) 1726 cpu_relax(); 1727 } 1728 return 0; 1729 } 1730 1731 static void cirrusfb_fillrect(struct fb_info *info, 1732 const struct fb_fillrect *region) 1733 { 1734 struct fb_fillrect modded; 1735 int vxres, vyres; 1736 struct cirrusfb_info *cinfo = info->par; 1737 int m = info->var.bits_per_pixel; 1738 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? 1739 cinfo->pseudo_palette[region->color] : region->color; 1740 1741 if (info->state != FBINFO_STATE_RUNNING) 1742 return; 1743 if (info->flags & FBINFO_HWACCEL_DISABLED) { 1744 cfb_fillrect(info, region); 1745 return; 1746 } 1747 1748 vxres = info->var.xres_virtual; 1749 vyres = info->var.yres_virtual; 1750 1751 memcpy(&modded, region, sizeof(struct fb_fillrect)); 1752 1753 if (!modded.width || !modded.height || 1754 modded.dx >= vxres || modded.dy >= vyres) 1755 return; 1756 1757 if (modded.dx + modded.width > vxres) 1758 modded.width = vxres - modded.dx; 1759 if (modded.dy + modded.height > vyres) 1760 modded.height = vyres - modded.dy; 1761 1762 cirrusfb_RectFill(cinfo->regbase, 1763 info->var.bits_per_pixel, 1764 (region->dx * m) / 8, region->dy, 1765 (region->width * m) / 8, region->height, 1766 color, color, 1767 info->fix.line_length, 0x40); 1768 } 1769 1770 static void cirrusfb_copyarea(struct fb_info *info, 1771 const struct fb_copyarea *area) 1772 { 1773 struct fb_copyarea modded; 1774 u32 vxres, vyres; 1775 struct cirrusfb_info *cinfo = info->par; 1776 int m = info->var.bits_per_pixel; 1777 1778 if (info->state != FBINFO_STATE_RUNNING) 1779 return; 1780 if (info->flags & FBINFO_HWACCEL_DISABLED) { 1781 cfb_copyarea(info, area); 1782 return; 1783 } 1784 1785 vxres = info->var.xres_virtual; 1786 vyres = info->var.yres_virtual; 1787 memcpy(&modded, area, sizeof(struct fb_copyarea)); 1788 1789 if (!modded.width || !modded.height || 1790 modded.sx >= vxres || modded.sy >= vyres || 1791 modded.dx >= vxres || modded.dy >= vyres) 1792 return; 1793 1794 if (modded.sx + modded.width > vxres) 1795 modded.width = vxres - modded.sx; 1796 if (modded.dx + modded.width > vxres) 1797 modded.width = vxres - modded.dx; 1798 if (modded.sy + modded.height > vyres) 1799 modded.height = vyres - modded.sy; 1800 if (modded.dy + modded.height > vyres) 1801 modded.height = vyres - modded.dy; 1802 1803 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel, 1804 (area->sx * m) / 8, area->sy, 1805 (area->dx * m) / 8, area->dy, 1806 (area->width * m) / 8, area->height, 1807 info->fix.line_length); 1808 1809 } 1810 1811 static void cirrusfb_imageblit(struct fb_info *info, 1812 const struct fb_image *image) 1813 { 1814 struct cirrusfb_info *cinfo = info->par; 1815 unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4; 1816 1817 if (info->state != FBINFO_STATE_RUNNING) 1818 return; 1819 /* Alpine/SD64 does not work at 24bpp ??? */ 1820 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) 1821 cfb_imageblit(info, image); 1822 else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) && 1823 op == 0xc) 1824 cfb_imageblit(info, image); 1825 else { 1826 unsigned size = ((image->width + 7) >> 3) * image->height; 1827 int m = info->var.bits_per_pixel; 1828 u32 fg, bg; 1829 1830 if (info->var.bits_per_pixel == 8) { 1831 fg = image->fg_color; 1832 bg = image->bg_color; 1833 } else { 1834 fg = ((u32 *)(info->pseudo_palette))[image->fg_color]; 1835 bg = ((u32 *)(info->pseudo_palette))[image->bg_color]; 1836 } 1837 if (info->var.bits_per_pixel == 24) { 1838 /* clear background first */ 1839 cirrusfb_RectFill(cinfo->regbase, 1840 info->var.bits_per_pixel, 1841 (image->dx * m) / 8, image->dy, 1842 (image->width * m) / 8, 1843 image->height, 1844 bg, bg, 1845 info->fix.line_length, 0x40); 1846 } 1847 cirrusfb_RectFill(cinfo->regbase, 1848 info->var.bits_per_pixel, 1849 (image->dx * m) / 8, image->dy, 1850 (image->width * m) / 8, image->height, 1851 fg, bg, 1852 info->fix.line_length, op); 1853 memcpy(info->screen_base, image->data, size); 1854 } 1855 } 1856 1857 #ifdef CONFIG_PCI 1858 static int release_io_ports; 1859 1860 /* Pulled the logic from XFree86 Cirrus driver to get the memory size, 1861 * based on the DRAM bandwidth bit and DRAM bank switching bit. This 1862 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards 1863 * seem to have. */ 1864 static unsigned int cirrusfb_get_memsize(struct fb_info *info, 1865 u8 __iomem *regbase) 1866 { 1867 unsigned long mem; 1868 struct cirrusfb_info *cinfo = info->par; 1869 1870 if (is_laguna(cinfo)) { 1871 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14); 1872 1873 mem = ((SR14 & 7) + 1) << 20; 1874 } else { 1875 unsigned char SRF = vga_rseq(regbase, CL_SEQRF); 1876 switch ((SRF & 0x18)) { 1877 case 0x08: 1878 mem = 512 * 1024; 1879 break; 1880 case 0x10: 1881 mem = 1024 * 1024; 1882 break; 1883 /* 64-bit DRAM data bus width; assume 2MB. 1884 * Also indicates 2MB memory on the 5430. 1885 */ 1886 case 0x18: 1887 mem = 2048 * 1024; 1888 break; 1889 default: 1890 dev_warn(info->device, "Unknown memory size!\n"); 1891 mem = 1024 * 1024; 1892 } 1893 /* If DRAM bank switching is enabled, there must be 1894 * twice as much memory installed. (4MB on the 5434) 1895 */ 1896 if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0) 1897 mem *= 2; 1898 } 1899 1900 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */ 1901 return mem; 1902 } 1903 1904 static void get_pci_addrs(const struct pci_dev *pdev, 1905 unsigned long *display, unsigned long *registers) 1906 { 1907 assert(pdev != NULL); 1908 assert(display != NULL); 1909 assert(registers != NULL); 1910 1911 *display = 0; 1912 *registers = 0; 1913 1914 /* This is a best-guess for now */ 1915 1916 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { 1917 *display = pci_resource_start(pdev, 1); 1918 *registers = pci_resource_start(pdev, 0); 1919 } else { 1920 *display = pci_resource_start(pdev, 0); 1921 *registers = pci_resource_start(pdev, 1); 1922 } 1923 1924 assert(*display != 0); 1925 } 1926 1927 static void cirrusfb_pci_unmap(struct fb_info *info) 1928 { 1929 struct pci_dev *pdev = to_pci_dev(info->device); 1930 struct cirrusfb_info *cinfo = info->par; 1931 1932 if (cinfo->laguna_mmio == NULL) 1933 iounmap(cinfo->laguna_mmio); 1934 iounmap(info->screen_base); 1935 #if 0 /* if system didn't claim this region, we would... */ 1936 release_mem_region(0xA0000, 65535); 1937 #endif 1938 if (release_io_ports) 1939 release_region(0x3C0, 32); 1940 pci_release_regions(pdev); 1941 } 1942 #endif /* CONFIG_PCI */ 1943 1944 #ifdef CONFIG_ZORRO 1945 static void cirrusfb_zorro_unmap(struct fb_info *info) 1946 { 1947 struct cirrusfb_info *cinfo = info->par; 1948 struct zorro_dev *zdev = to_zorro_dev(info->device); 1949 1950 if (info->fix.smem_start > 16 * MB_) 1951 iounmap(info->screen_base); 1952 if (info->fix.mmio_start > 16 * MB_) 1953 iounmap(cinfo->regbase); 1954 1955 zorro_release_device(zdev); 1956 } 1957 #endif /* CONFIG_ZORRO */ 1958 1959 /* function table of the above functions */ 1960 static const struct fb_ops cirrusfb_ops = { 1961 .owner = THIS_MODULE, 1962 .fb_open = cirrusfb_open, 1963 .fb_release = cirrusfb_release, 1964 .fb_setcolreg = cirrusfb_setcolreg, 1965 .fb_check_var = cirrusfb_check_var, 1966 .fb_set_par = cirrusfb_set_par, 1967 .fb_pan_display = cirrusfb_pan_display, 1968 .fb_blank = cirrusfb_blank, 1969 .fb_fillrect = cirrusfb_fillrect, 1970 .fb_copyarea = cirrusfb_copyarea, 1971 .fb_sync = cirrusfb_sync, 1972 .fb_imageblit = cirrusfb_imageblit, 1973 }; 1974 1975 static int cirrusfb_set_fbinfo(struct fb_info *info) 1976 { 1977 struct cirrusfb_info *cinfo = info->par; 1978 struct fb_var_screeninfo *var = &info->var; 1979 1980 info->pseudo_palette = cinfo->pseudo_palette; 1981 info->flags = FBINFO_HWACCEL_XPAN 1982 | FBINFO_HWACCEL_YPAN 1983 | FBINFO_HWACCEL_FILLRECT 1984 | FBINFO_HWACCEL_IMAGEBLIT 1985 | FBINFO_HWACCEL_COPYAREA; 1986 if (noaccel || is_laguna(cinfo)) { 1987 info->flags |= FBINFO_HWACCEL_DISABLED; 1988 info->fix.accel = FB_ACCEL_NONE; 1989 } else 1990 info->fix.accel = FB_ACCEL_CIRRUS_ALPINE; 1991 1992 info->fbops = &cirrusfb_ops; 1993 1994 if (cinfo->btype == BT_GD5480) { 1995 if (var->bits_per_pixel == 16) 1996 info->screen_base += 1 * MB_; 1997 if (var->bits_per_pixel == 32) 1998 info->screen_base += 2 * MB_; 1999 } 2000 2001 /* Fill fix common fields */ 2002 strscpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name, 2003 sizeof(info->fix.id)); 2004 2005 /* monochrome: only 1 memory plane */ 2006 /* 8 bit and above: Use whole memory area */ 2007 info->fix.smem_len = info->screen_size; 2008 if (var->bits_per_pixel == 1) 2009 info->fix.smem_len /= 4; 2010 info->fix.type_aux = 0; 2011 info->fix.xpanstep = 1; 2012 info->fix.ypanstep = 1; 2013 info->fix.ywrapstep = 0; 2014 2015 /* FIXME: map region at 0xB8000 if available, fill in here */ 2016 info->fix.mmio_len = 0; 2017 2018 fb_alloc_cmap(&info->cmap, 256, 0); 2019 2020 return 0; 2021 } 2022 2023 static int cirrusfb_register(struct fb_info *info) 2024 { 2025 struct cirrusfb_info *cinfo = info->par; 2026 int err; 2027 2028 /* sanity checks */ 2029 assert(cinfo->btype != BT_NONE); 2030 2031 /* set all the vital stuff */ 2032 cirrusfb_set_fbinfo(info); 2033 2034 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base); 2035 2036 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); 2037 if (!err) { 2038 dev_dbg(info->device, "wrong initial video mode\n"); 2039 err = -EINVAL; 2040 goto err_dealloc_cmap; 2041 } 2042 2043 info->var.activate = FB_ACTIVATE_NOW; 2044 2045 err = cirrusfb_check_var(&info->var, info); 2046 if (err < 0) { 2047 /* should never happen */ 2048 dev_dbg(info->device, 2049 "choking on default var... umm, no good.\n"); 2050 goto err_dealloc_cmap; 2051 } 2052 2053 err = register_framebuffer(info); 2054 if (err < 0) { 2055 dev_err(info->device, 2056 "could not register fb device; err = %d!\n", err); 2057 goto err_dealloc_cmap; 2058 } 2059 2060 return 0; 2061 2062 err_dealloc_cmap: 2063 fb_dealloc_cmap(&info->cmap); 2064 return err; 2065 } 2066 2067 static void cirrusfb_cleanup(struct fb_info *info) 2068 { 2069 struct cirrusfb_info *cinfo = info->par; 2070 2071 switch_monitor(cinfo, 0); 2072 unregister_framebuffer(info); 2073 fb_dealloc_cmap(&info->cmap); 2074 dev_dbg(info->device, "Framebuffer unregistered\n"); 2075 cinfo->unmap(info); 2076 framebuffer_release(info); 2077 } 2078 2079 #ifdef CONFIG_PCI 2080 static int cirrusfb_pci_register(struct pci_dev *pdev, 2081 const struct pci_device_id *ent) 2082 { 2083 struct cirrusfb_info *cinfo; 2084 struct fb_info *info; 2085 unsigned long board_addr, board_size; 2086 int ret; 2087 2088 ret = aperture_remove_conflicting_pci_devices(pdev, "cirrusfb"); 2089 if (ret) 2090 return ret; 2091 2092 ret = pci_enable_device(pdev); 2093 if (ret < 0) { 2094 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n"); 2095 goto err_out; 2096 } 2097 2098 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev); 2099 if (!info) { 2100 ret = -ENOMEM; 2101 goto err_out; 2102 } 2103 2104 cinfo = info->par; 2105 cinfo->btype = (enum cirrus_board) ent->driver_data; 2106 2107 dev_dbg(info->device, 2108 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n", 2109 (unsigned long long)pdev->resource[0].start, cinfo->btype); 2110 dev_dbg(info->device, " base address 1 is 0x%Lx\n", 2111 (unsigned long long)pdev->resource[1].start); 2112 2113 dev_dbg(info->device, 2114 "Attempt to get PCI info for Cirrus Graphics Card\n"); 2115 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); 2116 /* FIXME: this forces VGA. alternatives? */ 2117 cinfo->regbase = NULL; 2118 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000); 2119 2120 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n", 2121 board_addr, info->fix.mmio_start); 2122 2123 board_size = (cinfo->btype == BT_GD5480) ? 2124 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase); 2125 2126 ret = pci_request_regions(pdev, "cirrusfb"); 2127 if (ret < 0) { 2128 dev_err(info->device, "cannot reserve region 0x%lx, abort\n", 2129 board_addr); 2130 goto err_release_fb; 2131 } 2132 #if 0 /* if the system didn't claim this region, we would... */ 2133 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) { 2134 dev_err(info->device, "cannot reserve region 0x%lx, abort\n", 2135 0xA0000L); 2136 ret = -EBUSY; 2137 goto err_release_regions; 2138 } 2139 #endif 2140 if (request_region(0x3C0, 32, "cirrusfb")) 2141 release_io_ports = 1; 2142 2143 info->screen_base = ioremap(board_addr, board_size); 2144 if (!info->screen_base) { 2145 ret = -EIO; 2146 goto err_release_legacy; 2147 } 2148 2149 info->fix.smem_start = board_addr; 2150 info->screen_size = board_size; 2151 cinfo->unmap = cirrusfb_pci_unmap; 2152 2153 dev_info(info->device, 2154 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n", 2155 info->screen_size >> 10, board_addr); 2156 pci_set_drvdata(pdev, info); 2157 2158 ret = cirrusfb_register(info); 2159 if (!ret) 2160 return 0; 2161 2162 iounmap(info->screen_base); 2163 err_release_legacy: 2164 if (release_io_ports) 2165 release_region(0x3C0, 32); 2166 #if 0 2167 release_mem_region(0xA0000, 65535); 2168 err_release_regions: 2169 #endif 2170 pci_release_regions(pdev); 2171 err_release_fb: 2172 if (cinfo->laguna_mmio != NULL) 2173 iounmap(cinfo->laguna_mmio); 2174 framebuffer_release(info); 2175 err_out: 2176 return ret; 2177 } 2178 2179 static void cirrusfb_pci_unregister(struct pci_dev *pdev) 2180 { 2181 struct fb_info *info = pci_get_drvdata(pdev); 2182 2183 cirrusfb_cleanup(info); 2184 } 2185 2186 static struct pci_driver cirrusfb_pci_driver = { 2187 .name = "cirrusfb", 2188 .id_table = cirrusfb_pci_table, 2189 .probe = cirrusfb_pci_register, 2190 .remove = cirrusfb_pci_unregister, 2191 }; 2192 #endif /* CONFIG_PCI */ 2193 2194 #ifdef CONFIG_ZORRO 2195 static int cirrusfb_zorro_register(struct zorro_dev *z, 2196 const struct zorro_device_id *ent) 2197 { 2198 struct fb_info *info; 2199 int error; 2200 const struct zorrocl *zcl; 2201 enum cirrus_board btype; 2202 unsigned long regbase, ramsize, rambase; 2203 struct cirrusfb_info *cinfo; 2204 2205 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); 2206 if (!info) 2207 return -ENOMEM; 2208 2209 zcl = (const struct zorrocl *)ent->driver_data; 2210 btype = zcl->type; 2211 regbase = zorro_resource_start(z) + zcl->regoffset; 2212 ramsize = zcl->ramsize; 2213 if (ramsize) { 2214 rambase = zorro_resource_start(z) + zcl->ramoffset; 2215 if (zorro_resource_len(z) == 64 * MB_) { 2216 /* Quirk for 64 MiB Picasso IV */ 2217 rambase += zcl->ramoffset; 2218 } 2219 } else { 2220 struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL); 2221 if (!ram || !zorro_resource_len(ram)) { 2222 dev_err(info->device, "No video RAM found\n"); 2223 error = -ENODEV; 2224 goto err_release_fb; 2225 } 2226 rambase = zorro_resource_start(ram); 2227 ramsize = zorro_resource_len(ram); 2228 if (zcl->ramid2 && 2229 (ram = zorro_find_device(zcl->ramid2, NULL))) { 2230 if (zorro_resource_start(ram) != rambase + ramsize) { 2231 dev_warn(info->device, 2232 "Skipping non-contiguous RAM at %pR\n", 2233 &ram->resource); 2234 } else { 2235 ramsize += zorro_resource_len(ram); 2236 } 2237 } 2238 } 2239 2240 dev_info(info->device, 2241 "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n", 2242 cirrusfb_board_info[btype].name, regbase, ramsize / MB_, 2243 rambase); 2244 2245 if (!zorro_request_device(z, "cirrusfb")) { 2246 dev_err(info->device, "Cannot reserve %pR\n", &z->resource); 2247 error = -EBUSY; 2248 goto err_release_fb; 2249 } 2250 2251 cinfo = info->par; 2252 cinfo->btype = btype; 2253 2254 info->fix.mmio_start = regbase; 2255 cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024) 2256 : ZTWO_VADDR(regbase); 2257 if (!cinfo->regbase) { 2258 dev_err(info->device, "Cannot map registers\n"); 2259 error = -EIO; 2260 goto err_release_dev; 2261 } 2262 2263 info->fix.smem_start = rambase; 2264 info->screen_size = ramsize; 2265 info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize) 2266 : ZTWO_VADDR(rambase); 2267 if (!info->screen_base) { 2268 dev_err(info->device, "Cannot map video RAM\n"); 2269 error = -EIO; 2270 goto err_unmap_reg; 2271 } 2272 2273 cinfo->unmap = cirrusfb_zorro_unmap; 2274 2275 dev_info(info->device, 2276 "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n", 2277 ramsize / MB_, rambase); 2278 2279 /* MCLK select etc. */ 2280 if (cirrusfb_board_info[btype].init_sr1f) 2281 vga_wseq(cinfo->regbase, CL_SEQR1F, 2282 cirrusfb_board_info[btype].sr1f); 2283 2284 error = cirrusfb_register(info); 2285 if (error) { 2286 dev_err(info->device, "Failed to register device, error %d\n", 2287 error); 2288 goto err_unmap_ram; 2289 } 2290 2291 zorro_set_drvdata(z, info); 2292 return 0; 2293 2294 err_unmap_ram: 2295 if (rambase > 16 * MB_) 2296 iounmap(info->screen_base); 2297 2298 err_unmap_reg: 2299 if (regbase > 16 * MB_) 2300 iounmap(cinfo->regbase); 2301 err_release_dev: 2302 zorro_release_device(z); 2303 err_release_fb: 2304 framebuffer_release(info); 2305 return error; 2306 } 2307 2308 static void cirrusfb_zorro_unregister(struct zorro_dev *z) 2309 { 2310 struct fb_info *info = zorro_get_drvdata(z); 2311 2312 cirrusfb_cleanup(info); 2313 zorro_set_drvdata(z, NULL); 2314 } 2315 2316 static struct zorro_driver cirrusfb_zorro_driver = { 2317 .name = "cirrusfb", 2318 .id_table = cirrusfb_zorro_table, 2319 .probe = cirrusfb_zorro_register, 2320 .remove = cirrusfb_zorro_unregister, 2321 }; 2322 #endif /* CONFIG_ZORRO */ 2323 2324 #ifndef MODULE 2325 static int __init cirrusfb_setup(char *options) 2326 { 2327 char *this_opt; 2328 2329 if (!options || !*options) 2330 return 0; 2331 2332 while ((this_opt = strsep(&options, ",")) != NULL) { 2333 if (!*this_opt) 2334 continue; 2335 2336 if (!strcmp(this_opt, "noaccel")) 2337 noaccel = 1; 2338 else if (!strncmp(this_opt, "mode:", 5)) 2339 mode_option = this_opt + 5; 2340 else 2341 mode_option = this_opt; 2342 } 2343 return 0; 2344 } 2345 #endif 2346 2347 /* 2348 * Modularization 2349 */ 2350 2351 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>"); 2352 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); 2353 MODULE_LICENSE("GPL"); 2354 2355 static int __init cirrusfb_init(void) 2356 { 2357 int error = 0; 2358 2359 #ifndef MODULE 2360 char *option = NULL; 2361 #endif 2362 2363 if (fb_modesetting_disabled("cirrusfb")) 2364 return -ENODEV; 2365 2366 #ifndef MODULE 2367 if (fb_get_options("cirrusfb", &option)) 2368 return -ENODEV; 2369 cirrusfb_setup(option); 2370 #endif 2371 2372 #ifdef CONFIG_ZORRO 2373 error |= zorro_register_driver(&cirrusfb_zorro_driver); 2374 #endif 2375 #ifdef CONFIG_PCI 2376 error |= pci_register_driver(&cirrusfb_pci_driver); 2377 #endif 2378 return error; 2379 } 2380 2381 static void __exit cirrusfb_exit(void) 2382 { 2383 #ifdef CONFIG_PCI 2384 pci_unregister_driver(&cirrusfb_pci_driver); 2385 #endif 2386 #ifdef CONFIG_ZORRO 2387 zorro_unregister_driver(&cirrusfb_zorro_driver); 2388 #endif 2389 } 2390 2391 module_init(cirrusfb_init); 2392 2393 module_param(mode_option, charp, 0); 2394 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); 2395 module_param(noaccel, bool, 0); 2396 MODULE_PARM_DESC(noaccel, "Disable acceleration"); 2397 2398 #ifdef MODULE 2399 module_exit(cirrusfb_exit); 2400 #endif 2401 2402 /**********************************************************************/ 2403 /* about the following functions - I have used the same names for the */ 2404 /* functions as Markus Wild did in his Retina driver for NetBSD as */ 2405 /* they just made sense for this purpose. Apart from that, I wrote */ 2406 /* these functions myself. */ 2407 /**********************************************************************/ 2408 2409 /*** WGen() - write into one of the external/general registers ***/ 2410 static void WGen(const struct cirrusfb_info *cinfo, 2411 int regnum, unsigned char val) 2412 { 2413 unsigned long regofs = 0; 2414 2415 if (cinfo->btype == BT_PICASSO) { 2416 /* Picasso II specific hack */ 2417 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || 2418 regnum == CL_VSSM2) */ 2419 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2420 regofs = 0xfff; 2421 } 2422 2423 vga_w(cinfo->regbase, regofs + regnum, val); 2424 } 2425 2426 /*** RGen() - read out one of the external/general registers ***/ 2427 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum) 2428 { 2429 unsigned long regofs = 0; 2430 2431 if (cinfo->btype == BT_PICASSO) { 2432 /* Picasso II specific hack */ 2433 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || 2434 regnum == CL_VSSM2) */ 2435 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2436 regofs = 0xfff; 2437 } 2438 2439 return vga_r(cinfo->regbase, regofs + regnum); 2440 } 2441 2442 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/ 2443 static void AttrOn(const struct cirrusfb_info *cinfo) 2444 { 2445 assert(cinfo != NULL); 2446 2447 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) { 2448 /* if we're just in "write value" mode, write back the */ 2449 /* same value as before to not modify anything */ 2450 vga_w(cinfo->regbase, VGA_ATT_IW, 2451 vga_r(cinfo->regbase, VGA_ATT_R)); 2452 } 2453 /* turn on video bit */ 2454 /* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */ 2455 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33); 2456 2457 /* dummy write on Reg0 to be on "write index" mode next time */ 2458 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00); 2459 } 2460 2461 /*** WHDR() - write into the Hidden DAC register ***/ 2462 /* as the HDR is the only extension register that requires special treatment 2463 * (the other extension registers are accessible just like the "ordinary" 2464 * registers of their functional group) here is a specialized routine for 2465 * accessing the HDR 2466 */ 2467 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) 2468 { 2469 if (is_laguna(cinfo)) 2470 return; 2471 if (cinfo->btype == BT_PICASSO) { 2472 /* Klaus' hint for correct access to HDR on some boards */ 2473 /* first write 0 to pixel mask (3c6) */ 2474 WGen(cinfo, VGA_PEL_MSK, 0x00); 2475 udelay(200); 2476 /* next read dummy from pixel address (3c8) */ 2477 RGen(cinfo, VGA_PEL_IW); 2478 udelay(200); 2479 } 2480 /* now do the usual stuff to access the HDR */ 2481 2482 RGen(cinfo, VGA_PEL_MSK); 2483 udelay(200); 2484 RGen(cinfo, VGA_PEL_MSK); 2485 udelay(200); 2486 RGen(cinfo, VGA_PEL_MSK); 2487 udelay(200); 2488 RGen(cinfo, VGA_PEL_MSK); 2489 udelay(200); 2490 2491 WGen(cinfo, VGA_PEL_MSK, val); 2492 udelay(200); 2493 2494 if (cinfo->btype == BT_PICASSO) { 2495 /* now first reset HDR access counter */ 2496 RGen(cinfo, VGA_PEL_IW); 2497 udelay(200); 2498 2499 /* and at the end, restore the mask value */ 2500 /* ## is this mask always 0xff? */ 2501 WGen(cinfo, VGA_PEL_MSK, 0xff); 2502 udelay(200); 2503 } 2504 } 2505 2506 /*** WSFR() - write to the "special function register" (SFR) ***/ 2507 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val) 2508 { 2509 #ifdef CONFIG_ZORRO 2510 assert(cinfo->regbase != NULL); 2511 cinfo->SFR = val; 2512 z_writeb(val, cinfo->regbase + 0x8000); 2513 #endif 2514 } 2515 2516 /* The Picasso has a second register for switching the monitor bit */ 2517 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val) 2518 { 2519 #ifdef CONFIG_ZORRO 2520 /* writing an arbitrary value to this one causes the monitor switcher */ 2521 /* to flip to Amiga display */ 2522 assert(cinfo->regbase != NULL); 2523 cinfo->SFR = val; 2524 z_writeb(val, cinfo->regbase + 0x9000); 2525 #endif 2526 } 2527 2528 /*** WClut - set CLUT entry (range: 0..63) ***/ 2529 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red, 2530 unsigned char green, unsigned char blue) 2531 { 2532 unsigned int data = VGA_PEL_D; 2533 2534 /* address write mode register is not translated.. */ 2535 vga_w(cinfo->regbase, VGA_PEL_IW, regnum); 2536 2537 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2538 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || 2539 cinfo->btype == BT_SD64 || is_laguna(cinfo)) { 2540 /* but DAC data register IS, at least for Picasso II */ 2541 if (cinfo->btype == BT_PICASSO) 2542 data += 0xfff; 2543 vga_w(cinfo->regbase, data, red); 2544 vga_w(cinfo->regbase, data, green); 2545 vga_w(cinfo->regbase, data, blue); 2546 } else { 2547 vga_w(cinfo->regbase, data, blue); 2548 vga_w(cinfo->regbase, data, green); 2549 vga_w(cinfo->regbase, data, red); 2550 } 2551 } 2552 2553 #if 0 2554 /*** RClut - read CLUT entry (range 0..63) ***/ 2555 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red, 2556 unsigned char *green, unsigned char *blue) 2557 { 2558 unsigned int data = VGA_PEL_D; 2559 2560 vga_w(cinfo->regbase, VGA_PEL_IR, regnum); 2561 2562 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2563 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2564 if (cinfo->btype == BT_PICASSO) 2565 data += 0xfff; 2566 *red = vga_r(cinfo->regbase, data); 2567 *green = vga_r(cinfo->regbase, data); 2568 *blue = vga_r(cinfo->regbase, data); 2569 } else { 2570 *blue = vga_r(cinfo->regbase, data); 2571 *green = vga_r(cinfo->regbase, data); 2572 *red = vga_r(cinfo->regbase, data); 2573 } 2574 } 2575 #endif 2576 2577 /******************************************************************* 2578 cirrusfb_WaitBLT() 2579 2580 Wait for the BitBLT engine to complete a possible earlier job 2581 *********************************************************************/ 2582 2583 /* FIXME: use interrupts instead */ 2584 static void cirrusfb_WaitBLT(u8 __iomem *regbase) 2585 { 2586 while (vga_rgfx(regbase, CL_GR31) & 0x08) 2587 cpu_relax(); 2588 } 2589 2590 /******************************************************************* 2591 cirrusfb_BitBLT() 2592 2593 perform accelerated "scrolling" 2594 ********************************************************************/ 2595 2596 static void cirrusfb_set_blitter(u8 __iomem *regbase, 2597 u_short nwidth, u_short nheight, 2598 u_long nsrc, u_long ndest, 2599 u_short bltmode, u_short line_length) 2600 2601 { 2602 /* pitch: set to line_length */ 2603 /* dest pitch low */ 2604 vga_wgfx(regbase, CL_GR24, line_length & 0xff); 2605 /* dest pitch hi */ 2606 vga_wgfx(regbase, CL_GR25, line_length >> 8); 2607 /* source pitch low */ 2608 vga_wgfx(regbase, CL_GR26, line_length & 0xff); 2609 /* source pitch hi */ 2610 vga_wgfx(regbase, CL_GR27, line_length >> 8); 2611 2612 /* BLT width: actual number of pixels - 1 */ 2613 /* BLT width low */ 2614 vga_wgfx(regbase, CL_GR20, nwidth & 0xff); 2615 /* BLT width hi */ 2616 vga_wgfx(regbase, CL_GR21, nwidth >> 8); 2617 2618 /* BLT height: actual number of lines -1 */ 2619 /* BLT height low */ 2620 vga_wgfx(regbase, CL_GR22, nheight & 0xff); 2621 /* BLT width hi */ 2622 vga_wgfx(regbase, CL_GR23, nheight >> 8); 2623 2624 /* BLT destination */ 2625 /* BLT dest low */ 2626 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff)); 2627 /* BLT dest mid */ 2628 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8)); 2629 /* BLT dest hi */ 2630 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16)); 2631 2632 /* BLT source */ 2633 /* BLT src low */ 2634 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff)); 2635 /* BLT src mid */ 2636 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8)); 2637 /* BLT src hi */ 2638 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16)); 2639 2640 /* BLT mode */ 2641 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */ 2642 2643 /* BLT ROP: SrcCopy */ 2644 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */ 2645 2646 /* and finally: GO! */ 2647 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ 2648 } 2649 2650 /******************************************************************* 2651 cirrusfb_BitBLT() 2652 2653 perform accelerated "scrolling" 2654 ********************************************************************/ 2655 2656 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, 2657 u_short curx, u_short cury, 2658 u_short destx, u_short desty, 2659 u_short width, u_short height, 2660 u_short line_length) 2661 { 2662 u_short nwidth = width - 1; 2663 u_short nheight = height - 1; 2664 u_long nsrc, ndest; 2665 u_char bltmode; 2666 2667 bltmode = 0x00; 2668 /* if source adr < dest addr, do the Blt backwards */ 2669 if (cury <= desty) { 2670 if (cury == desty) { 2671 /* if src and dest are on the same line, check x */ 2672 if (curx < destx) 2673 bltmode |= 0x01; 2674 } else 2675 bltmode |= 0x01; 2676 } 2677 /* standard case: forward blitting */ 2678 nsrc = (cury * line_length) + curx; 2679 ndest = (desty * line_length) + destx; 2680 if (bltmode) { 2681 /* this means start addresses are at the end, 2682 * counting backwards 2683 */ 2684 nsrc += nheight * line_length + nwidth; 2685 ndest += nheight * line_length + nwidth; 2686 } 2687 2688 cirrusfb_WaitBLT(regbase); 2689 2690 cirrusfb_set_blitter(regbase, nwidth, nheight, 2691 nsrc, ndest, bltmode, line_length); 2692 } 2693 2694 /******************************************************************* 2695 cirrusfb_RectFill() 2696 2697 perform accelerated rectangle fill 2698 ********************************************************************/ 2699 2700 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, 2701 u_short x, u_short y, u_short width, u_short height, 2702 u32 fg_color, u32 bg_color, u_short line_length, 2703 u_char blitmode) 2704 { 2705 u_long ndest = (y * line_length) + x; 2706 u_char op; 2707 2708 cirrusfb_WaitBLT(regbase); 2709 2710 /* This is a ColorExpand Blt, using the */ 2711 /* same color for foreground and background */ 2712 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color); 2713 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color); 2714 2715 op = 0x80; 2716 if (bits_per_pixel >= 16) { 2717 vga_wgfx(regbase, CL_GR10, bg_color >> 8); 2718 vga_wgfx(regbase, CL_GR11, fg_color >> 8); 2719 op = 0x90; 2720 } 2721 if (bits_per_pixel >= 24) { 2722 vga_wgfx(regbase, CL_GR12, bg_color >> 16); 2723 vga_wgfx(regbase, CL_GR13, fg_color >> 16); 2724 op = 0xa0; 2725 } 2726 if (bits_per_pixel == 32) { 2727 vga_wgfx(regbase, CL_GR14, bg_color >> 24); 2728 vga_wgfx(regbase, CL_GR15, fg_color >> 24); 2729 op = 0xb0; 2730 } 2731 cirrusfb_set_blitter(regbase, width - 1, height - 1, 2732 0, ndest, op | blitmode, line_length); 2733 } 2734 2735 /************************************************************************** 2736 * bestclock() - determine closest possible clock lower(?) than the 2737 * desired pixel clock 2738 **************************************************************************/ 2739 static void bestclock(long freq, int *nom, int *den, int *div) 2740 { 2741 int n, d; 2742 long h, diff; 2743 2744 assert(nom != NULL); 2745 assert(den != NULL); 2746 assert(div != NULL); 2747 2748 *nom = 0; 2749 *den = 0; 2750 *div = 0; 2751 2752 if (freq < 8000) 2753 freq = 8000; 2754 2755 diff = freq; 2756 2757 for (n = 32; n < 128; n++) { 2758 int s = 0; 2759 2760 d = (14318 * n) / freq; 2761 if ((d >= 7) && (d <= 63)) { 2762 int temp = d; 2763 2764 if (temp > 31) { 2765 s = 1; 2766 temp >>= 1; 2767 } 2768 h = ((14318 * n) / temp) >> s; 2769 h = h > freq ? h - freq : freq - h; 2770 if (h < diff) { 2771 diff = h; 2772 *nom = n; 2773 *den = temp; 2774 *div = s; 2775 } 2776 } 2777 d++; 2778 if ((d >= 7) && (d <= 63)) { 2779 if (d > 31) { 2780 s = 1; 2781 d >>= 1; 2782 } 2783 h = ((14318 * n) / d) >> s; 2784 h = h > freq ? h - freq : freq - h; 2785 if (h < diff) { 2786 diff = h; 2787 *nom = n; 2788 *den = d; 2789 *div = s; 2790 } 2791 } 2792 } 2793 } 2794 2795 /* ------------------------------------------------------------------------- 2796 * 2797 * debugging functions 2798 * 2799 * ------------------------------------------------------------------------- 2800 */ 2801 2802 #ifdef CIRRUSFB_DEBUG 2803 2804 /* 2805 * cirrusfb_dbg_print_regs 2806 * @regbase: If using newmmio, the newmmio base address, otherwise %NULL 2807 * @reg_class: type of registers to read: %CRT, or %SEQ 2808 * 2809 * DESCRIPTION: 2810 * Dumps the given list of VGA CRTC registers. If @base is %NULL, 2811 * old-style I/O ports are queried for information, otherwise MMIO is 2812 * used at the given @base address to query the information. 2813 */ 2814 2815 static void cirrusfb_dbg_print_regs(struct fb_info *info, 2816 caddr_t regbase, 2817 enum cirrusfb_dbg_reg_class reg_class, ...) 2818 { 2819 va_list list; 2820 unsigned char val = 0; 2821 unsigned reg; 2822 char *name; 2823 2824 va_start(list, reg_class); 2825 2826 name = va_arg(list, char *); 2827 while (name != NULL) { 2828 reg = va_arg(list, int); 2829 2830 switch (reg_class) { 2831 case CRT: 2832 val = vga_rcrt(regbase, (unsigned char) reg); 2833 break; 2834 case SEQ: 2835 val = vga_rseq(regbase, (unsigned char) reg); 2836 break; 2837 default: 2838 /* should never occur */ 2839 assert(false); 2840 break; 2841 } 2842 2843 dev_dbg(info->device, "%8s = 0x%02X\n", name, val); 2844 2845 name = va_arg(list, char *); 2846 } 2847 2848 va_end(list); 2849 } 2850 2851 /* 2852 * cirrusfb_dbg_reg_dump 2853 * @base: If using newmmio, the newmmio base address, otherwise %NULL 2854 * 2855 * DESCRIPTION: 2856 * Dumps a list of interesting VGA and CIRRUSFB registers. If @base is %NULL, 2857 * old-style I/O ports are queried for information, otherwise MMIO is 2858 * used at the given @base address to query the information. 2859 */ 2860 2861 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) 2862 { 2863 dev_dbg(info->device, "VGA CRTC register dump:\n"); 2864 2865 cirrusfb_dbg_print_regs(info, regbase, CRT, 2866 "CR00", 0x00, 2867 "CR01", 0x01, 2868 "CR02", 0x02, 2869 "CR03", 0x03, 2870 "CR04", 0x04, 2871 "CR05", 0x05, 2872 "CR06", 0x06, 2873 "CR07", 0x07, 2874 "CR08", 0x08, 2875 "CR09", 0x09, 2876 "CR0A", 0x0A, 2877 "CR0B", 0x0B, 2878 "CR0C", 0x0C, 2879 "CR0D", 0x0D, 2880 "CR0E", 0x0E, 2881 "CR0F", 0x0F, 2882 "CR10", 0x10, 2883 "CR11", 0x11, 2884 "CR12", 0x12, 2885 "CR13", 0x13, 2886 "CR14", 0x14, 2887 "CR15", 0x15, 2888 "CR16", 0x16, 2889 "CR17", 0x17, 2890 "CR18", 0x18, 2891 "CR22", 0x22, 2892 "CR24", 0x24, 2893 "CR26", 0x26, 2894 "CR2D", 0x2D, 2895 "CR2E", 0x2E, 2896 "CR2F", 0x2F, 2897 "CR30", 0x30, 2898 "CR31", 0x31, 2899 "CR32", 0x32, 2900 "CR33", 0x33, 2901 "CR34", 0x34, 2902 "CR35", 0x35, 2903 "CR36", 0x36, 2904 "CR37", 0x37, 2905 "CR38", 0x38, 2906 "CR39", 0x39, 2907 "CR3A", 0x3A, 2908 "CR3B", 0x3B, 2909 "CR3C", 0x3C, 2910 "CR3D", 0x3D, 2911 "CR3E", 0x3E, 2912 "CR3F", 0x3F, 2913 NULL); 2914 2915 dev_dbg(info->device, "\n"); 2916 2917 dev_dbg(info->device, "VGA SEQ register dump:\n"); 2918 2919 cirrusfb_dbg_print_regs(info, regbase, SEQ, 2920 "SR00", 0x00, 2921 "SR01", 0x01, 2922 "SR02", 0x02, 2923 "SR03", 0x03, 2924 "SR04", 0x04, 2925 "SR08", 0x08, 2926 "SR09", 0x09, 2927 "SR0A", 0x0A, 2928 "SR0B", 0x0B, 2929 "SR0D", 0x0D, 2930 "SR10", 0x10, 2931 "SR11", 0x11, 2932 "SR12", 0x12, 2933 "SR13", 0x13, 2934 "SR14", 0x14, 2935 "SR15", 0x15, 2936 "SR16", 0x16, 2937 "SR17", 0x17, 2938 "SR18", 0x18, 2939 "SR19", 0x19, 2940 "SR1A", 0x1A, 2941 "SR1B", 0x1B, 2942 "SR1C", 0x1C, 2943 "SR1D", 0x1D, 2944 "SR1E", 0x1E, 2945 "SR1F", 0x1F, 2946 NULL); 2947 2948 dev_dbg(info->device, "\n"); 2949 } 2950 2951 #endif /* CIRRUSFB_DEBUG */ 2952 2953