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_DEFAULT 1982 | FBINFO_HWACCEL_XPAN 1983 | FBINFO_HWACCEL_YPAN 1984 | FBINFO_HWACCEL_FILLRECT 1985 | FBINFO_HWACCEL_IMAGEBLIT 1986 | FBINFO_HWACCEL_COPYAREA; 1987 if (noaccel || is_laguna(cinfo)) { 1988 info->flags |= FBINFO_HWACCEL_DISABLED; 1989 info->fix.accel = FB_ACCEL_NONE; 1990 } else 1991 info->fix.accel = FB_ACCEL_CIRRUS_ALPINE; 1992 1993 info->fbops = &cirrusfb_ops; 1994 1995 if (cinfo->btype == BT_GD5480) { 1996 if (var->bits_per_pixel == 16) 1997 info->screen_base += 1 * MB_; 1998 if (var->bits_per_pixel == 32) 1999 info->screen_base += 2 * MB_; 2000 } 2001 2002 /* Fill fix common fields */ 2003 strscpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name, 2004 sizeof(info->fix.id)); 2005 2006 /* monochrome: only 1 memory plane */ 2007 /* 8 bit and above: Use whole memory area */ 2008 info->fix.smem_len = info->screen_size; 2009 if (var->bits_per_pixel == 1) 2010 info->fix.smem_len /= 4; 2011 info->fix.type_aux = 0; 2012 info->fix.xpanstep = 1; 2013 info->fix.ypanstep = 1; 2014 info->fix.ywrapstep = 0; 2015 2016 /* FIXME: map region at 0xB8000 if available, fill in here */ 2017 info->fix.mmio_len = 0; 2018 2019 fb_alloc_cmap(&info->cmap, 256, 0); 2020 2021 return 0; 2022 } 2023 2024 static int cirrusfb_register(struct fb_info *info) 2025 { 2026 struct cirrusfb_info *cinfo = info->par; 2027 int err; 2028 2029 /* sanity checks */ 2030 assert(cinfo->btype != BT_NONE); 2031 2032 /* set all the vital stuff */ 2033 cirrusfb_set_fbinfo(info); 2034 2035 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base); 2036 2037 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); 2038 if (!err) { 2039 dev_dbg(info->device, "wrong initial video mode\n"); 2040 err = -EINVAL; 2041 goto err_dealloc_cmap; 2042 } 2043 2044 info->var.activate = FB_ACTIVATE_NOW; 2045 2046 err = cirrusfb_check_var(&info->var, info); 2047 if (err < 0) { 2048 /* should never happen */ 2049 dev_dbg(info->device, 2050 "choking on default var... umm, no good.\n"); 2051 goto err_dealloc_cmap; 2052 } 2053 2054 err = register_framebuffer(info); 2055 if (err < 0) { 2056 dev_err(info->device, 2057 "could not register fb device; err = %d!\n", err); 2058 goto err_dealloc_cmap; 2059 } 2060 2061 return 0; 2062 2063 err_dealloc_cmap: 2064 fb_dealloc_cmap(&info->cmap); 2065 return err; 2066 } 2067 2068 static void cirrusfb_cleanup(struct fb_info *info) 2069 { 2070 struct cirrusfb_info *cinfo = info->par; 2071 2072 switch_monitor(cinfo, 0); 2073 unregister_framebuffer(info); 2074 fb_dealloc_cmap(&info->cmap); 2075 dev_dbg(info->device, "Framebuffer unregistered\n"); 2076 cinfo->unmap(info); 2077 framebuffer_release(info); 2078 } 2079 2080 #ifdef CONFIG_PCI 2081 static int cirrusfb_pci_register(struct pci_dev *pdev, 2082 const struct pci_device_id *ent) 2083 { 2084 struct cirrusfb_info *cinfo; 2085 struct fb_info *info; 2086 unsigned long board_addr, board_size; 2087 int ret; 2088 2089 ret = aperture_remove_conflicting_pci_devices(pdev, "cirrusfb"); 2090 if (ret) 2091 return ret; 2092 2093 ret = pci_enable_device(pdev); 2094 if (ret < 0) { 2095 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n"); 2096 goto err_out; 2097 } 2098 2099 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev); 2100 if (!info) { 2101 ret = -ENOMEM; 2102 goto err_out; 2103 } 2104 2105 cinfo = info->par; 2106 cinfo->btype = (enum cirrus_board) ent->driver_data; 2107 2108 dev_dbg(info->device, 2109 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n", 2110 (unsigned long long)pdev->resource[0].start, cinfo->btype); 2111 dev_dbg(info->device, " base address 1 is 0x%Lx\n", 2112 (unsigned long long)pdev->resource[1].start); 2113 2114 dev_dbg(info->device, 2115 "Attempt to get PCI info for Cirrus Graphics Card\n"); 2116 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); 2117 /* FIXME: this forces VGA. alternatives? */ 2118 cinfo->regbase = NULL; 2119 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000); 2120 2121 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n", 2122 board_addr, info->fix.mmio_start); 2123 2124 board_size = (cinfo->btype == BT_GD5480) ? 2125 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase); 2126 2127 ret = pci_request_regions(pdev, "cirrusfb"); 2128 if (ret < 0) { 2129 dev_err(info->device, "cannot reserve region 0x%lx, abort\n", 2130 board_addr); 2131 goto err_release_fb; 2132 } 2133 #if 0 /* if the system didn't claim this region, we would... */ 2134 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) { 2135 dev_err(info->device, "cannot reserve region 0x%lx, abort\n", 2136 0xA0000L); 2137 ret = -EBUSY; 2138 goto err_release_regions; 2139 } 2140 #endif 2141 if (request_region(0x3C0, 32, "cirrusfb")) 2142 release_io_ports = 1; 2143 2144 info->screen_base = ioremap(board_addr, board_size); 2145 if (!info->screen_base) { 2146 ret = -EIO; 2147 goto err_release_legacy; 2148 } 2149 2150 info->fix.smem_start = board_addr; 2151 info->screen_size = board_size; 2152 cinfo->unmap = cirrusfb_pci_unmap; 2153 2154 dev_info(info->device, 2155 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n", 2156 info->screen_size >> 10, board_addr); 2157 pci_set_drvdata(pdev, info); 2158 2159 ret = cirrusfb_register(info); 2160 if (!ret) 2161 return 0; 2162 2163 iounmap(info->screen_base); 2164 err_release_legacy: 2165 if (release_io_ports) 2166 release_region(0x3C0, 32); 2167 #if 0 2168 release_mem_region(0xA0000, 65535); 2169 err_release_regions: 2170 #endif 2171 pci_release_regions(pdev); 2172 err_release_fb: 2173 if (cinfo->laguna_mmio != NULL) 2174 iounmap(cinfo->laguna_mmio); 2175 framebuffer_release(info); 2176 err_out: 2177 return ret; 2178 } 2179 2180 static void cirrusfb_pci_unregister(struct pci_dev *pdev) 2181 { 2182 struct fb_info *info = pci_get_drvdata(pdev); 2183 2184 cirrusfb_cleanup(info); 2185 } 2186 2187 static struct pci_driver cirrusfb_pci_driver = { 2188 .name = "cirrusfb", 2189 .id_table = cirrusfb_pci_table, 2190 .probe = cirrusfb_pci_register, 2191 .remove = cirrusfb_pci_unregister, 2192 }; 2193 #endif /* CONFIG_PCI */ 2194 2195 #ifdef CONFIG_ZORRO 2196 static int cirrusfb_zorro_register(struct zorro_dev *z, 2197 const struct zorro_device_id *ent) 2198 { 2199 struct fb_info *info; 2200 int error; 2201 const struct zorrocl *zcl; 2202 enum cirrus_board btype; 2203 unsigned long regbase, ramsize, rambase; 2204 struct cirrusfb_info *cinfo; 2205 2206 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); 2207 if (!info) 2208 return -ENOMEM; 2209 2210 zcl = (const struct zorrocl *)ent->driver_data; 2211 btype = zcl->type; 2212 regbase = zorro_resource_start(z) + zcl->regoffset; 2213 ramsize = zcl->ramsize; 2214 if (ramsize) { 2215 rambase = zorro_resource_start(z) + zcl->ramoffset; 2216 if (zorro_resource_len(z) == 64 * MB_) { 2217 /* Quirk for 64 MiB Picasso IV */ 2218 rambase += zcl->ramoffset; 2219 } 2220 } else { 2221 struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL); 2222 if (!ram || !zorro_resource_len(ram)) { 2223 dev_err(info->device, "No video RAM found\n"); 2224 error = -ENODEV; 2225 goto err_release_fb; 2226 } 2227 rambase = zorro_resource_start(ram); 2228 ramsize = zorro_resource_len(ram); 2229 if (zcl->ramid2 && 2230 (ram = zorro_find_device(zcl->ramid2, NULL))) { 2231 if (zorro_resource_start(ram) != rambase + ramsize) { 2232 dev_warn(info->device, 2233 "Skipping non-contiguous RAM at %pR\n", 2234 &ram->resource); 2235 } else { 2236 ramsize += zorro_resource_len(ram); 2237 } 2238 } 2239 } 2240 2241 dev_info(info->device, 2242 "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n", 2243 cirrusfb_board_info[btype].name, regbase, ramsize / MB_, 2244 rambase); 2245 2246 if (!zorro_request_device(z, "cirrusfb")) { 2247 dev_err(info->device, "Cannot reserve %pR\n", &z->resource); 2248 error = -EBUSY; 2249 goto err_release_fb; 2250 } 2251 2252 cinfo = info->par; 2253 cinfo->btype = btype; 2254 2255 info->fix.mmio_start = regbase; 2256 cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024) 2257 : ZTWO_VADDR(regbase); 2258 if (!cinfo->regbase) { 2259 dev_err(info->device, "Cannot map registers\n"); 2260 error = -EIO; 2261 goto err_release_dev; 2262 } 2263 2264 info->fix.smem_start = rambase; 2265 info->screen_size = ramsize; 2266 info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize) 2267 : ZTWO_VADDR(rambase); 2268 if (!info->screen_base) { 2269 dev_err(info->device, "Cannot map video RAM\n"); 2270 error = -EIO; 2271 goto err_unmap_reg; 2272 } 2273 2274 cinfo->unmap = cirrusfb_zorro_unmap; 2275 2276 dev_info(info->device, 2277 "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n", 2278 ramsize / MB_, rambase); 2279 2280 /* MCLK select etc. */ 2281 if (cirrusfb_board_info[btype].init_sr1f) 2282 vga_wseq(cinfo->regbase, CL_SEQR1F, 2283 cirrusfb_board_info[btype].sr1f); 2284 2285 error = cirrusfb_register(info); 2286 if (error) { 2287 dev_err(info->device, "Failed to register device, error %d\n", 2288 error); 2289 goto err_unmap_ram; 2290 } 2291 2292 zorro_set_drvdata(z, info); 2293 return 0; 2294 2295 err_unmap_ram: 2296 if (rambase > 16 * MB_) 2297 iounmap(info->screen_base); 2298 2299 err_unmap_reg: 2300 if (regbase > 16 * MB_) 2301 iounmap(cinfo->regbase); 2302 err_release_dev: 2303 zorro_release_device(z); 2304 err_release_fb: 2305 framebuffer_release(info); 2306 return error; 2307 } 2308 2309 static void cirrusfb_zorro_unregister(struct zorro_dev *z) 2310 { 2311 struct fb_info *info = zorro_get_drvdata(z); 2312 2313 cirrusfb_cleanup(info); 2314 zorro_set_drvdata(z, NULL); 2315 } 2316 2317 static struct zorro_driver cirrusfb_zorro_driver = { 2318 .name = "cirrusfb", 2319 .id_table = cirrusfb_zorro_table, 2320 .probe = cirrusfb_zorro_register, 2321 .remove = cirrusfb_zorro_unregister, 2322 }; 2323 #endif /* CONFIG_ZORRO */ 2324 2325 #ifndef MODULE 2326 static int __init cirrusfb_setup(char *options) 2327 { 2328 char *this_opt; 2329 2330 if (!options || !*options) 2331 return 0; 2332 2333 while ((this_opt = strsep(&options, ",")) != NULL) { 2334 if (!*this_opt) 2335 continue; 2336 2337 if (!strcmp(this_opt, "noaccel")) 2338 noaccel = 1; 2339 else if (!strncmp(this_opt, "mode:", 5)) 2340 mode_option = this_opt + 5; 2341 else 2342 mode_option = this_opt; 2343 } 2344 return 0; 2345 } 2346 #endif 2347 2348 /* 2349 * Modularization 2350 */ 2351 2352 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>"); 2353 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); 2354 MODULE_LICENSE("GPL"); 2355 2356 static int __init cirrusfb_init(void) 2357 { 2358 int error = 0; 2359 2360 #ifndef MODULE 2361 char *option = NULL; 2362 2363 if (fb_get_options("cirrusfb", &option)) 2364 return -ENODEV; 2365 cirrusfb_setup(option); 2366 #endif 2367 2368 #ifdef CONFIG_ZORRO 2369 error |= zorro_register_driver(&cirrusfb_zorro_driver); 2370 #endif 2371 #ifdef CONFIG_PCI 2372 error |= pci_register_driver(&cirrusfb_pci_driver); 2373 #endif 2374 return error; 2375 } 2376 2377 static void __exit cirrusfb_exit(void) 2378 { 2379 #ifdef CONFIG_PCI 2380 pci_unregister_driver(&cirrusfb_pci_driver); 2381 #endif 2382 #ifdef CONFIG_ZORRO 2383 zorro_unregister_driver(&cirrusfb_zorro_driver); 2384 #endif 2385 } 2386 2387 module_init(cirrusfb_init); 2388 2389 module_param(mode_option, charp, 0); 2390 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); 2391 module_param(noaccel, bool, 0); 2392 MODULE_PARM_DESC(noaccel, "Disable acceleration"); 2393 2394 #ifdef MODULE 2395 module_exit(cirrusfb_exit); 2396 #endif 2397 2398 /**********************************************************************/ 2399 /* about the following functions - I have used the same names for the */ 2400 /* functions as Markus Wild did in his Retina driver for NetBSD as */ 2401 /* they just made sense for this purpose. Apart from that, I wrote */ 2402 /* these functions myself. */ 2403 /**********************************************************************/ 2404 2405 /*** WGen() - write into one of the external/general registers ***/ 2406 static void WGen(const struct cirrusfb_info *cinfo, 2407 int regnum, unsigned char val) 2408 { 2409 unsigned long regofs = 0; 2410 2411 if (cinfo->btype == BT_PICASSO) { 2412 /* Picasso II specific hack */ 2413 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || 2414 regnum == CL_VSSM2) */ 2415 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2416 regofs = 0xfff; 2417 } 2418 2419 vga_w(cinfo->regbase, regofs + regnum, val); 2420 } 2421 2422 /*** RGen() - read out one of the external/general registers ***/ 2423 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum) 2424 { 2425 unsigned long regofs = 0; 2426 2427 if (cinfo->btype == BT_PICASSO) { 2428 /* Picasso II specific hack */ 2429 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || 2430 regnum == CL_VSSM2) */ 2431 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2432 regofs = 0xfff; 2433 } 2434 2435 return vga_r(cinfo->regbase, regofs + regnum); 2436 } 2437 2438 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/ 2439 static void AttrOn(const struct cirrusfb_info *cinfo) 2440 { 2441 assert(cinfo != NULL); 2442 2443 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) { 2444 /* if we're just in "write value" mode, write back the */ 2445 /* same value as before to not modify anything */ 2446 vga_w(cinfo->regbase, VGA_ATT_IW, 2447 vga_r(cinfo->regbase, VGA_ATT_R)); 2448 } 2449 /* turn on video bit */ 2450 /* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */ 2451 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33); 2452 2453 /* dummy write on Reg0 to be on "write index" mode next time */ 2454 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00); 2455 } 2456 2457 /*** WHDR() - write into the Hidden DAC register ***/ 2458 /* as the HDR is the only extension register that requires special treatment 2459 * (the other extension registers are accessible just like the "ordinary" 2460 * registers of their functional group) here is a specialized routine for 2461 * accessing the HDR 2462 */ 2463 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) 2464 { 2465 if (is_laguna(cinfo)) 2466 return; 2467 if (cinfo->btype == BT_PICASSO) { 2468 /* Klaus' hint for correct access to HDR on some boards */ 2469 /* first write 0 to pixel mask (3c6) */ 2470 WGen(cinfo, VGA_PEL_MSK, 0x00); 2471 udelay(200); 2472 /* next read dummy from pixel address (3c8) */ 2473 RGen(cinfo, VGA_PEL_IW); 2474 udelay(200); 2475 } 2476 /* now do the usual stuff to access the HDR */ 2477 2478 RGen(cinfo, VGA_PEL_MSK); 2479 udelay(200); 2480 RGen(cinfo, VGA_PEL_MSK); 2481 udelay(200); 2482 RGen(cinfo, VGA_PEL_MSK); 2483 udelay(200); 2484 RGen(cinfo, VGA_PEL_MSK); 2485 udelay(200); 2486 2487 WGen(cinfo, VGA_PEL_MSK, val); 2488 udelay(200); 2489 2490 if (cinfo->btype == BT_PICASSO) { 2491 /* now first reset HDR access counter */ 2492 RGen(cinfo, VGA_PEL_IW); 2493 udelay(200); 2494 2495 /* and at the end, restore the mask value */ 2496 /* ## is this mask always 0xff? */ 2497 WGen(cinfo, VGA_PEL_MSK, 0xff); 2498 udelay(200); 2499 } 2500 } 2501 2502 /*** WSFR() - write to the "special function register" (SFR) ***/ 2503 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val) 2504 { 2505 #ifdef CONFIG_ZORRO 2506 assert(cinfo->regbase != NULL); 2507 cinfo->SFR = val; 2508 z_writeb(val, cinfo->regbase + 0x8000); 2509 #endif 2510 } 2511 2512 /* The Picasso has a second register for switching the monitor bit */ 2513 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val) 2514 { 2515 #ifdef CONFIG_ZORRO 2516 /* writing an arbitrary value to this one causes the monitor switcher */ 2517 /* to flip to Amiga display */ 2518 assert(cinfo->regbase != NULL); 2519 cinfo->SFR = val; 2520 z_writeb(val, cinfo->regbase + 0x9000); 2521 #endif 2522 } 2523 2524 /*** WClut - set CLUT entry (range: 0..63) ***/ 2525 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red, 2526 unsigned char green, unsigned char blue) 2527 { 2528 unsigned int data = VGA_PEL_D; 2529 2530 /* address write mode register is not translated.. */ 2531 vga_w(cinfo->regbase, VGA_PEL_IW, regnum); 2532 2533 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2534 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || 2535 cinfo->btype == BT_SD64 || is_laguna(cinfo)) { 2536 /* but DAC data register IS, at least for Picasso II */ 2537 if (cinfo->btype == BT_PICASSO) 2538 data += 0xfff; 2539 vga_w(cinfo->regbase, data, red); 2540 vga_w(cinfo->regbase, data, green); 2541 vga_w(cinfo->regbase, data, blue); 2542 } else { 2543 vga_w(cinfo->regbase, data, blue); 2544 vga_w(cinfo->regbase, data, green); 2545 vga_w(cinfo->regbase, data, red); 2546 } 2547 } 2548 2549 #if 0 2550 /*** RClut - read CLUT entry (range 0..63) ***/ 2551 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red, 2552 unsigned char *green, unsigned char *blue) 2553 { 2554 unsigned int data = VGA_PEL_D; 2555 2556 vga_w(cinfo->regbase, VGA_PEL_IR, regnum); 2557 2558 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2559 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2560 if (cinfo->btype == BT_PICASSO) 2561 data += 0xfff; 2562 *red = vga_r(cinfo->regbase, data); 2563 *green = vga_r(cinfo->regbase, data); 2564 *blue = vga_r(cinfo->regbase, data); 2565 } else { 2566 *blue = vga_r(cinfo->regbase, data); 2567 *green = vga_r(cinfo->regbase, data); 2568 *red = vga_r(cinfo->regbase, data); 2569 } 2570 } 2571 #endif 2572 2573 /******************************************************************* 2574 cirrusfb_WaitBLT() 2575 2576 Wait for the BitBLT engine to complete a possible earlier job 2577 *********************************************************************/ 2578 2579 /* FIXME: use interrupts instead */ 2580 static void cirrusfb_WaitBLT(u8 __iomem *regbase) 2581 { 2582 while (vga_rgfx(regbase, CL_GR31) & 0x08) 2583 cpu_relax(); 2584 } 2585 2586 /******************************************************************* 2587 cirrusfb_BitBLT() 2588 2589 perform accelerated "scrolling" 2590 ********************************************************************/ 2591 2592 static void cirrusfb_set_blitter(u8 __iomem *regbase, 2593 u_short nwidth, u_short nheight, 2594 u_long nsrc, u_long ndest, 2595 u_short bltmode, u_short line_length) 2596 2597 { 2598 /* pitch: set to line_length */ 2599 /* dest pitch low */ 2600 vga_wgfx(regbase, CL_GR24, line_length & 0xff); 2601 /* dest pitch hi */ 2602 vga_wgfx(regbase, CL_GR25, line_length >> 8); 2603 /* source pitch low */ 2604 vga_wgfx(regbase, CL_GR26, line_length & 0xff); 2605 /* source pitch hi */ 2606 vga_wgfx(regbase, CL_GR27, line_length >> 8); 2607 2608 /* BLT width: actual number of pixels - 1 */ 2609 /* BLT width low */ 2610 vga_wgfx(regbase, CL_GR20, nwidth & 0xff); 2611 /* BLT width hi */ 2612 vga_wgfx(regbase, CL_GR21, nwidth >> 8); 2613 2614 /* BLT height: actual number of lines -1 */ 2615 /* BLT height low */ 2616 vga_wgfx(regbase, CL_GR22, nheight & 0xff); 2617 /* BLT width hi */ 2618 vga_wgfx(regbase, CL_GR23, nheight >> 8); 2619 2620 /* BLT destination */ 2621 /* BLT dest low */ 2622 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff)); 2623 /* BLT dest mid */ 2624 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8)); 2625 /* BLT dest hi */ 2626 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16)); 2627 2628 /* BLT source */ 2629 /* BLT src low */ 2630 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff)); 2631 /* BLT src mid */ 2632 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8)); 2633 /* BLT src hi */ 2634 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16)); 2635 2636 /* BLT mode */ 2637 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */ 2638 2639 /* BLT ROP: SrcCopy */ 2640 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */ 2641 2642 /* and finally: GO! */ 2643 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ 2644 } 2645 2646 /******************************************************************* 2647 cirrusfb_BitBLT() 2648 2649 perform accelerated "scrolling" 2650 ********************************************************************/ 2651 2652 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, 2653 u_short curx, u_short cury, 2654 u_short destx, u_short desty, 2655 u_short width, u_short height, 2656 u_short line_length) 2657 { 2658 u_short nwidth = width - 1; 2659 u_short nheight = height - 1; 2660 u_long nsrc, ndest; 2661 u_char bltmode; 2662 2663 bltmode = 0x00; 2664 /* if source adr < dest addr, do the Blt backwards */ 2665 if (cury <= desty) { 2666 if (cury == desty) { 2667 /* if src and dest are on the same line, check x */ 2668 if (curx < destx) 2669 bltmode |= 0x01; 2670 } else 2671 bltmode |= 0x01; 2672 } 2673 /* standard case: forward blitting */ 2674 nsrc = (cury * line_length) + curx; 2675 ndest = (desty * line_length) + destx; 2676 if (bltmode) { 2677 /* this means start addresses are at the end, 2678 * counting backwards 2679 */ 2680 nsrc += nheight * line_length + nwidth; 2681 ndest += nheight * line_length + nwidth; 2682 } 2683 2684 cirrusfb_WaitBLT(regbase); 2685 2686 cirrusfb_set_blitter(regbase, nwidth, nheight, 2687 nsrc, ndest, bltmode, line_length); 2688 } 2689 2690 /******************************************************************* 2691 cirrusfb_RectFill() 2692 2693 perform accelerated rectangle fill 2694 ********************************************************************/ 2695 2696 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, 2697 u_short x, u_short y, u_short width, u_short height, 2698 u32 fg_color, u32 bg_color, u_short line_length, 2699 u_char blitmode) 2700 { 2701 u_long ndest = (y * line_length) + x; 2702 u_char op; 2703 2704 cirrusfb_WaitBLT(regbase); 2705 2706 /* This is a ColorExpand Blt, using the */ 2707 /* same color for foreground and background */ 2708 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color); 2709 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color); 2710 2711 op = 0x80; 2712 if (bits_per_pixel >= 16) { 2713 vga_wgfx(regbase, CL_GR10, bg_color >> 8); 2714 vga_wgfx(regbase, CL_GR11, fg_color >> 8); 2715 op = 0x90; 2716 } 2717 if (bits_per_pixel >= 24) { 2718 vga_wgfx(regbase, CL_GR12, bg_color >> 16); 2719 vga_wgfx(regbase, CL_GR13, fg_color >> 16); 2720 op = 0xa0; 2721 } 2722 if (bits_per_pixel == 32) { 2723 vga_wgfx(regbase, CL_GR14, bg_color >> 24); 2724 vga_wgfx(regbase, CL_GR15, fg_color >> 24); 2725 op = 0xb0; 2726 } 2727 cirrusfb_set_blitter(regbase, width - 1, height - 1, 2728 0, ndest, op | blitmode, line_length); 2729 } 2730 2731 /************************************************************************** 2732 * bestclock() - determine closest possible clock lower(?) than the 2733 * desired pixel clock 2734 **************************************************************************/ 2735 static void bestclock(long freq, int *nom, int *den, int *div) 2736 { 2737 int n, d; 2738 long h, diff; 2739 2740 assert(nom != NULL); 2741 assert(den != NULL); 2742 assert(div != NULL); 2743 2744 *nom = 0; 2745 *den = 0; 2746 *div = 0; 2747 2748 if (freq < 8000) 2749 freq = 8000; 2750 2751 diff = freq; 2752 2753 for (n = 32; n < 128; n++) { 2754 int s = 0; 2755 2756 d = (14318 * n) / freq; 2757 if ((d >= 7) && (d <= 63)) { 2758 int temp = d; 2759 2760 if (temp > 31) { 2761 s = 1; 2762 temp >>= 1; 2763 } 2764 h = ((14318 * n) / temp) >> s; 2765 h = h > freq ? h - freq : freq - h; 2766 if (h < diff) { 2767 diff = h; 2768 *nom = n; 2769 *den = temp; 2770 *div = s; 2771 } 2772 } 2773 d++; 2774 if ((d >= 7) && (d <= 63)) { 2775 if (d > 31) { 2776 s = 1; 2777 d >>= 1; 2778 } 2779 h = ((14318 * n) / d) >> s; 2780 h = h > freq ? h - freq : freq - h; 2781 if (h < diff) { 2782 diff = h; 2783 *nom = n; 2784 *den = d; 2785 *div = s; 2786 } 2787 } 2788 } 2789 } 2790 2791 /* ------------------------------------------------------------------------- 2792 * 2793 * debugging functions 2794 * 2795 * ------------------------------------------------------------------------- 2796 */ 2797 2798 #ifdef CIRRUSFB_DEBUG 2799 2800 /* 2801 * cirrusfb_dbg_print_regs 2802 * @regbase: If using newmmio, the newmmio base address, otherwise %NULL 2803 * @reg_class: type of registers to read: %CRT, or %SEQ 2804 * 2805 * DESCRIPTION: 2806 * Dumps the given list of VGA CRTC registers. If @base is %NULL, 2807 * old-style I/O ports are queried for information, otherwise MMIO is 2808 * used at the given @base address to query the information. 2809 */ 2810 2811 static void cirrusfb_dbg_print_regs(struct fb_info *info, 2812 caddr_t regbase, 2813 enum cirrusfb_dbg_reg_class reg_class, ...) 2814 { 2815 va_list list; 2816 unsigned char val = 0; 2817 unsigned reg; 2818 char *name; 2819 2820 va_start(list, reg_class); 2821 2822 name = va_arg(list, char *); 2823 while (name != NULL) { 2824 reg = va_arg(list, int); 2825 2826 switch (reg_class) { 2827 case CRT: 2828 val = vga_rcrt(regbase, (unsigned char) reg); 2829 break; 2830 case SEQ: 2831 val = vga_rseq(regbase, (unsigned char) reg); 2832 break; 2833 default: 2834 /* should never occur */ 2835 assert(false); 2836 break; 2837 } 2838 2839 dev_dbg(info->device, "%8s = 0x%02X\n", name, val); 2840 2841 name = va_arg(list, char *); 2842 } 2843 2844 va_end(list); 2845 } 2846 2847 /* 2848 * cirrusfb_dbg_reg_dump 2849 * @base: If using newmmio, the newmmio base address, otherwise %NULL 2850 * 2851 * DESCRIPTION: 2852 * Dumps a list of interesting VGA and CIRRUSFB registers. If @base is %NULL, 2853 * old-style I/O ports are queried for information, otherwise MMIO is 2854 * used at the given @base address to query the information. 2855 */ 2856 2857 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) 2858 { 2859 dev_dbg(info->device, "VGA CRTC register dump:\n"); 2860 2861 cirrusfb_dbg_print_regs(info, regbase, CRT, 2862 "CR00", 0x00, 2863 "CR01", 0x01, 2864 "CR02", 0x02, 2865 "CR03", 0x03, 2866 "CR04", 0x04, 2867 "CR05", 0x05, 2868 "CR06", 0x06, 2869 "CR07", 0x07, 2870 "CR08", 0x08, 2871 "CR09", 0x09, 2872 "CR0A", 0x0A, 2873 "CR0B", 0x0B, 2874 "CR0C", 0x0C, 2875 "CR0D", 0x0D, 2876 "CR0E", 0x0E, 2877 "CR0F", 0x0F, 2878 "CR10", 0x10, 2879 "CR11", 0x11, 2880 "CR12", 0x12, 2881 "CR13", 0x13, 2882 "CR14", 0x14, 2883 "CR15", 0x15, 2884 "CR16", 0x16, 2885 "CR17", 0x17, 2886 "CR18", 0x18, 2887 "CR22", 0x22, 2888 "CR24", 0x24, 2889 "CR26", 0x26, 2890 "CR2D", 0x2D, 2891 "CR2E", 0x2E, 2892 "CR2F", 0x2F, 2893 "CR30", 0x30, 2894 "CR31", 0x31, 2895 "CR32", 0x32, 2896 "CR33", 0x33, 2897 "CR34", 0x34, 2898 "CR35", 0x35, 2899 "CR36", 0x36, 2900 "CR37", 0x37, 2901 "CR38", 0x38, 2902 "CR39", 0x39, 2903 "CR3A", 0x3A, 2904 "CR3B", 0x3B, 2905 "CR3C", 0x3C, 2906 "CR3D", 0x3D, 2907 "CR3E", 0x3E, 2908 "CR3F", 0x3F, 2909 NULL); 2910 2911 dev_dbg(info->device, "\n"); 2912 2913 dev_dbg(info->device, "VGA SEQ register dump:\n"); 2914 2915 cirrusfb_dbg_print_regs(info, regbase, SEQ, 2916 "SR00", 0x00, 2917 "SR01", 0x01, 2918 "SR02", 0x02, 2919 "SR03", 0x03, 2920 "SR04", 0x04, 2921 "SR08", 0x08, 2922 "SR09", 0x09, 2923 "SR0A", 0x0A, 2924 "SR0B", 0x0B, 2925 "SR0D", 0x0D, 2926 "SR10", 0x10, 2927 "SR11", 0x11, 2928 "SR12", 0x12, 2929 "SR13", 0x13, 2930 "SR14", 0x14, 2931 "SR15", 0x15, 2932 "SR16", 0x16, 2933 "SR17", 0x17, 2934 "SR18", 0x18, 2935 "SR19", 0x19, 2936 "SR1A", 0x1A, 2937 "SR1B", 0x1B, 2938 "SR1C", 0x1C, 2939 "SR1D", 0x1D, 2940 "SR1E", 0x1E, 2941 "SR1F", 0x1F, 2942 NULL); 2943 2944 dev_dbg(info->device, "\n"); 2945 } 2946 2947 #endif /* CIRRUSFB_DEBUG */ 2948 2949