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