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