Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.2 2976 lines 78 kB view raw
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/module.h> 38#include <linux/kernel.h> 39#include <linux/errno.h> 40#include <linux/string.h> 41#include <linux/mm.h> 42#include <linux/delay.h> 43#include <linux/fb.h> 44#include <linux/init.h> 45#include <asm/pgtable.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#ifdef CONFIG_PPC_PREP 57#include <asm/machdep.h> 58#define isPReP machine_is(prep) 59#else 60#define isPReP 0 61#endif 62 63#include <video/vga.h> 64#include <video/cirrus.h> 65 66/***************************************************************** 67 * 68 * debugging and utility macros 69 * 70 */ 71 72/* disable runtime assertions? */ 73/* #define CIRRUSFB_NDEBUG */ 74 75/* debugging assertions */ 76#ifndef CIRRUSFB_NDEBUG 77#define assert(expr) \ 78 if (!(expr)) { \ 79 printk("Assertion failed! %s,%s,%s,line=%d\n", \ 80 #expr, __FILE__, __func__, __LINE__); \ 81 } 82#else 83#define assert(expr) 84#endif 85 86#define MB_ (1024 * 1024) 87 88/***************************************************************** 89 * 90 * chipset information 91 * 92 */ 93 94/* board types */ 95enum cirrus_board { 96 BT_NONE = 0, 97 BT_SD64, /* GD5434 */ 98 BT_PICCOLO, /* GD5426 */ 99 BT_PICASSO, /* GD5426 or GD5428 */ 100 BT_SPECTRUM, /* GD5426 or GD5428 */ 101 BT_PICASSO4, /* GD5446 */ 102 BT_ALPINE, /* GD543x/4x */ 103 BT_GD5480, 104 BT_LAGUNA, /* GD5462/64 */ 105 BT_LAGUNAB, /* GD5465 */ 106}; 107 108/* 109 * per-board-type information, used for enumerating and abstracting 110 * chip-specific information 111 * NOTE: MUST be in the same order as enum cirrus_board in order to 112 * use direct indexing on this array 113 * NOTE: '__initdata' cannot be used as some of this info 114 * is required at runtime. Maybe separate into an init-only and 115 * a run-time table? 116 */ 117static const struct cirrusfb_board_info_rec { 118 char *name; /* ASCII name of chipset */ 119 long maxclock[5]; /* maximum video clock */ 120 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ 121 bool init_sr07 : 1; /* init SR07 during init_vgachip() */ 122 bool init_sr1f : 1; /* write SR1F during init_vgachip() */ 123 /* construct bit 19 of screen start address */ 124 bool scrn_start_bit19 : 1; 125 126 /* initial SR07 value, then for each mode */ 127 unsigned char sr07; 128 unsigned char sr07_1bpp; 129 unsigned char sr07_1bpp_mux; 130 unsigned char sr07_8bpp; 131 unsigned char sr07_8bpp_mux; 132 133 unsigned char sr1f; /* SR1F VGA initial register value */ 134} cirrusfb_board_info[] = { 135 [BT_SD64] = { 136 .name = "CL SD64", 137 .maxclock = { 138 /* guess */ 139 /* the SD64/P4 have a higher max. videoclock */ 140 135100, 135100, 85500, 85500, 0 141 }, 142 .init_sr07 = true, 143 .init_sr1f = true, 144 .scrn_start_bit19 = true, 145 .sr07 = 0xF0, 146 .sr07_1bpp = 0xF0, 147 .sr07_1bpp_mux = 0xF6, 148 .sr07_8bpp = 0xF1, 149 .sr07_8bpp_mux = 0xF7, 150 .sr1f = 0x1E 151 }, 152 [BT_PICCOLO] = { 153 .name = "CL Piccolo", 154 .maxclock = { 155 /* guess */ 156 90000, 90000, 90000, 90000, 90000 157 }, 158 .init_sr07 = true, 159 .init_sr1f = true, 160 .scrn_start_bit19 = false, 161 .sr07 = 0x80, 162 .sr07_1bpp = 0x80, 163 .sr07_8bpp = 0x81, 164 .sr1f = 0x22 165 }, 166 [BT_PICASSO] = { 167 .name = "CL Picasso", 168 .maxclock = { 169 /* guess */ 170 90000, 90000, 90000, 90000, 90000 171 }, 172 .init_sr07 = true, 173 .init_sr1f = true, 174 .scrn_start_bit19 = false, 175 .sr07 = 0x20, 176 .sr07_1bpp = 0x20, 177 .sr07_8bpp = 0x21, 178 .sr1f = 0x22 179 }, 180 [BT_SPECTRUM] = { 181 .name = "CL Spectrum", 182 .maxclock = { 183 /* guess */ 184 90000, 90000, 90000, 90000, 90000 185 }, 186 .init_sr07 = true, 187 .init_sr1f = true, 188 .scrn_start_bit19 = false, 189 .sr07 = 0x80, 190 .sr07_1bpp = 0x80, 191 .sr07_8bpp = 0x81, 192 .sr1f = 0x22 193 }, 194 [BT_PICASSO4] = { 195 .name = "CL Picasso4", 196 .maxclock = { 197 135100, 135100, 85500, 85500, 0 198 }, 199 .init_sr07 = true, 200 .init_sr1f = false, 201 .scrn_start_bit19 = true, 202 .sr07 = 0xA0, 203 .sr07_1bpp = 0xA0, 204 .sr07_1bpp_mux = 0xA6, 205 .sr07_8bpp = 0xA1, 206 .sr07_8bpp_mux = 0xA7, 207 .sr1f = 0 208 }, 209 [BT_ALPINE] = { 210 .name = "CL Alpine", 211 .maxclock = { 212 /* for the GD5430. GD5446 can do more... */ 213 85500, 85500, 50000, 28500, 0 214 }, 215 .init_sr07 = true, 216 .init_sr1f = true, 217 .scrn_start_bit19 = true, 218 .sr07 = 0xA0, 219 .sr07_1bpp = 0xA0, 220 .sr07_1bpp_mux = 0xA6, 221 .sr07_8bpp = 0xA1, 222 .sr07_8bpp_mux = 0xA7, 223 .sr1f = 0x1C 224 }, 225 [BT_GD5480] = { 226 .name = "CL GD5480", 227 .maxclock = { 228 135100, 200000, 200000, 135100, 135100 229 }, 230 .init_sr07 = true, 231 .init_sr1f = true, 232 .scrn_start_bit19 = true, 233 .sr07 = 0x10, 234 .sr07_1bpp = 0x11, 235 .sr07_8bpp = 0x11, 236 .sr1f = 0x1C 237 }, 238 [BT_LAGUNA] = { 239 .name = "CL Laguna", 240 .maxclock = { 241 /* taken from X11 code */ 242 170000, 170000, 170000, 170000, 135100, 243 }, 244 .init_sr07 = false, 245 .init_sr1f = false, 246 .scrn_start_bit19 = true, 247 }, 248 [BT_LAGUNAB] = { 249 .name = "CL Laguna AGP", 250 .maxclock = { 251 /* taken from X11 code */ 252 170000, 250000, 170000, 170000, 135100, 253 }, 254 .init_sr07 = false, 255 .init_sr1f = false, 256 .scrn_start_bit19 = true, 257 } 258}; 259 260#ifdef CONFIG_PCI 261#define CHIP(id, btype) \ 262 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } 263 264static struct pci_device_id cirrusfb_pci_table[] = { 265 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), 266 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64), 267 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64), 268 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ 269 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), 270 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), 271 CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */ 272 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */ 273 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */ 274 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */ 275 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/ 276 { 0, } 277}; 278MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); 279#undef CHIP 280#endif /* CONFIG_PCI */ 281 282#ifdef CONFIG_ZORRO 283static const struct zorro_device_id cirrusfb_zorro_table[] = { 284 { 285 .id = ZORRO_PROD_HELFRICH_SD64_RAM, 286 .driver_data = BT_SD64, 287 }, { 288 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM, 289 .driver_data = BT_PICCOLO, 290 }, { 291 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, 292 .driver_data = BT_PICASSO, 293 }, { 294 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, 295 .driver_data = BT_SPECTRUM, 296 }, { 297 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, 298 .driver_data = BT_PICASSO4, 299 }, 300 { 0 } 301}; 302MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table); 303 304static const struct { 305 zorro_id id2; 306 unsigned long size; 307} cirrusfb_zorro_table2[] = { 308 [BT_SD64] = { 309 .id2 = ZORRO_PROD_HELFRICH_SD64_REG, 310 .size = 0x400000 311 }, 312 [BT_PICCOLO] = { 313 .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG, 314 .size = 0x200000 315 }, 316 [BT_PICASSO] = { 317 .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, 318 .size = 0x200000 319 }, 320 [BT_SPECTRUM] = { 321 .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, 322 .size = 0x200000 323 }, 324 [BT_PICASSO4] = { 325 .id2 = 0, 326 .size = 0x400000 327 } 328}; 329#endif /* CONFIG_ZORRO */ 330 331#ifdef CIRRUSFB_DEBUG 332enum cirrusfb_dbg_reg_class { 333 CRT, 334 SEQ 335}; 336#endif /* CIRRUSFB_DEBUG */ 337 338/* info about board */ 339struct cirrusfb_info { 340 u8 __iomem *regbase; 341 u8 __iomem *laguna_mmio; 342 enum cirrus_board btype; 343 unsigned char SFR; /* Shadow of special function register */ 344 345 int multiplexing; 346 int doubleVCLK; 347 int blank_mode; 348 u32 pseudo_palette[16]; 349 350 void (*unmap)(struct fb_info *info); 351}; 352 353static int noaccel __devinitdata; 354static char *mode_option __devinitdata = "640x480@60"; 355 356/****************************************************************************/ 357/**** BEGIN PROTOTYPES ******************************************************/ 358 359/*--- Interface used by the world ------------------------------------------*/ 360static int cirrusfb_pan_display(struct fb_var_screeninfo *var, 361 struct fb_info *info); 362 363/*--- Internal routines ----------------------------------------------------*/ 364static void init_vgachip(struct fb_info *info); 365static void switch_monitor(struct cirrusfb_info *cinfo, int on); 366static void WGen(const struct cirrusfb_info *cinfo, 367 int regnum, unsigned char val); 368static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum); 369static void AttrOn(const struct cirrusfb_info *cinfo); 370static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val); 371static void WSFR(struct cirrusfb_info *cinfo, unsigned char val); 372static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val); 373static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, 374 unsigned char red, unsigned char green, unsigned char blue); 375#if 0 376static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, 377 unsigned char *red, unsigned char *green, 378 unsigned char *blue); 379#endif 380static void cirrusfb_WaitBLT(u8 __iomem *regbase); 381static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, 382 u_short curx, u_short cury, 383 u_short destx, u_short desty, 384 u_short width, u_short height, 385 u_short line_length); 386static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, 387 u_short x, u_short y, 388 u_short width, u_short height, 389 u32 fg_color, u32 bg_color, 390 u_short line_length, u_char blitmode); 391 392static void bestclock(long freq, int *nom, int *den, int *div); 393 394#ifdef CIRRUSFB_DEBUG 395static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase); 396static void cirrusfb_dbg_print_regs(struct fb_info *info, 397 caddr_t regbase, 398 enum cirrusfb_dbg_reg_class reg_class, ...); 399#endif /* CIRRUSFB_DEBUG */ 400 401/*** END PROTOTYPES ********************************************************/ 402/*****************************************************************************/ 403/*** BEGIN Interface Used by the World ***************************************/ 404 405static inline int is_laguna(const struct cirrusfb_info *cinfo) 406{ 407 return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB; 408} 409 410static int opencount; 411 412/*--- Open /dev/fbx ---------------------------------------------------------*/ 413static int cirrusfb_open(struct fb_info *info, int user) 414{ 415 if (opencount++ == 0) 416 switch_monitor(info->par, 1); 417 return 0; 418} 419 420/*--- Close /dev/fbx --------------------------------------------------------*/ 421static int cirrusfb_release(struct fb_info *info, int user) 422{ 423 if (--opencount == 0) 424 switch_monitor(info->par, 0); 425 return 0; 426} 427 428/**** END Interface used by the World *************************************/ 429/****************************************************************************/ 430/**** BEGIN Hardware specific Routines **************************************/ 431 432/* Check if the MCLK is not a better clock source */ 433static int cirrusfb_check_mclk(struct fb_info *info, long freq) 434{ 435 struct cirrusfb_info *cinfo = info->par; 436 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f; 437 438 /* Read MCLK value */ 439 mclk = (14318 * mclk) >> 3; 440 dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk); 441 442 /* Determine if we should use MCLK instead of VCLK, and if so, what we 443 * should divide it by to get VCLK 444 */ 445 446 if (abs(freq - mclk) < 250) { 447 dev_dbg(info->device, "Using VCLK = MCLK\n"); 448 return 1; 449 } else if (abs(freq - (mclk / 2)) < 250) { 450 dev_dbg(info->device, "Using VCLK = MCLK/2\n"); 451 return 2; 452 } 453 454 return 0; 455} 456 457static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var, 458 struct fb_info *info) 459{ 460 long freq; 461 long maxclock; 462 struct cirrusfb_info *cinfo = info->par; 463 unsigned maxclockidx = var->bits_per_pixel >> 3; 464 465 /* convert from ps to kHz */ 466 freq = PICOS2KHZ(var->pixclock); 467 468 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq); 469 470 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; 471 cinfo->multiplexing = 0; 472 473 /* If the frequency is greater than we can support, we might be able 474 * to use multiplexing for the video mode */ 475 if (freq > maxclock) { 476 dev_err(info->device, 477 "Frequency greater than maxclock (%ld kHz)\n", 478 maxclock); 479 return -EINVAL; 480 } 481 /* 482 * Additional constraint: 8bpp uses DAC clock doubling to allow maximum 483 * pixel clock 484 */ 485 if (var->bits_per_pixel == 8) { 486 switch (cinfo->btype) { 487 case BT_ALPINE: 488 case BT_SD64: 489 case BT_PICASSO4: 490 if (freq > 85500) 491 cinfo->multiplexing = 1; 492 break; 493 case BT_GD5480: 494 if (freq > 135100) 495 cinfo->multiplexing = 1; 496 break; 497 498 default: 499 break; 500 } 501 } 502 503 /* If we have a 1MB 5434, we need to put ourselves in a mode where 504 * the VCLK is double the pixel clock. */ 505 cinfo->doubleVCLK = 0; 506 if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ && 507 var->bits_per_pixel == 16) { 508 cinfo->doubleVCLK = 1; 509 } 510 511 return 0; 512} 513 514static int cirrusfb_check_var(struct fb_var_screeninfo *var, 515 struct fb_info *info) 516{ 517 int yres; 518 /* memory size in pixels */ 519 unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; 520 struct cirrusfb_info *cinfo = info->par; 521 522 switch (var->bits_per_pixel) { 523 case 1: 524 var->red.offset = 0; 525 var->red.length = 1; 526 var->green = var->red; 527 var->blue = var->red; 528 break; 529 530 case 8: 531 var->red.offset = 0; 532 var->red.length = 8; 533 var->green = var->red; 534 var->blue = var->red; 535 break; 536 537 case 16: 538 if (isPReP) { 539 var->red.offset = 2; 540 var->green.offset = -3; 541 var->blue.offset = 8; 542 } else { 543 var->red.offset = 11; 544 var->green.offset = 5; 545 var->blue.offset = 0; 546 } 547 var->red.length = 5; 548 var->green.length = 6; 549 var->blue.length = 5; 550 break; 551 552 case 24: 553 if (isPReP) { 554 var->red.offset = 0; 555 var->green.offset = 8; 556 var->blue.offset = 16; 557 } else { 558 var->red.offset = 16; 559 var->green.offset = 8; 560 var->blue.offset = 0; 561 } 562 var->red.length = 8; 563 var->green.length = 8; 564 var->blue.length = 8; 565 break; 566 567 default: 568 dev_dbg(info->device, 569 "Unsupported bpp size: %d\n", var->bits_per_pixel); 570 return -EINVAL; 571 } 572 573 if (var->xres_virtual < var->xres) 574 var->xres_virtual = var->xres; 575 /* use highest possible virtual resolution */ 576 if (var->yres_virtual == -1) { 577 var->yres_virtual = pixels / var->xres_virtual; 578 579 dev_info(info->device, 580 "virtual resolution set to maximum of %dx%d\n", 581 var->xres_virtual, var->yres_virtual); 582 } 583 if (var->yres_virtual < var->yres) 584 var->yres_virtual = var->yres; 585 586 if (var->xres_virtual * var->yres_virtual > pixels) { 587 dev_err(info->device, "mode %dx%dx%d rejected... " 588 "virtual resolution too high to fit into video memory!\n", 589 var->xres_virtual, var->yres_virtual, 590 var->bits_per_pixel); 591 return -EINVAL; 592 } 593 594 if (var->xoffset < 0) 595 var->xoffset = 0; 596 if (var->yoffset < 0) 597 var->yoffset = 0; 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 633static 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**************************************************************************/ 659static 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 */ 1271static int cirrusfb_set_par(struct fb_info *info) 1272{ 1273 cirrusfb_set_par_foo(info); 1274 return cirrusfb_set_par_foo(info); 1275} 1276 1277static 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**************************************************************************/ 1314static 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 1378static 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 1447static 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 case BT_GD5480: /* fall through */ 1482 /* from Klaus' NetBSD driver: */ 1483 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); 1484 case BT_ALPINE: /* fall through */ 1485 /* put blitter into 542x compat */ 1486 vga_wgfx(cinfo->regbase, CL_GR33, 0x00); 1487 break; 1488 1489 case BT_LAGUNA: 1490 case BT_LAGUNAB: 1491 /* Nothing to do to reset the board. */ 1492 break; 1493 1494 default: 1495 dev_err(info->device, "Warning: Unknown board type\n"); 1496 break; 1497 } 1498 1499 /* make sure RAM size set by this point */ 1500 assert(info->screen_size > 0); 1501 1502 /* the P4 is not fully initialized here; I rely on it having been */ 1503 /* inited under AmigaOS already, which seems to work just fine */ 1504 /* (Klaus advised to do it this way) */ 1505 1506 if (cinfo->btype != BT_PICASSO4) { 1507 WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */ 1508 WGen(cinfo, CL_POS102, 0x01); 1509 WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */ 1510 1511 if (cinfo->btype != BT_SD64) 1512 WGen(cinfo, CL_VSSM2, 0x01); 1513 1514 /* reset sequencer logic */ 1515 vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03); 1516 1517 /* FullBandwidth (video off) and 8/9 dot clock */ 1518 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); 1519 1520 /* "magic cookie" - doesn't make any sense to me.. */ 1521/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */ 1522 /* unlock all extension registers */ 1523 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12); 1524 1525 switch (cinfo->btype) { 1526 case BT_GD5480: 1527 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98); 1528 break; 1529 case BT_ALPINE: 1530 case BT_LAGUNA: 1531 case BT_LAGUNAB: 1532 break; 1533 case BT_SD64: 1534#ifdef CONFIG_ZORRO 1535 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); 1536#endif 1537 break; 1538 default: 1539 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); 1540 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0); 1541 break; 1542 } 1543 } 1544 /* plane mask: nothing */ 1545 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); 1546 /* character map select: doesn't even matter in gx mode */ 1547 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); 1548 /* memory mode: chain4, ext. memory */ 1549 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a); 1550 1551 /* controller-internal base address of video memory */ 1552 if (bi->init_sr07) 1553 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07); 1554 1555 /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */ 1556 /* EEPROM control: shouldn't be necessary to write to this at all.. */ 1557 1558 /* graphics cursor X position (incomplete; position gives rem. 3 bits */ 1559 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00); 1560 /* graphics cursor Y position (..."... ) */ 1561 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00); 1562 /* graphics cursor attributes */ 1563 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00); 1564 /* graphics cursor pattern address */ 1565 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00); 1566 1567 /* writing these on a P4 might give problems.. */ 1568 if (cinfo->btype != BT_PICASSO4) { 1569 /* configuration readback and ext. color */ 1570 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00); 1571 /* signature generator */ 1572 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02); 1573 } 1574 1575 /* Screen A preset row scan: none */ 1576 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); 1577 /* Text cursor start: disable text cursor */ 1578 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); 1579 /* Text cursor end: - */ 1580 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); 1581 /* text cursor location high: 0 */ 1582 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); 1583 /* text cursor location low: 0 */ 1584 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00); 1585 1586 /* Underline Row scanline: - */ 1587 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); 1588 /* ### add 0x40 for text modes with > 30 MHz pixclock */ 1589 /* ext. display controls: ext.adr. wrap */ 1590 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); 1591 1592 /* Set/Reset registes: - */ 1593 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00); 1594 /* Set/Reset enable: - */ 1595 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00); 1596 /* Color Compare: - */ 1597 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00); 1598 /* Data Rotate: - */ 1599 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00); 1600 /* Read Map Select: - */ 1601 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00); 1602 /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */ 1603 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00); 1604 /* Miscellaneous: memory map base address, graphics mode */ 1605 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01); 1606 /* Color Don't care: involve all planes */ 1607 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); 1608 /* Bit Mask: no mask at all */ 1609 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); 1610 1611 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 || 1612 is_laguna(cinfo)) 1613 /* (5434 can't have bit 3 set for bitblt) */ 1614 vga_wgfx(cinfo->regbase, CL_GRB, 0x20); 1615 else 1616 /* Graphics controller mode extensions: finer granularity, 1617 * 8byte data latches 1618 */ 1619 vga_wgfx(cinfo->regbase, CL_GRB, 0x28); 1620 1621 vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */ 1622 vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */ 1623 vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */ 1624 /* Background color byte 1: - */ 1625 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */ 1626 /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */ 1627 1628 /* Attribute Controller palette registers: "identity mapping" */ 1629 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00); 1630 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01); 1631 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02); 1632 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03); 1633 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04); 1634 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05); 1635 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06); 1636 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07); 1637 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08); 1638 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09); 1639 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a); 1640 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b); 1641 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c); 1642 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d); 1643 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e); 1644 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f); 1645 1646 /* Attribute Controller mode: graphics mode */ 1647 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01); 1648 /* Overscan color reg.: reg. 0 */ 1649 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); 1650 /* Color Plane enable: Enable all 4 planes */ 1651 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); 1652 /* Color Select: - */ 1653 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); 1654 1655 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ 1656 1657 /* BLT Start/status: Blitter reset */ 1658 vga_wgfx(cinfo->regbase, CL_GR31, 0x04); 1659 /* - " - : "end-of-reset" */ 1660 vga_wgfx(cinfo->regbase, CL_GR31, 0x00); 1661 1662 /* misc... */ 1663 WHDR(cinfo, 0); /* Hidden DAC register: - */ 1664 return; 1665} 1666 1667static void switch_monitor(struct cirrusfb_info *cinfo, int on) 1668{ 1669#ifdef CONFIG_ZORRO /* only works on Zorro boards */ 1670 static int IsOn = 0; /* XXX not ok for multiple boards */ 1671 1672 if (cinfo->btype == BT_PICASSO4) 1673 return; /* nothing to switch */ 1674 if (cinfo->btype == BT_ALPINE) 1675 return; /* nothing to switch */ 1676 if (cinfo->btype == BT_GD5480) 1677 return; /* nothing to switch */ 1678 if (cinfo->btype == BT_PICASSO) { 1679 if ((on && !IsOn) || (!on && IsOn)) 1680 WSFR(cinfo, 0xff); 1681 return; 1682 } 1683 if (on) { 1684 switch (cinfo->btype) { 1685 case BT_SD64: 1686 WSFR(cinfo, cinfo->SFR | 0x21); 1687 break; 1688 case BT_PICCOLO: 1689 WSFR(cinfo, cinfo->SFR | 0x28); 1690 break; 1691 case BT_SPECTRUM: 1692 WSFR(cinfo, 0x6f); 1693 break; 1694 default: /* do nothing */ break; 1695 } 1696 } else { 1697 switch (cinfo->btype) { 1698 case BT_SD64: 1699 WSFR(cinfo, cinfo->SFR & 0xde); 1700 break; 1701 case BT_PICCOLO: 1702 WSFR(cinfo, cinfo->SFR & 0xd7); 1703 break; 1704 case BT_SPECTRUM: 1705 WSFR(cinfo, 0x4f); 1706 break; 1707 default: /* do nothing */ 1708 break; 1709 } 1710 } 1711#endif /* CONFIG_ZORRO */ 1712} 1713 1714/******************************************/ 1715/* Linux 2.6-style accelerated functions */ 1716/******************************************/ 1717 1718static int cirrusfb_sync(struct fb_info *info) 1719{ 1720 struct cirrusfb_info *cinfo = info->par; 1721 1722 if (!is_laguna(cinfo)) { 1723 while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03) 1724 cpu_relax(); 1725 } 1726 return 0; 1727} 1728 1729static void cirrusfb_fillrect(struct fb_info *info, 1730 const struct fb_fillrect *region) 1731{ 1732 struct fb_fillrect modded; 1733 int vxres, vyres; 1734 struct cirrusfb_info *cinfo = info->par; 1735 int m = info->var.bits_per_pixel; 1736 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? 1737 cinfo->pseudo_palette[region->color] : region->color; 1738 1739 if (info->state != FBINFO_STATE_RUNNING) 1740 return; 1741 if (info->flags & FBINFO_HWACCEL_DISABLED) { 1742 cfb_fillrect(info, region); 1743 return; 1744 } 1745 1746 vxres = info->var.xres_virtual; 1747 vyres = info->var.yres_virtual; 1748 1749 memcpy(&modded, region, sizeof(struct fb_fillrect)); 1750 1751 if (!modded.width || !modded.height || 1752 modded.dx >= vxres || modded.dy >= vyres) 1753 return; 1754 1755 if (modded.dx + modded.width > vxres) 1756 modded.width = vxres - modded.dx; 1757 if (modded.dy + modded.height > vyres) 1758 modded.height = vyres - modded.dy; 1759 1760 cirrusfb_RectFill(cinfo->regbase, 1761 info->var.bits_per_pixel, 1762 (region->dx * m) / 8, region->dy, 1763 (region->width * m) / 8, region->height, 1764 color, color, 1765 info->fix.line_length, 0x40); 1766} 1767 1768static void cirrusfb_copyarea(struct fb_info *info, 1769 const struct fb_copyarea *area) 1770{ 1771 struct fb_copyarea modded; 1772 u32 vxres, vyres; 1773 struct cirrusfb_info *cinfo = info->par; 1774 int m = info->var.bits_per_pixel; 1775 1776 if (info->state != FBINFO_STATE_RUNNING) 1777 return; 1778 if (info->flags & FBINFO_HWACCEL_DISABLED) { 1779 cfb_copyarea(info, area); 1780 return; 1781 } 1782 1783 vxres = info->var.xres_virtual; 1784 vyres = info->var.yres_virtual; 1785 memcpy(&modded, area, sizeof(struct fb_copyarea)); 1786 1787 if (!modded.width || !modded.height || 1788 modded.sx >= vxres || modded.sy >= vyres || 1789 modded.dx >= vxres || modded.dy >= vyres) 1790 return; 1791 1792 if (modded.sx + modded.width > vxres) 1793 modded.width = vxres - modded.sx; 1794 if (modded.dx + modded.width > vxres) 1795 modded.width = vxres - modded.dx; 1796 if (modded.sy + modded.height > vyres) 1797 modded.height = vyres - modded.sy; 1798 if (modded.dy + modded.height > vyres) 1799 modded.height = vyres - modded.dy; 1800 1801 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel, 1802 (area->sx * m) / 8, area->sy, 1803 (area->dx * m) / 8, area->dy, 1804 (area->width * m) / 8, area->height, 1805 info->fix.line_length); 1806 1807} 1808 1809static void cirrusfb_imageblit(struct fb_info *info, 1810 const struct fb_image *image) 1811{ 1812 struct cirrusfb_info *cinfo = info->par; 1813 unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4; 1814 1815 if (info->state != FBINFO_STATE_RUNNING) 1816 return; 1817 /* Alpine/SD64 does not work at 24bpp ??? */ 1818 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) 1819 cfb_imageblit(info, image); 1820 else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) && 1821 op == 0xc) 1822 cfb_imageblit(info, image); 1823 else { 1824 unsigned size = ((image->width + 7) >> 3) * image->height; 1825 int m = info->var.bits_per_pixel; 1826 u32 fg, bg; 1827 1828 if (info->var.bits_per_pixel == 8) { 1829 fg = image->fg_color; 1830 bg = image->bg_color; 1831 } else { 1832 fg = ((u32 *)(info->pseudo_palette))[image->fg_color]; 1833 bg = ((u32 *)(info->pseudo_palette))[image->bg_color]; 1834 } 1835 if (info->var.bits_per_pixel == 24) { 1836 /* clear background first */ 1837 cirrusfb_RectFill(cinfo->regbase, 1838 info->var.bits_per_pixel, 1839 (image->dx * m) / 8, image->dy, 1840 (image->width * m) / 8, 1841 image->height, 1842 bg, bg, 1843 info->fix.line_length, 0x40); 1844 } 1845 cirrusfb_RectFill(cinfo->regbase, 1846 info->var.bits_per_pixel, 1847 (image->dx * m) / 8, image->dy, 1848 (image->width * m) / 8, image->height, 1849 fg, bg, 1850 info->fix.line_length, op); 1851 memcpy(info->screen_base, image->data, size); 1852 } 1853} 1854 1855#ifdef CONFIG_PPC_PREP 1856#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000) 1857#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000) 1858static void get_prep_addrs(unsigned long *display, unsigned long *registers) 1859{ 1860 *display = PREP_VIDEO_BASE; 1861 *registers = (unsigned long) PREP_IO_BASE; 1862} 1863 1864#endif /* CONFIG_PPC_PREP */ 1865 1866#ifdef CONFIG_PCI 1867static int release_io_ports; 1868 1869/* Pulled the logic from XFree86 Cirrus driver to get the memory size, 1870 * based on the DRAM bandwidth bit and DRAM bank switching bit. This 1871 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards 1872 * seem to have. */ 1873static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info, 1874 u8 __iomem *regbase) 1875{ 1876 unsigned long mem; 1877 struct cirrusfb_info *cinfo = info->par; 1878 1879 if (is_laguna(cinfo)) { 1880 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14); 1881 1882 mem = ((SR14 & 7) + 1) << 20; 1883 } else { 1884 unsigned char SRF = vga_rseq(regbase, CL_SEQRF); 1885 switch ((SRF & 0x18)) { 1886 case 0x08: 1887 mem = 512 * 1024; 1888 break; 1889 case 0x10: 1890 mem = 1024 * 1024; 1891 break; 1892 /* 64-bit DRAM data bus width; assume 2MB. 1893 * Also indicates 2MB memory on the 5430. 1894 */ 1895 case 0x18: 1896 mem = 2048 * 1024; 1897 break; 1898 default: 1899 dev_warn(info->device, "Unknown memory size!\n"); 1900 mem = 1024 * 1024; 1901 } 1902 /* If DRAM bank switching is enabled, there must be 1903 * twice as much memory installed. (4MB on the 5434) 1904 */ 1905 if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0) 1906 mem *= 2; 1907 } 1908 1909 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */ 1910 return mem; 1911} 1912 1913static void get_pci_addrs(const struct pci_dev *pdev, 1914 unsigned long *display, unsigned long *registers) 1915{ 1916 assert(pdev != NULL); 1917 assert(display != NULL); 1918 assert(registers != NULL); 1919 1920 *display = 0; 1921 *registers = 0; 1922 1923 /* This is a best-guess for now */ 1924 1925 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { 1926 *display = pci_resource_start(pdev, 1); 1927 *registers = pci_resource_start(pdev, 0); 1928 } else { 1929 *display = pci_resource_start(pdev, 0); 1930 *registers = pci_resource_start(pdev, 1); 1931 } 1932 1933 assert(*display != 0); 1934} 1935 1936static void cirrusfb_pci_unmap(struct fb_info *info) 1937{ 1938 struct pci_dev *pdev = to_pci_dev(info->device); 1939 struct cirrusfb_info *cinfo = info->par; 1940 1941 if (cinfo->laguna_mmio == NULL) 1942 iounmap(cinfo->laguna_mmio); 1943 iounmap(info->screen_base); 1944#if 0 /* if system didn't claim this region, we would... */ 1945 release_mem_region(0xA0000, 65535); 1946#endif 1947 if (release_io_ports) 1948 release_region(0x3C0, 32); 1949 pci_release_regions(pdev); 1950} 1951#endif /* CONFIG_PCI */ 1952 1953#ifdef CONFIG_ZORRO 1954static void cirrusfb_zorro_unmap(struct fb_info *info) 1955{ 1956 struct cirrusfb_info *cinfo = info->par; 1957 struct zorro_dev *zdev = to_zorro_dev(info->device); 1958 1959 zorro_release_device(zdev); 1960 1961 if (cinfo->btype == BT_PICASSO4) { 1962 cinfo->regbase -= 0x600000; 1963 iounmap((void *)cinfo->regbase); 1964 iounmap(info->screen_base); 1965 } else { 1966 if (zorro_resource_start(zdev) > 0x01000000) 1967 iounmap(info->screen_base); 1968 } 1969} 1970#endif /* CONFIG_ZORRO */ 1971 1972/* function table of the above functions */ 1973static struct fb_ops cirrusfb_ops = { 1974 .owner = THIS_MODULE, 1975 .fb_open = cirrusfb_open, 1976 .fb_release = cirrusfb_release, 1977 .fb_setcolreg = cirrusfb_setcolreg, 1978 .fb_check_var = cirrusfb_check_var, 1979 .fb_set_par = cirrusfb_set_par, 1980 .fb_pan_display = cirrusfb_pan_display, 1981 .fb_blank = cirrusfb_blank, 1982 .fb_fillrect = cirrusfb_fillrect, 1983 .fb_copyarea = cirrusfb_copyarea, 1984 .fb_sync = cirrusfb_sync, 1985 .fb_imageblit = cirrusfb_imageblit, 1986}; 1987 1988static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) 1989{ 1990 struct cirrusfb_info *cinfo = info->par; 1991 struct fb_var_screeninfo *var = &info->var; 1992 1993 info->pseudo_palette = cinfo->pseudo_palette; 1994 info->flags = FBINFO_DEFAULT 1995 | FBINFO_HWACCEL_XPAN 1996 | FBINFO_HWACCEL_YPAN 1997 | FBINFO_HWACCEL_FILLRECT 1998 | FBINFO_HWACCEL_IMAGEBLIT 1999 | FBINFO_HWACCEL_COPYAREA; 2000 if (noaccel || is_laguna(cinfo)) { 2001 info->flags |= FBINFO_HWACCEL_DISABLED; 2002 info->fix.accel = FB_ACCEL_NONE; 2003 } else 2004 info->fix.accel = FB_ACCEL_CIRRUS_ALPINE; 2005 2006 info->fbops = &cirrusfb_ops; 2007 2008 if (cinfo->btype == BT_GD5480) { 2009 if (var->bits_per_pixel == 16) 2010 info->screen_base += 1 * MB_; 2011 if (var->bits_per_pixel == 32) 2012 info->screen_base += 2 * MB_; 2013 } 2014 2015 /* Fill fix common fields */ 2016 strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name, 2017 sizeof(info->fix.id)); 2018 2019 /* monochrome: only 1 memory plane */ 2020 /* 8 bit and above: Use whole memory area */ 2021 info->fix.smem_len = info->screen_size; 2022 if (var->bits_per_pixel == 1) 2023 info->fix.smem_len /= 4; 2024 info->fix.type_aux = 0; 2025 info->fix.xpanstep = 1; 2026 info->fix.ypanstep = 1; 2027 info->fix.ywrapstep = 0; 2028 2029 /* FIXME: map region at 0xB8000 if available, fill in here */ 2030 info->fix.mmio_len = 0; 2031 2032 fb_alloc_cmap(&info->cmap, 256, 0); 2033 2034 return 0; 2035} 2036 2037static int __devinit cirrusfb_register(struct fb_info *info) 2038{ 2039 struct cirrusfb_info *cinfo = info->par; 2040 int err; 2041 2042 /* sanity checks */ 2043 assert(cinfo->btype != BT_NONE); 2044 2045 /* set all the vital stuff */ 2046 cirrusfb_set_fbinfo(info); 2047 2048 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base); 2049 2050 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); 2051 if (!err) { 2052 dev_dbg(info->device, "wrong initial video mode\n"); 2053 err = -EINVAL; 2054 goto err_dealloc_cmap; 2055 } 2056 2057 info->var.activate = FB_ACTIVATE_NOW; 2058 2059 err = cirrusfb_check_var(&info->var, info); 2060 if (err < 0) { 2061 /* should never happen */ 2062 dev_dbg(info->device, 2063 "choking on default var... umm, no good.\n"); 2064 goto err_dealloc_cmap; 2065 } 2066 2067 err = register_framebuffer(info); 2068 if (err < 0) { 2069 dev_err(info->device, 2070 "could not register fb device; err = %d!\n", err); 2071 goto err_dealloc_cmap; 2072 } 2073 2074 return 0; 2075 2076err_dealloc_cmap: 2077 fb_dealloc_cmap(&info->cmap); 2078 return err; 2079} 2080 2081static void __devexit cirrusfb_cleanup(struct fb_info *info) 2082{ 2083 struct cirrusfb_info *cinfo = info->par; 2084 2085 switch_monitor(cinfo, 0); 2086 unregister_framebuffer(info); 2087 fb_dealloc_cmap(&info->cmap); 2088 dev_dbg(info->device, "Framebuffer unregistered\n"); 2089 cinfo->unmap(info); 2090 framebuffer_release(info); 2091} 2092 2093#ifdef CONFIG_PCI 2094static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, 2095 const struct pci_device_id *ent) 2096{ 2097 struct cirrusfb_info *cinfo; 2098 struct fb_info *info; 2099 unsigned long board_addr, board_size; 2100 int ret; 2101 2102 ret = pci_enable_device(pdev); 2103 if (ret < 0) { 2104 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n"); 2105 goto err_out; 2106 } 2107 2108 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev); 2109 if (!info) { 2110 printk(KERN_ERR "cirrusfb: could not allocate memory\n"); 2111 ret = -ENOMEM; 2112 goto err_out; 2113 } 2114 2115 cinfo = info->par; 2116 cinfo->btype = (enum cirrus_board) ent->driver_data; 2117 2118 dev_dbg(info->device, 2119 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n", 2120 (unsigned long long)pdev->resource[0].start, cinfo->btype); 2121 dev_dbg(info->device, " base address 1 is 0x%Lx\n", 2122 (unsigned long long)pdev->resource[1].start); 2123 2124 if (isPReP) { 2125 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000); 2126#ifdef CONFIG_PPC_PREP 2127 get_prep_addrs(&board_addr, &info->fix.mmio_start); 2128#endif 2129 /* PReP dies if we ioremap the IO registers, but it works w/out... */ 2130 cinfo->regbase = (char __iomem *) info->fix.mmio_start; 2131 } else { 2132 dev_dbg(info->device, 2133 "Attempt to get PCI info for Cirrus Graphics Card\n"); 2134 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); 2135 /* FIXME: this forces VGA. alternatives? */ 2136 cinfo->regbase = NULL; 2137 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000); 2138 } 2139 2140 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n", 2141 board_addr, info->fix.mmio_start); 2142 2143 board_size = (cinfo->btype == BT_GD5480) ? 2144 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase); 2145 2146 ret = pci_request_regions(pdev, "cirrusfb"); 2147 if (ret < 0) { 2148 dev_err(info->device, "cannot reserve region 0x%lx, abort\n", 2149 board_addr); 2150 goto err_release_fb; 2151 } 2152#if 0 /* if the system didn't claim this region, we would... */ 2153 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) { 2154 dev_err(info->device, "cannot reserve region 0x%lx, abort\n", 2155 0xA0000L); 2156 ret = -EBUSY; 2157 goto err_release_regions; 2158 } 2159#endif 2160 if (request_region(0x3C0, 32, "cirrusfb")) 2161 release_io_ports = 1; 2162 2163 info->screen_base = ioremap(board_addr, board_size); 2164 if (!info->screen_base) { 2165 ret = -EIO; 2166 goto err_release_legacy; 2167 } 2168 2169 info->fix.smem_start = board_addr; 2170 info->screen_size = board_size; 2171 cinfo->unmap = cirrusfb_pci_unmap; 2172 2173 dev_info(info->device, 2174 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n", 2175 info->screen_size >> 10, board_addr); 2176 pci_set_drvdata(pdev, info); 2177 2178 ret = cirrusfb_register(info); 2179 if (!ret) 2180 return 0; 2181 2182 pci_set_drvdata(pdev, NULL); 2183 iounmap(info->screen_base); 2184err_release_legacy: 2185 if (release_io_ports) 2186 release_region(0x3C0, 32); 2187#if 0 2188 release_mem_region(0xA0000, 65535); 2189err_release_regions: 2190#endif 2191 pci_release_regions(pdev); 2192err_release_fb: 2193 if (cinfo->laguna_mmio != NULL) 2194 iounmap(cinfo->laguna_mmio); 2195 framebuffer_release(info); 2196err_out: 2197 return ret; 2198} 2199 2200static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev) 2201{ 2202 struct fb_info *info = pci_get_drvdata(pdev); 2203 2204 cirrusfb_cleanup(info); 2205} 2206 2207static struct pci_driver cirrusfb_pci_driver = { 2208 .name = "cirrusfb", 2209 .id_table = cirrusfb_pci_table, 2210 .probe = cirrusfb_pci_register, 2211 .remove = __devexit_p(cirrusfb_pci_unregister), 2212#ifdef CONFIG_PM 2213#if 0 2214 .suspend = cirrusfb_pci_suspend, 2215 .resume = cirrusfb_pci_resume, 2216#endif 2217#endif 2218}; 2219#endif /* CONFIG_PCI */ 2220 2221#ifdef CONFIG_ZORRO 2222static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, 2223 const struct zorro_device_id *ent) 2224{ 2225 struct cirrusfb_info *cinfo; 2226 struct fb_info *info; 2227 enum cirrus_board btype; 2228 struct zorro_dev *z2 = NULL; 2229 unsigned long board_addr, board_size, size; 2230 int ret; 2231 2232 btype = ent->driver_data; 2233 if (cirrusfb_zorro_table2[btype].id2) 2234 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL); 2235 size = cirrusfb_zorro_table2[btype].size; 2236 2237 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); 2238 if (!info) { 2239 printk(KERN_ERR "cirrusfb: could not allocate memory\n"); 2240 ret = -ENOMEM; 2241 goto err_out; 2242 } 2243 2244 dev_info(info->device, "%s board detected\n", 2245 cirrusfb_board_info[btype].name); 2246 2247 cinfo = info->par; 2248 cinfo->btype = btype; 2249 2250 assert(z); 2251 assert(btype != BT_NONE); 2252 2253 board_addr = zorro_resource_start(z); 2254 board_size = zorro_resource_len(z); 2255 info->screen_size = size; 2256 2257 if (!zorro_request_device(z, "cirrusfb")) { 2258 dev_err(info->device, "cannot reserve region 0x%lx, abort\n", 2259 board_addr); 2260 ret = -EBUSY; 2261 goto err_release_fb; 2262 } 2263 2264 ret = -EIO; 2265 2266 if (btype == BT_PICASSO4) { 2267 dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000); 2268 2269 /* To be precise, for the P4 this is not the */ 2270 /* begin of the board, but the begin of RAM. */ 2271 /* for P4, map in its address space in 2 chunks (### TEST! ) */ 2272 /* (note the ugly hardcoded 16M number) */ 2273 cinfo->regbase = ioremap(board_addr, 16777216); 2274 if (!cinfo->regbase) 2275 goto err_release_region; 2276 2277 dev_dbg(info->device, "Virtual address for board set to: $%p\n", 2278 cinfo->regbase); 2279 cinfo->regbase += 0x600000; 2280 info->fix.mmio_start = board_addr + 0x600000; 2281 2282 info->fix.smem_start = board_addr + 16777216; 2283 info->screen_base = ioremap(info->fix.smem_start, 16777216); 2284 if (!info->screen_base) 2285 goto err_unmap_regbase; 2286 } else { 2287 dev_info(info->device, " REG at $%lx\n", 2288 (unsigned long) z2->resource.start); 2289 2290 info->fix.smem_start = board_addr; 2291 if (board_addr > 0x01000000) 2292 info->screen_base = ioremap(board_addr, board_size); 2293 else 2294 info->screen_base = (caddr_t) ZTWO_VADDR(board_addr); 2295 if (!info->screen_base) 2296 goto err_release_region; 2297 2298 /* set address for REG area of board */ 2299 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start); 2300 info->fix.mmio_start = z2->resource.start; 2301 2302 dev_dbg(info->device, "Virtual address for board set to: $%p\n", 2303 cinfo->regbase); 2304 } 2305 cinfo->unmap = cirrusfb_zorro_unmap; 2306 2307 dev_info(info->device, 2308 "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n", 2309 board_size / MB_, board_addr); 2310 2311 zorro_set_drvdata(z, info); 2312 2313 /* MCLK select etc. */ 2314 if (cirrusfb_board_info[btype].init_sr1f) 2315 vga_wseq(cinfo->regbase, CL_SEQR1F, 2316 cirrusfb_board_info[btype].sr1f); 2317 2318 ret = cirrusfb_register(info); 2319 if (!ret) 2320 return 0; 2321 2322 if (btype == BT_PICASSO4 || board_addr > 0x01000000) 2323 iounmap(info->screen_base); 2324 2325err_unmap_regbase: 2326 if (btype == BT_PICASSO4) 2327 iounmap(cinfo->regbase - 0x600000); 2328err_release_region: 2329 release_region(board_addr, board_size); 2330err_release_fb: 2331 framebuffer_release(info); 2332err_out: 2333 return ret; 2334} 2335 2336void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) 2337{ 2338 struct fb_info *info = zorro_get_drvdata(z); 2339 2340 cirrusfb_cleanup(info); 2341} 2342 2343static struct zorro_driver cirrusfb_zorro_driver = { 2344 .name = "cirrusfb", 2345 .id_table = cirrusfb_zorro_table, 2346 .probe = cirrusfb_zorro_register, 2347 .remove = __devexit_p(cirrusfb_zorro_unregister), 2348}; 2349#endif /* CONFIG_ZORRO */ 2350 2351#ifndef MODULE 2352static int __init cirrusfb_setup(char *options) 2353{ 2354 char *this_opt; 2355 2356 if (!options || !*options) 2357 return 0; 2358 2359 while ((this_opt = strsep(&options, ",")) != NULL) { 2360 if (!*this_opt) 2361 continue; 2362 2363 if (!strcmp(this_opt, "noaccel")) 2364 noaccel = 1; 2365 else if (!strncmp(this_opt, "mode:", 5)) 2366 mode_option = this_opt + 5; 2367 else 2368 mode_option = this_opt; 2369 } 2370 return 0; 2371} 2372#endif 2373 2374 /* 2375 * Modularization 2376 */ 2377 2378MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>"); 2379MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); 2380MODULE_LICENSE("GPL"); 2381 2382static int __init cirrusfb_init(void) 2383{ 2384 int error = 0; 2385 2386#ifndef MODULE 2387 char *option = NULL; 2388 2389 if (fb_get_options("cirrusfb", &option)) 2390 return -ENODEV; 2391 cirrusfb_setup(option); 2392#endif 2393 2394#ifdef CONFIG_ZORRO 2395 error |= zorro_register_driver(&cirrusfb_zorro_driver); 2396#endif 2397#ifdef CONFIG_PCI 2398 error |= pci_register_driver(&cirrusfb_pci_driver); 2399#endif 2400 return error; 2401} 2402 2403static void __exit cirrusfb_exit(void) 2404{ 2405#ifdef CONFIG_PCI 2406 pci_unregister_driver(&cirrusfb_pci_driver); 2407#endif 2408#ifdef CONFIG_ZORRO 2409 zorro_unregister_driver(&cirrusfb_zorro_driver); 2410#endif 2411} 2412 2413module_init(cirrusfb_init); 2414 2415module_param(mode_option, charp, 0); 2416MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); 2417module_param(noaccel, bool, 0); 2418MODULE_PARM_DESC(noaccel, "Disable acceleration"); 2419 2420#ifdef MODULE 2421module_exit(cirrusfb_exit); 2422#endif 2423 2424/**********************************************************************/ 2425/* about the following functions - I have used the same names for the */ 2426/* functions as Markus Wild did in his Retina driver for NetBSD as */ 2427/* they just made sense for this purpose. Apart from that, I wrote */ 2428/* these functions myself. */ 2429/**********************************************************************/ 2430 2431/*** WGen() - write into one of the external/general registers ***/ 2432static void WGen(const struct cirrusfb_info *cinfo, 2433 int regnum, unsigned char val) 2434{ 2435 unsigned long regofs = 0; 2436 2437 if (cinfo->btype == BT_PICASSO) { 2438 /* Picasso II specific hack */ 2439/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || 2440 regnum == CL_VSSM2) */ 2441 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2442 regofs = 0xfff; 2443 } 2444 2445 vga_w(cinfo->regbase, regofs + regnum, val); 2446} 2447 2448/*** RGen() - read out one of the external/general registers ***/ 2449static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum) 2450{ 2451 unsigned long regofs = 0; 2452 2453 if (cinfo->btype == BT_PICASSO) { 2454 /* Picasso II specific hack */ 2455/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || 2456 regnum == CL_VSSM2) */ 2457 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2458 regofs = 0xfff; 2459 } 2460 2461 return vga_r(cinfo->regbase, regofs + regnum); 2462} 2463 2464/*** AttrOn() - turn on VideoEnable for Attribute controller ***/ 2465static void AttrOn(const struct cirrusfb_info *cinfo) 2466{ 2467 assert(cinfo != NULL); 2468 2469 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) { 2470 /* if we're just in "write value" mode, write back the */ 2471 /* same value as before to not modify anything */ 2472 vga_w(cinfo->regbase, VGA_ATT_IW, 2473 vga_r(cinfo->regbase, VGA_ATT_R)); 2474 } 2475 /* turn on video bit */ 2476/* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */ 2477 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33); 2478 2479 /* dummy write on Reg0 to be on "write index" mode next time */ 2480 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00); 2481} 2482 2483/*** WHDR() - write into the Hidden DAC register ***/ 2484/* as the HDR is the only extension register that requires special treatment 2485 * (the other extension registers are accessible just like the "ordinary" 2486 * registers of their functional group) here is a specialized routine for 2487 * accessing the HDR 2488 */ 2489static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) 2490{ 2491 unsigned char dummy; 2492 2493 if (is_laguna(cinfo)) 2494 return; 2495 if (cinfo->btype == BT_PICASSO) { 2496 /* Klaus' hint for correct access to HDR on some boards */ 2497 /* first write 0 to pixel mask (3c6) */ 2498 WGen(cinfo, VGA_PEL_MSK, 0x00); 2499 udelay(200); 2500 /* next read dummy from pixel address (3c8) */ 2501 dummy = RGen(cinfo, VGA_PEL_IW); 2502 udelay(200); 2503 } 2504 /* now do the usual stuff to access the HDR */ 2505 2506 dummy = RGen(cinfo, VGA_PEL_MSK); 2507 udelay(200); 2508 dummy = RGen(cinfo, VGA_PEL_MSK); 2509 udelay(200); 2510 dummy = RGen(cinfo, VGA_PEL_MSK); 2511 udelay(200); 2512 dummy = RGen(cinfo, VGA_PEL_MSK); 2513 udelay(200); 2514 2515 WGen(cinfo, VGA_PEL_MSK, val); 2516 udelay(200); 2517 2518 if (cinfo->btype == BT_PICASSO) { 2519 /* now first reset HDR access counter */ 2520 dummy = RGen(cinfo, VGA_PEL_IW); 2521 udelay(200); 2522 2523 /* and at the end, restore the mask value */ 2524 /* ## is this mask always 0xff? */ 2525 WGen(cinfo, VGA_PEL_MSK, 0xff); 2526 udelay(200); 2527 } 2528} 2529 2530/*** WSFR() - write to the "special function register" (SFR) ***/ 2531static void WSFR(struct cirrusfb_info *cinfo, unsigned char val) 2532{ 2533#ifdef CONFIG_ZORRO 2534 assert(cinfo->regbase != NULL); 2535 cinfo->SFR = val; 2536 z_writeb(val, cinfo->regbase + 0x8000); 2537#endif 2538} 2539 2540/* The Picasso has a second register for switching the monitor bit */ 2541static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val) 2542{ 2543#ifdef CONFIG_ZORRO 2544 /* writing an arbitrary value to this one causes the monitor switcher */ 2545 /* to flip to Amiga display */ 2546 assert(cinfo->regbase != NULL); 2547 cinfo->SFR = val; 2548 z_writeb(val, cinfo->regbase + 0x9000); 2549#endif 2550} 2551 2552/*** WClut - set CLUT entry (range: 0..63) ***/ 2553static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red, 2554 unsigned char green, unsigned char blue) 2555{ 2556 unsigned int data = VGA_PEL_D; 2557 2558 /* address write mode register is not translated.. */ 2559 vga_w(cinfo->regbase, VGA_PEL_IW, regnum); 2560 2561 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2562 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || 2563 cinfo->btype == BT_SD64 || is_laguna(cinfo)) { 2564 /* but DAC data register IS, at least for Picasso II */ 2565 if (cinfo->btype == BT_PICASSO) 2566 data += 0xfff; 2567 vga_w(cinfo->regbase, data, red); 2568 vga_w(cinfo->regbase, data, green); 2569 vga_w(cinfo->regbase, data, blue); 2570 } else { 2571 vga_w(cinfo->regbase, data, blue); 2572 vga_w(cinfo->regbase, data, green); 2573 vga_w(cinfo->regbase, data, red); 2574 } 2575} 2576 2577#if 0 2578/*** RClut - read CLUT entry (range 0..63) ***/ 2579static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red, 2580 unsigned char *green, unsigned char *blue) 2581{ 2582 unsigned int data = VGA_PEL_D; 2583 2584 vga_w(cinfo->regbase, VGA_PEL_IR, regnum); 2585 2586 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2587 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2588 if (cinfo->btype == BT_PICASSO) 2589 data += 0xfff; 2590 *red = vga_r(cinfo->regbase, data); 2591 *green = vga_r(cinfo->regbase, data); 2592 *blue = vga_r(cinfo->regbase, data); 2593 } else { 2594 *blue = vga_r(cinfo->regbase, data); 2595 *green = vga_r(cinfo->regbase, data); 2596 *red = vga_r(cinfo->regbase, data); 2597 } 2598} 2599#endif 2600 2601/******************************************************************* 2602 cirrusfb_WaitBLT() 2603 2604 Wait for the BitBLT engine to complete a possible earlier job 2605*********************************************************************/ 2606 2607/* FIXME: use interrupts instead */ 2608static void cirrusfb_WaitBLT(u8 __iomem *regbase) 2609{ 2610 while (vga_rgfx(regbase, CL_GR31) & 0x08) 2611 cpu_relax(); 2612} 2613 2614/******************************************************************* 2615 cirrusfb_BitBLT() 2616 2617 perform accelerated "scrolling" 2618********************************************************************/ 2619 2620static void cirrusfb_set_blitter(u8 __iomem *regbase, 2621 u_short nwidth, u_short nheight, 2622 u_long nsrc, u_long ndest, 2623 u_short bltmode, u_short line_length) 2624 2625{ 2626 /* pitch: set to line_length */ 2627 /* dest pitch low */ 2628 vga_wgfx(regbase, CL_GR24, line_length & 0xff); 2629 /* dest pitch hi */ 2630 vga_wgfx(regbase, CL_GR25, line_length >> 8); 2631 /* source pitch low */ 2632 vga_wgfx(regbase, CL_GR26, line_length & 0xff); 2633 /* source pitch hi */ 2634 vga_wgfx(regbase, CL_GR27, line_length >> 8); 2635 2636 /* BLT width: actual number of pixels - 1 */ 2637 /* BLT width low */ 2638 vga_wgfx(regbase, CL_GR20, nwidth & 0xff); 2639 /* BLT width hi */ 2640 vga_wgfx(regbase, CL_GR21, nwidth >> 8); 2641 2642 /* BLT height: actual number of lines -1 */ 2643 /* BLT height low */ 2644 vga_wgfx(regbase, CL_GR22, nheight & 0xff); 2645 /* BLT width hi */ 2646 vga_wgfx(regbase, CL_GR23, nheight >> 8); 2647 2648 /* BLT destination */ 2649 /* BLT dest low */ 2650 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff)); 2651 /* BLT dest mid */ 2652 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8)); 2653 /* BLT dest hi */ 2654 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16)); 2655 2656 /* BLT source */ 2657 /* BLT src low */ 2658 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff)); 2659 /* BLT src mid */ 2660 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8)); 2661 /* BLT src hi */ 2662 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16)); 2663 2664 /* BLT mode */ 2665 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */ 2666 2667 /* BLT ROP: SrcCopy */ 2668 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */ 2669 2670 /* and finally: GO! */ 2671 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ 2672} 2673 2674/******************************************************************* 2675 cirrusfb_BitBLT() 2676 2677 perform accelerated "scrolling" 2678********************************************************************/ 2679 2680static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, 2681 u_short curx, u_short cury, 2682 u_short destx, u_short desty, 2683 u_short width, u_short height, 2684 u_short line_length) 2685{ 2686 u_short nwidth = width - 1; 2687 u_short nheight = height - 1; 2688 u_long nsrc, ndest; 2689 u_char bltmode; 2690 2691 bltmode = 0x00; 2692 /* if source adr < dest addr, do the Blt backwards */ 2693 if (cury <= desty) { 2694 if (cury == desty) { 2695 /* if src and dest are on the same line, check x */ 2696 if (curx < destx) 2697 bltmode |= 0x01; 2698 } else 2699 bltmode |= 0x01; 2700 } 2701 /* standard case: forward blitting */ 2702 nsrc = (cury * line_length) + curx; 2703 ndest = (desty * line_length) + destx; 2704 if (bltmode) { 2705 /* this means start addresses are at the end, 2706 * counting backwards 2707 */ 2708 nsrc += nheight * line_length + nwidth; 2709 ndest += nheight * line_length + nwidth; 2710 } 2711 2712 cirrusfb_WaitBLT(regbase); 2713 2714 cirrusfb_set_blitter(regbase, nwidth, nheight, 2715 nsrc, ndest, bltmode, line_length); 2716} 2717 2718/******************************************************************* 2719 cirrusfb_RectFill() 2720 2721 perform accelerated rectangle fill 2722********************************************************************/ 2723 2724static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, 2725 u_short x, u_short y, u_short width, u_short height, 2726 u32 fg_color, u32 bg_color, u_short line_length, 2727 u_char blitmode) 2728{ 2729 u_long ndest = (y * line_length) + x; 2730 u_char op; 2731 2732 cirrusfb_WaitBLT(regbase); 2733 2734 /* This is a ColorExpand Blt, using the */ 2735 /* same color for foreground and background */ 2736 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color); 2737 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color); 2738 2739 op = 0x80; 2740 if (bits_per_pixel >= 16) { 2741 vga_wgfx(regbase, CL_GR10, bg_color >> 8); 2742 vga_wgfx(regbase, CL_GR11, fg_color >> 8); 2743 op = 0x90; 2744 } 2745 if (bits_per_pixel >= 24) { 2746 vga_wgfx(regbase, CL_GR12, bg_color >> 16); 2747 vga_wgfx(regbase, CL_GR13, fg_color >> 16); 2748 op = 0xa0; 2749 } 2750 if (bits_per_pixel == 32) { 2751 vga_wgfx(regbase, CL_GR14, bg_color >> 24); 2752 vga_wgfx(regbase, CL_GR15, fg_color >> 24); 2753 op = 0xb0; 2754 } 2755 cirrusfb_set_blitter(regbase, width - 1, height - 1, 2756 0, ndest, op | blitmode, line_length); 2757} 2758 2759/************************************************************************** 2760 * bestclock() - determine closest possible clock lower(?) than the 2761 * desired pixel clock 2762 **************************************************************************/ 2763static void bestclock(long freq, int *nom, int *den, int *div) 2764{ 2765 int n, d; 2766 long h, diff; 2767 2768 assert(nom != NULL); 2769 assert(den != NULL); 2770 assert(div != NULL); 2771 2772 *nom = 0; 2773 *den = 0; 2774 *div = 0; 2775 2776 if (freq < 8000) 2777 freq = 8000; 2778 2779 diff = freq; 2780 2781 for (n = 32; n < 128; n++) { 2782 int s = 0; 2783 2784 d = (14318 * n) / freq; 2785 if ((d >= 7) && (d <= 63)) { 2786 int temp = d; 2787 2788 if (temp > 31) { 2789 s = 1; 2790 temp >>= 1; 2791 } 2792 h = ((14318 * n) / temp) >> s; 2793 h = h > freq ? h - freq : freq - h; 2794 if (h < diff) { 2795 diff = h; 2796 *nom = n; 2797 *den = temp; 2798 *div = s; 2799 } 2800 } 2801 d++; 2802 if ((d >= 7) && (d <= 63)) { 2803 if (d > 31) { 2804 s = 1; 2805 d >>= 1; 2806 } 2807 h = ((14318 * n) / d) >> s; 2808 h = h > freq ? h - freq : freq - h; 2809 if (h < diff) { 2810 diff = h; 2811 *nom = n; 2812 *den = d; 2813 *div = s; 2814 } 2815 } 2816 } 2817} 2818 2819/* ------------------------------------------------------------------------- 2820 * 2821 * debugging functions 2822 * 2823 * ------------------------------------------------------------------------- 2824 */ 2825 2826#ifdef CIRRUSFB_DEBUG 2827 2828/** 2829 * cirrusfb_dbg_print_regs 2830 * @base: If using newmmio, the newmmio base address, otherwise %NULL 2831 * @reg_class: type of registers to read: %CRT, or %SEQ 2832 * 2833 * DESCRIPTION: 2834 * Dumps the given list of VGA CRTC registers. If @base is %NULL, 2835 * old-style I/O ports are queried for information, otherwise MMIO is 2836 * used at the given @base address to query the information. 2837 */ 2838 2839static void cirrusfb_dbg_print_regs(struct fb_info *info, 2840 caddr_t regbase, 2841 enum cirrusfb_dbg_reg_class reg_class, ...) 2842{ 2843 va_list list; 2844 unsigned char val = 0; 2845 unsigned reg; 2846 char *name; 2847 2848 va_start(list, reg_class); 2849 2850 name = va_arg(list, char *); 2851 while (name != NULL) { 2852 reg = va_arg(list, int); 2853 2854 switch (reg_class) { 2855 case CRT: 2856 val = vga_rcrt(regbase, (unsigned char) reg); 2857 break; 2858 case SEQ: 2859 val = vga_rseq(regbase, (unsigned char) reg); 2860 break; 2861 default: 2862 /* should never occur */ 2863 assert(false); 2864 break; 2865 } 2866 2867 dev_dbg(info->device, "%8s = 0x%02X\n", name, val); 2868 2869 name = va_arg(list, char *); 2870 } 2871 2872 va_end(list); 2873} 2874 2875/** 2876 * cirrusfb_dbg_reg_dump 2877 * @base: If using newmmio, the newmmio base address, otherwise %NULL 2878 * 2879 * DESCRIPTION: 2880 * Dumps a list of interesting VGA and CIRRUSFB registers. If @base is %NULL, 2881 * old-style I/O ports are queried for information, otherwise MMIO is 2882 * used at the given @base address to query the information. 2883 */ 2884 2885static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) 2886{ 2887 dev_dbg(info->device, "VGA CRTC register dump:\n"); 2888 2889 cirrusfb_dbg_print_regs(info, regbase, CRT, 2890 "CR00", 0x00, 2891 "CR01", 0x01, 2892 "CR02", 0x02, 2893 "CR03", 0x03, 2894 "CR04", 0x04, 2895 "CR05", 0x05, 2896 "CR06", 0x06, 2897 "CR07", 0x07, 2898 "CR08", 0x08, 2899 "CR09", 0x09, 2900 "CR0A", 0x0A, 2901 "CR0B", 0x0B, 2902 "CR0C", 0x0C, 2903 "CR0D", 0x0D, 2904 "CR0E", 0x0E, 2905 "CR0F", 0x0F, 2906 "CR10", 0x10, 2907 "CR11", 0x11, 2908 "CR12", 0x12, 2909 "CR13", 0x13, 2910 "CR14", 0x14, 2911 "CR15", 0x15, 2912 "CR16", 0x16, 2913 "CR17", 0x17, 2914 "CR18", 0x18, 2915 "CR22", 0x22, 2916 "CR24", 0x24, 2917 "CR26", 0x26, 2918 "CR2D", 0x2D, 2919 "CR2E", 0x2E, 2920 "CR2F", 0x2F, 2921 "CR30", 0x30, 2922 "CR31", 0x31, 2923 "CR32", 0x32, 2924 "CR33", 0x33, 2925 "CR34", 0x34, 2926 "CR35", 0x35, 2927 "CR36", 0x36, 2928 "CR37", 0x37, 2929 "CR38", 0x38, 2930 "CR39", 0x39, 2931 "CR3A", 0x3A, 2932 "CR3B", 0x3B, 2933 "CR3C", 0x3C, 2934 "CR3D", 0x3D, 2935 "CR3E", 0x3E, 2936 "CR3F", 0x3F, 2937 NULL); 2938 2939 dev_dbg(info->device, "\n"); 2940 2941 dev_dbg(info->device, "VGA SEQ register dump:\n"); 2942 2943 cirrusfb_dbg_print_regs(info, regbase, SEQ, 2944 "SR00", 0x00, 2945 "SR01", 0x01, 2946 "SR02", 0x02, 2947 "SR03", 0x03, 2948 "SR04", 0x04, 2949 "SR08", 0x08, 2950 "SR09", 0x09, 2951 "SR0A", 0x0A, 2952 "SR0B", 0x0B, 2953 "SR0D", 0x0D, 2954 "SR10", 0x10, 2955 "SR11", 0x11, 2956 "SR12", 0x12, 2957 "SR13", 0x13, 2958 "SR14", 0x14, 2959 "SR15", 0x15, 2960 "SR16", 0x16, 2961 "SR17", 0x17, 2962 "SR18", 0x18, 2963 "SR19", 0x19, 2964 "SR1A", 0x1A, 2965 "SR1B", 0x1B, 2966 "SR1C", 0x1C, 2967 "SR1D", 0x1D, 2968 "SR1E", 0x1E, 2969 "SR1F", 0x1F, 2970 NULL); 2971 2972 dev_dbg(info->device, "\n"); 2973} 2974 2975#endif /* CIRRUSFB_DEBUG */ 2976