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