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