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