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