1 /* 2 * macfb.c: Generic framebuffer for Macs whose colourmaps/modes we 3 * don't know how to set. 4 * 5 * (c) 1999 David Huggins-Daines <dhd@debian.org> 6 * 7 * Primarily based on vesafb.c, by Gerd Knorr 8 * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de> 9 * 10 * Also uses information and code from: 11 * 12 * The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen 13 * Mellinger, Mikael Forselius, Michael Schmitz, and others. 14 * 15 * valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan 16 * Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven. 17 * 18 * The VideoToolbox "Bugs" web page at 19 * http://rajsky.psych.nyu.edu/Tips/VideoBugs.html 20 * 21 * This code is free software. You may copy, modify, and distribute 22 * it subject to the terms and conditions of the GNU General Public 23 * License, version 2, or any later version, at your convenience. 24 */ 25 26 #include <linux/module.h> 27 #include <linux/kernel.h> 28 #include <linux/errno.h> 29 #include <linux/string.h> 30 #include <linux/mm.h> 31 #include <linux/delay.h> 32 #include <linux/nubus.h> 33 #include <linux/init.h> 34 #include <linux/fb.h> 35 36 #include <asm/setup.h> 37 #include <asm/macintosh.h> 38 #include <asm/io.h> 39 40 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */ 41 #define DAC_BASE 0x50f24000 42 43 /* Some addresses for the DAFB */ 44 #define DAFB_BASE 0xf9800200 45 46 /* Address for the built-in Civic framebuffer in Quadra AVs */ 47 #define CIVIC_BASE 0x50f30800 48 49 /* GSC (Gray Scale Controller) base address */ 50 #define GSC_BASE 0x50F20000 51 52 /* CSC (Color Screen Controller) base address */ 53 #define CSC_BASE 0x50F20000 54 55 static int (*macfb_setpalette)(unsigned int regno, unsigned int red, 56 unsigned int green, unsigned int blue, 57 struct fb_info *info); 58 59 static struct { 60 unsigned char addr; 61 unsigned char lut; 62 } __iomem *v8_brazil_cmap_regs; 63 64 static struct { 65 unsigned char addr; 66 char pad1[3]; /* word aligned */ 67 unsigned char lut; 68 char pad2[3]; /* word aligned */ 69 unsigned char cntl; /* a guess as to purpose */ 70 } __iomem *rbv_cmap_regs; 71 72 static struct { 73 unsigned long reset; 74 unsigned long pad1[3]; 75 unsigned char pad2[3]; 76 unsigned char lut; 77 } __iomem *dafb_cmap_regs; 78 79 static struct { 80 unsigned char addr; /* OFFSET: 0x00 */ 81 unsigned char pad1[15]; 82 unsigned char lut; /* OFFSET: 0x10 */ 83 unsigned char pad2[15]; 84 unsigned char status; /* OFFSET: 0x20 */ 85 unsigned char pad3[7]; 86 unsigned long vbl_addr; /* OFFSET: 0x28 */ 87 unsigned int status2; /* OFFSET: 0x2C */ 88 } __iomem *civic_cmap_regs; 89 90 static struct { 91 char pad1[0x40]; 92 unsigned char clut_waddr; /* 0x40 */ 93 char pad2; 94 unsigned char clut_data; /* 0x42 */ 95 char pad3[0x3]; 96 unsigned char clut_raddr; /* 0x46 */ 97 } __iomem *csc_cmap_regs; 98 99 /* The registers in these structs are in NuBus slot space */ 100 struct mdc_cmap_regs { 101 char pad1[0x200200]; 102 unsigned char addr; 103 char pad2[6]; 104 unsigned char lut; 105 }; 106 107 struct toby_cmap_regs { 108 char pad1[0x90018]; 109 unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */ 110 char pad2[3]; 111 unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */ 112 }; 113 114 struct jet_cmap_regs { 115 char pad1[0xe0e000]; 116 unsigned char addr; 117 unsigned char lut; 118 }; 119 120 #define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */ 121 122 static struct fb_var_screeninfo macfb_defined = { 123 .activate = FB_ACTIVATE_NOW, 124 .right_margin = 32, 125 .upper_margin = 16, 126 .lower_margin = 4, 127 .vsync_len = 4, 128 .vmode = FB_VMODE_NONINTERLACED, 129 }; 130 131 static struct fb_fix_screeninfo macfb_fix = { 132 .type = FB_TYPE_PACKED_PIXELS, 133 .accel = FB_ACCEL_NONE, 134 }; 135 136 static void *slot_addr; 137 static struct fb_info fb_info; 138 static u32 pseudo_palette[16]; 139 static int vidtest; 140 141 /* 142 * Unlike the Valkyrie, the DAFB cannot set individual colormap 143 * registers. Therefore, we do what the MacOS driver does (no 144 * kidding!) and simply set them one by one until we hit the one we 145 * want. 146 */ 147 static int dafb_setpalette(unsigned int regno, unsigned int red, 148 unsigned int green, unsigned int blue, 149 struct fb_info *info) 150 { 151 static int lastreg = -2; 152 unsigned long flags; 153 154 local_irq_save(flags); 155 156 /* 157 * fbdev will set an entire colourmap, but X won't. Hopefully 158 * this should accommodate both of them 159 */ 160 if (regno != lastreg + 1) { 161 int i; 162 163 /* Stab in the dark trying to reset the CLUT pointer */ 164 nubus_writel(0, &dafb_cmap_regs->reset); 165 nop(); 166 167 /* Loop until we get to the register we want */ 168 for (i = 0; i < regno; i++) { 169 nubus_writeb(info->cmap.red[i] >> 8, 170 &dafb_cmap_regs->lut); 171 nop(); 172 nubus_writeb(info->cmap.green[i] >> 8, 173 &dafb_cmap_regs->lut); 174 nop(); 175 nubus_writeb(info->cmap.blue[i] >> 8, 176 &dafb_cmap_regs->lut); 177 nop(); 178 } 179 } 180 181 nubus_writeb(red, &dafb_cmap_regs->lut); 182 nop(); 183 nubus_writeb(green, &dafb_cmap_regs->lut); 184 nop(); 185 nubus_writeb(blue, &dafb_cmap_regs->lut); 186 187 local_irq_restore(flags); 188 lastreg = regno; 189 return 0; 190 } 191 192 /* V8 and Brazil seem to use the same DAC. Sonora does as well. */ 193 static int v8_brazil_setpalette(unsigned int regno, unsigned int red, 194 unsigned int green, unsigned int blue, 195 struct fb_info *info) 196 { 197 unsigned int bpp = info->var.bits_per_pixel; 198 unsigned long flags; 199 200 local_irq_save(flags); 201 202 /* On these chips, the CLUT register numbers are spread out 203 * across the register space. Thus: 204 * In 8bpp, all regnos are valid. 205 * In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc 206 * In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff 207 */ 208 regno = (regno << (8 - bpp)) | (0xFF >> bpp); 209 nubus_writeb(regno, &v8_brazil_cmap_regs->addr); 210 nop(); 211 212 /* send one color channel at a time */ 213 nubus_writeb(red, &v8_brazil_cmap_regs->lut); 214 nop(); 215 nubus_writeb(green, &v8_brazil_cmap_regs->lut); 216 nop(); 217 nubus_writeb(blue, &v8_brazil_cmap_regs->lut); 218 219 local_irq_restore(flags); 220 return 0; 221 } 222 223 /* RAM-Based Video */ 224 static int rbv_setpalette(unsigned int regno, unsigned int red, 225 unsigned int green, unsigned int blue, 226 struct fb_info *info) 227 { 228 unsigned long flags; 229 230 local_irq_save(flags); 231 232 /* From the VideoToolbox driver. Seems to be saying that 233 * regno #254 and #255 are the important ones for 1-bit color, 234 * regno #252-255 are the important ones for 2-bit color, etc. 235 */ 236 regno += 256 - (1 << info->var.bits_per_pixel); 237 238 /* reset clut? (VideoToolbox sez "not necessary") */ 239 nubus_writeb(0xFF, &rbv_cmap_regs->cntl); 240 nop(); 241 242 /* tell clut which address to use. */ 243 nubus_writeb(regno, &rbv_cmap_regs->addr); 244 nop(); 245 246 /* send one color channel at a time. */ 247 nubus_writeb(red, &rbv_cmap_regs->lut); 248 nop(); 249 nubus_writeb(green, &rbv_cmap_regs->lut); 250 nop(); 251 nubus_writeb(blue, &rbv_cmap_regs->lut); 252 253 local_irq_restore(flags); 254 return 0; 255 } 256 257 /* Macintosh Display Card (8*24) */ 258 static int mdc_setpalette(unsigned int regno, unsigned int red, 259 unsigned int green, unsigned int blue, 260 struct fb_info *info) 261 { 262 struct mdc_cmap_regs *cmap_regs = slot_addr; 263 unsigned long flags; 264 265 local_irq_save(flags); 266 267 /* the nop's are there to order writes. */ 268 nubus_writeb(regno, &cmap_regs->addr); 269 nop(); 270 nubus_writeb(red, &cmap_regs->lut); 271 nop(); 272 nubus_writeb(green, &cmap_regs->lut); 273 nop(); 274 nubus_writeb(blue, &cmap_regs->lut); 275 276 local_irq_restore(flags); 277 return 0; 278 } 279 280 /* Toby frame buffer */ 281 static int toby_setpalette(unsigned int regno, unsigned int red, 282 unsigned int green, unsigned int blue, 283 struct fb_info *info) 284 { 285 struct toby_cmap_regs *cmap_regs = slot_addr; 286 unsigned int bpp = info->var.bits_per_pixel; 287 unsigned long flags; 288 289 red = ~red; 290 green = ~green; 291 blue = ~blue; 292 regno = (regno << (8 - bpp)) | (0xFF >> bpp); 293 294 local_irq_save(flags); 295 296 nubus_writeb(regno, &cmap_regs->addr); 297 nop(); 298 nubus_writeb(red, &cmap_regs->lut); 299 nop(); 300 nubus_writeb(green, &cmap_regs->lut); 301 nop(); 302 nubus_writeb(blue, &cmap_regs->lut); 303 304 local_irq_restore(flags); 305 return 0; 306 } 307 308 /* Jet frame buffer */ 309 static int jet_setpalette(unsigned int regno, unsigned int red, 310 unsigned int green, unsigned int blue, 311 struct fb_info *info) 312 { 313 struct jet_cmap_regs *cmap_regs = slot_addr; 314 unsigned long flags; 315 316 local_irq_save(flags); 317 318 nubus_writeb(regno, &cmap_regs->addr); 319 nop(); 320 nubus_writeb(red, &cmap_regs->lut); 321 nop(); 322 nubus_writeb(green, &cmap_regs->lut); 323 nop(); 324 nubus_writeb(blue, &cmap_regs->lut); 325 326 local_irq_restore(flags); 327 return 0; 328 } 329 330 /* 331 * Civic framebuffer -- Quadra AV built-in video. A chip 332 * called Sebastian holds the actual color palettes, and 333 * apparently, there are two different banks of 512K RAM 334 * which can act as separate framebuffers for doing video 335 * input and viewing the screen at the same time! The 840AV 336 * Can add another 1MB RAM to give the two framebuffers 337 * 1MB RAM apiece. 338 */ 339 static int civic_setpalette(unsigned int regno, unsigned int red, 340 unsigned int green, unsigned int blue, 341 struct fb_info *info) 342 { 343 unsigned long flags; 344 int clut_status; 345 346 local_irq_save(flags); 347 348 /* Set the register address */ 349 nubus_writeb(regno, &civic_cmap_regs->addr); 350 nop(); 351 352 /* 353 * Grab a status word and do some checking; 354 * Then finally write the clut! 355 */ 356 clut_status = nubus_readb(&civic_cmap_regs->status2); 357 358 if ((clut_status & 0x0008) == 0) 359 { 360 #if 0 361 if ((clut_status & 0x000D) != 0) 362 { 363 nubus_writeb(0x00, &civic_cmap_regs->lut); 364 nop(); 365 nubus_writeb(0x00, &civic_cmap_regs->lut); 366 nop(); 367 } 368 #endif 369 370 nubus_writeb(red, &civic_cmap_regs->lut); 371 nop(); 372 nubus_writeb(green, &civic_cmap_regs->lut); 373 nop(); 374 nubus_writeb(blue, &civic_cmap_regs->lut); 375 nop(); 376 nubus_writeb(0x00, &civic_cmap_regs->lut); 377 } 378 else 379 { 380 unsigned char junk; 381 382 junk = nubus_readb(&civic_cmap_regs->lut); 383 nop(); 384 junk = nubus_readb(&civic_cmap_regs->lut); 385 nop(); 386 junk = nubus_readb(&civic_cmap_regs->lut); 387 nop(); 388 junk = nubus_readb(&civic_cmap_regs->lut); 389 nop(); 390 391 if ((clut_status & 0x000D) != 0) 392 { 393 nubus_writeb(0x00, &civic_cmap_regs->lut); 394 nop(); 395 nubus_writeb(0x00, &civic_cmap_regs->lut); 396 nop(); 397 } 398 399 nubus_writeb(red, &civic_cmap_regs->lut); 400 nop(); 401 nubus_writeb(green, &civic_cmap_regs->lut); 402 nop(); 403 nubus_writeb(blue, &civic_cmap_regs->lut); 404 nop(); 405 nubus_writeb(junk, &civic_cmap_regs->lut); 406 } 407 408 local_irq_restore(flags); 409 return 0; 410 } 411 412 /* 413 * The CSC is the framebuffer on the PowerBook 190 series 414 * (and the 5300 too, but that's a PowerMac). This function 415 * brought to you in part by the ECSC driver for MkLinux. 416 */ 417 static int csc_setpalette(unsigned int regno, unsigned int red, 418 unsigned int green, unsigned int blue, 419 struct fb_info *info) 420 { 421 unsigned long flags; 422 423 local_irq_save(flags); 424 425 udelay(1); /* mklinux on PB 5300 waits for 260 ns */ 426 nubus_writeb(regno, &csc_cmap_regs->clut_waddr); 427 nubus_writeb(red, &csc_cmap_regs->clut_data); 428 nubus_writeb(green, &csc_cmap_regs->clut_data); 429 nubus_writeb(blue, &csc_cmap_regs->clut_data); 430 431 local_irq_restore(flags); 432 return 0; 433 } 434 435 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green, 436 unsigned blue, unsigned transp, 437 struct fb_info *fb_info) 438 { 439 /* 440 * Set a single color register. The values supplied are 441 * already rounded down to the hardware's capabilities 442 * (according to the entries in the `var' structure). 443 * Return non-zero for invalid regno. 444 */ 445 446 if (regno >= fb_info->cmap.len) 447 return 1; 448 449 if (fb_info->var.bits_per_pixel <= 8) { 450 switch (fb_info->var.bits_per_pixel) { 451 case 1: 452 /* We shouldn't get here */ 453 break; 454 case 2: 455 case 4: 456 case 8: 457 if (macfb_setpalette) 458 macfb_setpalette(regno, red >> 8, green >> 8, 459 blue >> 8, fb_info); 460 else 461 return 1; 462 break; 463 } 464 } else if (regno < 16) { 465 switch (fb_info->var.bits_per_pixel) { 466 case 16: 467 if (fb_info->var.red.offset == 10) { 468 /* 1:5:5:5 */ 469 ((u32*) (fb_info->pseudo_palette))[regno] = 470 ((red & 0xf800) >> 1) | 471 ((green & 0xf800) >> 6) | 472 ((blue & 0xf800) >> 11) | 473 ((transp != 0) << 15); 474 } else { 475 /* 0:5:6:5 */ 476 ((u32*) (fb_info->pseudo_palette))[regno] = 477 ((red & 0xf800) >> 0) | 478 ((green & 0xfc00) >> 5) | 479 ((blue & 0xf800) >> 11); 480 } 481 break; 482 /* 483 * 24-bit colour almost doesn't exist on 68k Macs -- 484 * http://support.apple.com/kb/TA28634 (Old Article: 10992) 485 */ 486 case 24: 487 case 32: 488 red >>= 8; 489 green >>= 8; 490 blue >>= 8; 491 ((u32 *)(fb_info->pseudo_palette))[regno] = 492 (red << fb_info->var.red.offset) | 493 (green << fb_info->var.green.offset) | 494 (blue << fb_info->var.blue.offset); 495 break; 496 } 497 } 498 499 return 0; 500 } 501 502 static struct fb_ops macfb_ops = { 503 .owner = THIS_MODULE, 504 .fb_setcolreg = macfb_setcolreg, 505 .fb_fillrect = cfb_fillrect, 506 .fb_copyarea = cfb_copyarea, 507 .fb_imageblit = cfb_imageblit, 508 }; 509 510 static void __init macfb_setup(char *options) 511 { 512 char *this_opt; 513 514 if (!options || !*options) 515 return; 516 517 while ((this_opt = strsep(&options, ",")) != NULL) { 518 if (!*this_opt) 519 continue; 520 521 if (!strcmp(this_opt, "inverse")) 522 fb_invert_cmaps(); 523 else 524 if (!strcmp(this_opt, "vidtest")) 525 vidtest = 1; /* enable experimental CLUT code */ 526 } 527 } 528 529 static void __init iounmap_macfb(void) 530 { 531 if (dafb_cmap_regs) 532 iounmap(dafb_cmap_regs); 533 if (v8_brazil_cmap_regs) 534 iounmap(v8_brazil_cmap_regs); 535 if (rbv_cmap_regs) 536 iounmap(rbv_cmap_regs); 537 if (civic_cmap_regs) 538 iounmap(civic_cmap_regs); 539 if (csc_cmap_regs) 540 iounmap(csc_cmap_regs); 541 } 542 543 static int __init macfb_init(void) 544 { 545 int video_cmap_len, video_is_nubus = 0; 546 struct nubus_rsrc *ndev = NULL; 547 char *option = NULL; 548 int err; 549 550 if (fb_get_options("macfb", &option)) 551 return -ENODEV; 552 macfb_setup(option); 553 554 if (!MACH_IS_MAC) 555 return -ENODEV; 556 557 if (mac_bi_data.id == MAC_MODEL_Q630 || 558 mac_bi_data.id == MAC_MODEL_P588) 559 return -ENODEV; /* See valkyriefb.c */ 560 561 macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF; 562 macfb_defined.yres = mac_bi_data.dimensions >> 16; 563 macfb_defined.bits_per_pixel = mac_bi_data.videodepth; 564 565 macfb_fix.line_length = mac_bi_data.videorow; 566 macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres; 567 /* Note: physical address (since 2.1.127) */ 568 macfb_fix.smem_start = mac_bi_data.videoaddr; 569 570 /* 571 * This is actually redundant with the initial mappings. 572 * However, there are some non-obvious aspects to the way 573 * those mappings are set up, so this is in fact the safest 574 * way to ensure that this driver will work on every possible Mac 575 */ 576 fb_info.screen_base = ioremap(mac_bi_data.videoaddr, 577 macfb_fix.smem_len); 578 if (!fb_info.screen_base) 579 return -ENODEV; 580 581 pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n", 582 macfb_fix.smem_start, fb_info.screen_base, 583 macfb_fix.smem_len / 1024); 584 pr_info("macfb: mode is %dx%dx%d, linelength=%d\n", 585 macfb_defined.xres, macfb_defined.yres, 586 macfb_defined.bits_per_pixel, macfb_fix.line_length); 587 588 /* Fill in the available video resolution */ 589 macfb_defined.xres_virtual = macfb_defined.xres; 590 macfb_defined.yres_virtual = macfb_defined.yres; 591 macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres); 592 macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres); 593 594 /* Some dummy values for timing to make fbset happy */ 595 macfb_defined.pixclock = 10000000 / macfb_defined.xres * 596 1000 / macfb_defined.yres; 597 macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8; 598 macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8; 599 600 switch (macfb_defined.bits_per_pixel) { 601 case 1: 602 macfb_defined.red.length = macfb_defined.bits_per_pixel; 603 macfb_defined.green.length = macfb_defined.bits_per_pixel; 604 macfb_defined.blue.length = macfb_defined.bits_per_pixel; 605 video_cmap_len = 2; 606 macfb_fix.visual = FB_VISUAL_MONO01; 607 break; 608 case 2: 609 case 4: 610 case 8: 611 macfb_defined.red.length = macfb_defined.bits_per_pixel; 612 macfb_defined.green.length = macfb_defined.bits_per_pixel; 613 macfb_defined.blue.length = macfb_defined.bits_per_pixel; 614 video_cmap_len = 1 << macfb_defined.bits_per_pixel; 615 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR; 616 break; 617 case 16: 618 macfb_defined.transp.offset = 15; 619 macfb_defined.transp.length = 1; 620 macfb_defined.red.offset = 10; 621 macfb_defined.red.length = 5; 622 macfb_defined.green.offset = 5; 623 macfb_defined.green.length = 5; 624 macfb_defined.blue.offset = 0; 625 macfb_defined.blue.length = 5; 626 video_cmap_len = 16; 627 /* 628 * Should actually be FB_VISUAL_DIRECTCOLOR, but this 629 * works too 630 */ 631 macfb_fix.visual = FB_VISUAL_TRUECOLOR; 632 break; 633 case 24: 634 case 32: 635 macfb_defined.red.offset = 16; 636 macfb_defined.red.length = 8; 637 macfb_defined.green.offset = 8; 638 macfb_defined.green.length = 8; 639 macfb_defined.blue.offset = 0; 640 macfb_defined.blue.length = 8; 641 video_cmap_len = 16; 642 macfb_fix.visual = FB_VISUAL_TRUECOLOR; 643 break; 644 default: 645 pr_err("macfb: unknown or unsupported bit depth: %d\n", 646 macfb_defined.bits_per_pixel); 647 err = -EINVAL; 648 goto fail_unmap; 649 } 650 651 /* 652 * We take a wild guess that if the video physical address is 653 * in nubus slot space, that the nubus card is driving video. 654 * Penguin really ought to tell us whether we are using internal 655 * video or not. 656 * Hopefully we only find one of them. Otherwise our NuBus 657 * code is really broken :-) 658 */ 659 660 for_each_func_rsrc(ndev) { 661 unsigned long base = ndev->board->slot_addr; 662 663 if (mac_bi_data.videoaddr < base || 664 mac_bi_data.videoaddr - base > 0xFFFFFF) 665 continue; 666 667 if (ndev->category != NUBUS_CAT_DISPLAY || 668 ndev->type != NUBUS_TYPE_VIDEO) 669 continue; 670 671 video_is_nubus = 1; 672 slot_addr = (unsigned char *)base; 673 674 switch(ndev->dr_hw) { 675 case NUBUS_DRHW_APPLE_MDC: 676 strcpy(macfb_fix.id, "Mac Disp. Card"); 677 macfb_setpalette = mdc_setpalette; 678 break; 679 case NUBUS_DRHW_APPLE_TFB: 680 strcpy(macfb_fix.id, "Toby"); 681 macfb_setpalette = toby_setpalette; 682 break; 683 case NUBUS_DRHW_APPLE_JET: 684 strcpy(macfb_fix.id, "Jet"); 685 macfb_setpalette = jet_setpalette; 686 break; 687 default: 688 strcpy(macfb_fix.id, "Generic NuBus"); 689 break; 690 } 691 } 692 693 /* If it's not a NuBus card, it must be internal video */ 694 if (!video_is_nubus) 695 switch (mac_bi_data.id) { 696 /* 697 * DAFB Quadras 698 * Note: these first four have the v7 DAFB, which is 699 * known to be rather unlike the ones used in the 700 * other models 701 */ 702 case MAC_MODEL_P475: 703 case MAC_MODEL_P475F: 704 case MAC_MODEL_P575: 705 case MAC_MODEL_Q605: 706 707 case MAC_MODEL_Q800: 708 case MAC_MODEL_Q650: 709 case MAC_MODEL_Q610: 710 case MAC_MODEL_C650: 711 case MAC_MODEL_C610: 712 case MAC_MODEL_Q700: 713 case MAC_MODEL_Q900: 714 case MAC_MODEL_Q950: 715 strcpy(macfb_fix.id, "DAFB"); 716 macfb_setpalette = dafb_setpalette; 717 dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); 718 break; 719 720 /* 721 * LC II uses the V8 framebuffer 722 */ 723 case MAC_MODEL_LCII: 724 strcpy(macfb_fix.id, "V8"); 725 macfb_setpalette = v8_brazil_setpalette; 726 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); 727 break; 728 729 /* 730 * IIvi, IIvx use the "Brazil" framebuffer (which is 731 * very much like the V8, it seems, and probably uses 732 * the same DAC) 733 */ 734 case MAC_MODEL_IIVI: 735 case MAC_MODEL_IIVX: 736 case MAC_MODEL_P600: 737 strcpy(macfb_fix.id, "Brazil"); 738 macfb_setpalette = v8_brazil_setpalette; 739 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); 740 break; 741 742 /* 743 * LC III (and friends) use the Sonora framebuffer 744 * Incidentally this is also used in the non-AV models 745 * of the x100 PowerMacs 746 * These do in fact seem to use the same DAC interface 747 * as the LC II. 748 */ 749 case MAC_MODEL_LCIII: 750 case MAC_MODEL_P520: 751 case MAC_MODEL_P550: 752 case MAC_MODEL_P460: 753 strcpy(macfb_fix.id, "Sonora"); 754 macfb_setpalette = v8_brazil_setpalette; 755 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); 756 break; 757 758 /* 759 * IIci and IIsi use the infamous RBV chip 760 * (the IIsi is just a rebadged and crippled 761 * IIci in a different case, BTW) 762 */ 763 case MAC_MODEL_IICI: 764 case MAC_MODEL_IISI: 765 strcpy(macfb_fix.id, "RBV"); 766 macfb_setpalette = rbv_setpalette; 767 rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); 768 break; 769 770 /* 771 * AVs use the Civic framebuffer 772 */ 773 case MAC_MODEL_Q840: 774 case MAC_MODEL_C660: 775 strcpy(macfb_fix.id, "Civic"); 776 macfb_setpalette = civic_setpalette; 777 civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000); 778 break; 779 780 781 /* 782 * Assorted weirdos 783 * We think this may be like the LC II 784 */ 785 case MAC_MODEL_LC: 786 strcpy(macfb_fix.id, "LC"); 787 if (vidtest) { 788 macfb_setpalette = v8_brazil_setpalette; 789 v8_brazil_cmap_regs = 790 ioremap(DAC_BASE, 0x1000); 791 } 792 break; 793 794 /* 795 * We think this may be like the LC II 796 */ 797 case MAC_MODEL_CCL: 798 strcpy(macfb_fix.id, "Color Classic"); 799 if (vidtest) { 800 macfb_setpalette = v8_brazil_setpalette; 801 v8_brazil_cmap_regs = 802 ioremap(DAC_BASE, 0x1000); 803 } 804 break; 805 806 /* 807 * And we *do* mean "weirdos" 808 */ 809 case MAC_MODEL_TV: 810 strcpy(macfb_fix.id, "Mac TV"); 811 break; 812 813 /* 814 * These don't have colour, so no need to worry 815 */ 816 case MAC_MODEL_SE30: 817 case MAC_MODEL_CLII: 818 strcpy(macfb_fix.id, "Monochrome"); 819 break; 820 821 /* 822 * Powerbooks are particularly difficult. Many of 823 * them have separate framebuffers for external and 824 * internal video, which is admittedly pretty cool, 825 * but will be a bit of a headache to support here. 826 * Also, many of them are grayscale, and we don't 827 * really support that. 828 */ 829 830 /* 831 * Slot 0 ROM says TIM. No external video. B&W. 832 */ 833 case MAC_MODEL_PB140: 834 case MAC_MODEL_PB145: 835 case MAC_MODEL_PB170: 836 strcpy(macfb_fix.id, "DDC"); 837 break; 838 839 /* 840 * Internal is GSC, External (if present) is ViSC 841 */ 842 case MAC_MODEL_PB150: /* no external video */ 843 case MAC_MODEL_PB160: 844 case MAC_MODEL_PB165: 845 case MAC_MODEL_PB180: 846 case MAC_MODEL_PB210: 847 case MAC_MODEL_PB230: 848 strcpy(macfb_fix.id, "GSC"); 849 break; 850 851 /* 852 * Internal is TIM, External is ViSC 853 */ 854 case MAC_MODEL_PB165C: 855 case MAC_MODEL_PB180C: 856 strcpy(macfb_fix.id, "TIM"); 857 break; 858 859 /* 860 * Internal is CSC, External is Keystone+Ariel. 861 */ 862 case MAC_MODEL_PB190: /* external video is optional */ 863 case MAC_MODEL_PB520: 864 case MAC_MODEL_PB250: 865 case MAC_MODEL_PB270C: 866 case MAC_MODEL_PB280: 867 case MAC_MODEL_PB280C: 868 strcpy(macfb_fix.id, "CSC"); 869 macfb_setpalette = csc_setpalette; 870 csc_cmap_regs = ioremap(CSC_BASE, 0x1000); 871 break; 872 873 default: 874 strcpy(macfb_fix.id, "Unknown"); 875 break; 876 } 877 878 fb_info.fbops = &macfb_ops; 879 fb_info.var = macfb_defined; 880 fb_info.fix = macfb_fix; 881 fb_info.pseudo_palette = pseudo_palette; 882 fb_info.flags = FBINFO_DEFAULT; 883 884 err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); 885 if (err) 886 goto fail_unmap; 887 888 err = register_framebuffer(&fb_info); 889 if (err) 890 goto fail_dealloc; 891 892 fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id); 893 894 return 0; 895 896 fail_dealloc: 897 fb_dealloc_cmap(&fb_info.cmap); 898 fail_unmap: 899 iounmap(fb_info.screen_base); 900 iounmap_macfb(); 901 return err; 902 } 903 904 module_init(macfb_init); 905 MODULE_LICENSE("GPL"); 906