1 /* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
 
   2    don't know how to set */
 
   4 /* (c) 1999 David Huggins-Daines <dhd@debian.org>
 
   6    Primarily based on vesafb.c, by Gerd Knorr
 
   7    (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
 
   9    Also uses information and code from:
 
  11    The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
 
  12    Mellinger, Mikael Forselius, Michael Schmitz, and others.
 
  14    valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
 
  15    Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
 
  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. */
 
  21 #include <linux/module.h>
 
  22 #include <linux/kernel.h>
 
  23 #include <linux/errno.h>
 
  24 #include <linux/string.h>
 
  26 #include <linux/slab.h>
 
  27 #include <linux/delay.h>
 
  28 #include <linux/nubus.h>
 
  29 #include <linux/init.h>
 
  32 #include <asm/setup.h>
 
  33 #include <asm/bootinfo.h>
 
  34 #include <asm/uaccess.h>
 
  35 #include <asm/pgtable.h>
 
  37 #include <asm/macintosh.h>
 
  39 #include <asm/machw.h>
 
  41 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
 
  42 #define DAC_BASE 0x50f24000
 
  44 /* Some addresses for the DAFB */
 
  45 #define DAFB_BASE 0xf9800200
 
  47 /* Address for the built-in Civic framebuffer in Quadra AVs */
 
  48 #define CIVIC_BASE 0x50f30800   /* Only tested on 660AV! */
 
  50 /* GSC (Gray Scale Controller) base address */
 
  51 #define GSC_BASE 0x50F20000
 
  53 /* CSC (Color Screen Controller) base address */
 
  54 #define CSC_BASE 0x50F20000
 
  56 static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
 
  57                                 unsigned int green, unsigned int blue,
 
  58                                 struct fb_info *info) = NULL;
 
  59 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
 
  60                                 unsigned int green, unsigned int blue,
 
  61                                 struct fb_info *info);
 
  62 static int dafb_setpalette (unsigned int regno, unsigned int red,
 
  63                             unsigned int green, unsigned int blue,
 
  64                             struct fb_info *fb_info);
 
  65 static int rbv_setpalette (unsigned int regno, unsigned int red,
 
  66                            unsigned int green, unsigned int blue,
 
  67                            struct fb_info *fb_info);
 
  68 static int mdc_setpalette (unsigned int regno, unsigned int red,
 
  69                            unsigned int green, unsigned int blue,
 
  70                            struct fb_info *fb_info);
 
  71 static int toby_setpalette (unsigned int regno, unsigned int red,
 
  72                             unsigned int green, unsigned int blue,
 
  73                             struct fb_info *fb_info);
 
  74 static int civic_setpalette (unsigned int regno, unsigned int red,
 
  75                              unsigned int green, unsigned int blue,
 
  76                              struct fb_info *fb_info);
 
  77 static int csc_setpalette (unsigned int regno, unsigned int red,
 
  78                            unsigned int green, unsigned int blue,
 
  79                            struct fb_info *fb_info);
 
  81 static volatile struct {
 
  83         /* Note: word-aligned */
 
  86 } *valkyrie_cmap_regs;
 
  88 static volatile struct {
 
  91 } *v8_brazil_cmap_regs;
 
  93 static volatile struct {
 
  95         char pad1[3]; /* word aligned */
 
  97         char pad2[3]; /* word aligned */
 
  98         unsigned char cntl; /* a guess as to purpose */
 
 101 static volatile struct {
 
 103         unsigned long pad1[3];
 
 104         unsigned char pad2[3];
 
 108 static 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 */
 
 119 static volatile struct {
 
 121         unsigned char   clut_waddr;     /* 0x40 */
 
 123         unsigned char   clut_data;      /* 0x42 */
 
 125         unsigned char   clut_raddr;     /* 0x46 */
 
 128 /* We will leave these the way they are for the time being */
 
 129 struct mdc_cmap_regs {
 
 136 struct toby_cmap_regs {
 
 138         unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
 
 140         unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
 
 143 struct jet_cmap_regs {
 
 149 #define PIXEL_TO_MM(a)  (((a)*10)/28)   /* width in mm at 72 dpi */     
 
 152 static int  video_slot = 0;
 
 154 static struct fb_var_screeninfo macfb_defined = {
 
 156         .activate       = FB_ACTIVATE_NOW,
 
 163         .vmode          = FB_VMODE_NONINTERLACED,
 
 166 static struct fb_fix_screeninfo macfb_fix = {
 
 168         .type   = FB_TYPE_PACKED_PIXELS,
 
 169         .accel  = FB_ACCEL_NONE,
 
 172 static struct fb_info fb_info;
 
 173 static u32 pseudo_palette[16];
 
 174 static int inverse   = 0;
 
 175 static int vidtest   = 0;
 
 177 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
 
 178                                 unsigned int green, unsigned int blue,
 
 179                                 struct fb_info *info)
 
 187         local_irq_save(flags);
 
 189         /* tell clut which address to fill */
 
 190         nubus_writeb(regno, &valkyrie_cmap_regs->addr);
 
 193         /* send one color channel at a time */
 
 194         nubus_writeb(red, &valkyrie_cmap_regs->lut);
 
 196         nubus_writeb(green, &valkyrie_cmap_regs->lut);
 
 198         nubus_writeb(blue, &valkyrie_cmap_regs->lut);
 
 200         local_irq_restore(flags);
 
 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
 
 208 static int dafb_setpalette (unsigned int regno, unsigned int red,
 
 209                             unsigned int green, unsigned int blue,
 
 210                             struct fb_info *info)
 
 212         /* FIXME: really, really need to use ioremap() here,
 
 213            phys_to_virt() doesn't work anymore */
 
 214         static int lastreg = -1;
 
 221         local_irq_save(flags);
 
 223         /* fbdev will set an entire colourmap, but X won't.  Hopefully
 
 224            this should accommodate both of them */
 
 225         if (regno != lastreg+1) {
 
 228                 /* Stab in the dark trying to reset the CLUT pointer */
 
 229                 nubus_writel(0, &dafb_cmap_regs->reset);
 
 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);
 
 236                         nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
 
 238                         nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
 
 243         nubus_writeb(red, &dafb_cmap_regs->lut);
 
 245         nubus_writeb(green, &dafb_cmap_regs->lut);
 
 247         nubus_writeb(blue, &dafb_cmap_regs->lut);
 
 249         local_irq_restore(flags);
 
 254 /* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
 
 255 static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
 
 256                                  unsigned int green, unsigned int blue,
 
 257                                  struct fb_info *info)  
 
 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;
 
 266         if (bpp > 8) return 1; /* failsafe */
 
 268         local_irq_save(flags);
 
 270         /* On these chips, the CLUT register numbers are spread out
 
 271            across the register space.  Thus:
 
 273            In 8bpp, all regnos are valid.
 
 275            In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
 
 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();
 
 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);
 
 286         local_irq_restore(flags);       
 
 290 static int rbv_setpalette (unsigned int regno, unsigned int red,
 
 291                            unsigned int green, unsigned int blue,
 
 292                            struct fb_info *info)
 
 295         unsigned char _red  =red>>8;
 
 296         unsigned char _green=green>>8;
 
 297         unsigned char _blue =blue>>8;
 
 298         unsigned char _regno;
 
 301         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
 
 303         local_irq_save(flags);
 
 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.
 
 309         _regno = regno + (256-(1 << info->var.bits_per_pixel));
 
 311         /* reset clut? (VideoToolbox sez "not necessary") */
 
 312         nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
 
 314         /* tell clut which address to use. */
 
 315         nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
 
 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);
 
 322         local_irq_restore(flags); /* done. */
 
 326 /* Macintosh Display Card (8x24) */
 
 327 static int mdc_setpalette(unsigned int regno, unsigned int red,
 
 328                           unsigned int green, unsigned int blue,
 
 329                           struct fb_info *info)
 
 331         volatile struct mdc_cmap_regs *cmap_regs =
 
 332                 nubus_slot_addr(video_slot);
 
 334         unsigned char _red  =red>>8;
 
 335         unsigned char _green=green>>8;
 
 336         unsigned char _blue =blue>>8;
 
 337         unsigned char _regno=regno;
 
 340         local_irq_save(flags);
 
 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);
 
 348         local_irq_restore(flags);
 
 352 /* Toby frame buffer */
 
 353 static int toby_setpalette(unsigned int regno, unsigned int red,
 
 354                            unsigned int green, unsigned int blue,
 
 355                            struct fb_info *info) 
 
 357         volatile struct toby_cmap_regs *cmap_regs =
 
 358                 nubus_slot_addr(video_slot);
 
 359         unsigned int bpp = info->var.bits_per_pixel;
 
 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);
 
 367         local_irq_save(flags);
 
 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);
 
 374         local_irq_restore(flags);
 
 378 /* Jet frame buffer */
 
 379 static int jet_setpalette(unsigned int regno, unsigned int red,
 
 380                           unsigned int green, unsigned int blue,
 
 381                           struct fb_info *info)
 
 383         volatile struct jet_cmap_regs *cmap_regs =
 
 384                 nubus_slot_addr(video_slot);
 
 386         unsigned char _red   = (red>>8);
 
 387         unsigned char _green = (green>>8);
 
 388         unsigned char _blue  = (blue>>8);
 
 391         local_irq_save(flags);
 
 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);
 
 398         local_irq_restore(flags);
 
 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 
 
 411  * FIXME: this doesn't seem to work anymore.
 
 413 static int civic_setpalette (unsigned int regno, unsigned int red,
 
 414                              unsigned int green, unsigned int blue,
 
 415                              struct fb_info *info)
 
 417         static int lastreg = -1;
 
 421         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
 
 427         local_irq_save(flags);
 
 430          * Set the register address
 
 432         nubus_writeb(regno, &civic_cmap_regs->addr); nop();
 
 435          * Wait for VBL interrupt here;
 
 436          * They're usually not enabled from Penguin, so we won't check
 
 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 */
 
 447                         usleep(10);     /* needed? */
 
 449                 /* do interrupt shutdown stuff here? */
 
 454          * Grab a status word and do some checking;
 
 455          * Then finally write the clut!
 
 457         clut_status =  nubus_readb(&civic_cmap_regs->status2);
 
 459         if ((clut_status & 0x0008) == 0)
 
 462                 if ((clut_status & 0x000D) != 0)
 
 464                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 465                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 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();
 
 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();
 
 483                 if ((clut_status & 0x000D) != 0)
 
 485                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 486                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 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();
 
 495         local_irq_restore(flags);
 
 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.
 
 506 static int csc_setpalette (unsigned int regno, unsigned int red,
 
 507                            unsigned int green, unsigned int blue,
 
 508                            struct fb_info *info)
 
 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;
 
 518 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 
 519                            unsigned blue, unsigned transp,
 
 520                            struct fb_info *fb_info)
 
 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.
 
 529         if (regno >= fb_info->cmap.len)
 
 532         if (fb_info->var.bits_per_pixel <= 8) {
 
 533                 switch (fb_info->var.bits_per_pixel) {
 
 535                         /* We shouldn't get here */
 
 540                         if (macfb_setpalette)
 
 541                                 macfb_setpalette(regno, red, green, blue,
 
 547         } else if (regno < 16) {
 
 548                 switch (fb_info->var.bits_per_pixel) {
 
 550                         if (fb_info->var.red.offset == 10) {
 
 552                                 ((u32*) (fb_info->pseudo_palette))[regno] =
 
 553                                         ((red   & 0xf800) >>  1) |
 
 554                                         ((green & 0xf800) >>  6) |
 
 555                                         ((blue  & 0xf800) >> 11) |
 
 556                                         ((transp != 0) << 15);
 
 559                                 ((u32*) (fb_info->pseudo_palette))[regno] =
 
 561                                         ((green & 0xfc00) >>  5) |
 
 562                                         ((blue  & 0xf800) >> 11);
 
 565                         /* I'm pretty sure that one or the other of these
 
 566                            doesn't exist on 68k Macs */
 
 571                         ((u32 *)(fb_info->pseudo_palette))[regno] =
 
 572                                 (red   << fb_info->var.red.offset)   |
 
 573                                 (green << fb_info->var.green.offset) |
 
 574                                 (blue  << fb_info->var.blue.offset);
 
 580                         ((u32 *)(fb_info->pseudo_palette))[regno] =
 
 581                                 (red   << fb_info->var.red.offset)   |
 
 582                                 (green << fb_info->var.green.offset) |
 
 583                                 (blue  << fb_info->var.blue.offset);
 
 591 static struct fb_ops macfb_ops = {
 
 592         .owner          = THIS_MODULE,
 
 593         .fb_setcolreg   = macfb_setcolreg,
 
 594         .fb_fillrect    = cfb_fillrect,
 
 595         .fb_copyarea    = cfb_copyarea,
 
 596         .fb_imageblit   = cfb_imageblit,
 
 599 void __init macfb_setup(char *options)
 
 603         if (!options || !*options)
 
 606         while ((this_opt = strsep(&options, ",")) != NULL) {
 
 607                 if (!*this_opt) continue;
 
 609                 if (! strcmp(this_opt, "inverse"))
 
 611                 /* This means "turn on experimental CLUT code" */
 
 612                 else if (!strcmp(this_opt, "vidtest"))
 
 617 static void __init iounmap_macfb(void)
 
 619         if (valkyrie_cmap_regs)
 
 620                 iounmap(valkyrie_cmap_regs);
 
 622                 iounmap(dafb_cmap_regs);
 
 623         if (v8_brazil_cmap_regs)
 
 624                 iounmap(v8_brazil_cmap_regs);
 
 626                 iounmap(rbv_cmap_regs);
 
 628                 iounmap(civic_cmap_regs);
 
 630                 iounmap(csc_cmap_regs);
 
 633 static int __init macfb_init(void)
 
 635         int video_cmap_len, video_is_nubus = 0;
 
 636         struct nubus_dev* ndev = NULL;
 
 640         if (fb_get_options("macfb", &option))
 
 647         /* There can only be one internal video controller anyway so
 
 648            we're not too worried about this */
 
 649         macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
 
 650         macfb_defined.yres = mac_bi_data.dimensions >> 16;
 
 651         macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
 
 652         macfb_fix.line_length = mac_bi_data.videorow;
 
 653         macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
 
 654         /* Note: physical address (since 2.1.127) */
 
 655         macfb_fix.smem_start = mac_bi_data.videoaddr;
 
 656         /* This is actually redundant with the initial mappings.
 
 657            However, there are some non-obvious aspects to the way
 
 658            those mappings are set up, so this is in fact the safest
 
 659            way to ensure that this driver will work on every possible
 
 661         fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
 
 663         printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
 
 664                macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
 
 665         printk("macfb: mode is %dx%dx%d, linelength=%d\n",
 
 666                macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
 
 669          *      Fill in the available video resolution
 
 672         macfb_defined.xres_virtual   = macfb_defined.xres;
 
 673         macfb_defined.yres_virtual   = macfb_defined.yres;
 
 674         macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
 
 675         macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);  
 
 677         printk("macfb: scrolling: redraw\n");
 
 678         macfb_defined.yres_virtual = macfb_defined.yres;
 
 680         /* some dummy values for timing to make fbset happy */
 
 681         macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
 
 682         macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
 
 683         macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
 
 685         switch (macfb_defined.bits_per_pixel) {
 
 687                 /* XXX: I think this will catch any program that tries
 
 688                    to do FBIO_PUTCMAP when the visual is monochrome */
 
 689                 macfb_defined.red.length = macfb_defined.bits_per_pixel;
 
 690                 macfb_defined.green.length = macfb_defined.bits_per_pixel;
 
 691                 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
 
 693                 macfb_fix.visual = FB_VISUAL_MONO01;
 
 698                 macfb_defined.red.length = macfb_defined.bits_per_pixel;
 
 699                 macfb_defined.green.length = macfb_defined.bits_per_pixel;
 
 700                 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
 
 701                 video_cmap_len = 1 << macfb_defined.bits_per_pixel;
 
 702                 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
 
 705                 macfb_defined.transp.offset = 15;
 
 706                 macfb_defined.transp.length = 1;
 
 707                 macfb_defined.red.offset = 10;
 
 708                 macfb_defined.red.length = 5;
 
 709                 macfb_defined.green.offset = 5;
 
 710                 macfb_defined.green.length = 5;
 
 711                 macfb_defined.blue.offset = 0;
 
 712                 macfb_defined.blue.length = 5;
 
 713                 printk("macfb: directcolor: "
 
 714                        "size=1:5:5:5, shift=15:10:5:0\n");
 
 716                 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
 
 718                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 
 722                 /* XXX: have to test these... can any 68k Macs
 
 723                    actually do this on internal video? */
 
 724                 macfb_defined.red.offset = 16;
 
 725                 macfb_defined.red.length = 8;
 
 726                 macfb_defined.green.offset = 8;
 
 727                 macfb_defined.green.length = 8;
 
 728                 macfb_defined.blue.offset = 0;
 
 729                 macfb_defined.blue.length = 8;
 
 730                 printk("macfb: truecolor: "
 
 731                        "size=0:8:8:8, shift=0:16:8:0\n");
 
 733                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 
 736                 macfb_fix.visual = FB_VISUAL_MONO01;
 
 737                 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
 
 741         /* Hardware dependent stuff */
 
 742         /*  We take a wild guess that if the video physical address is
 
 743          *  in nubus slot space, that the nubus card is driving video.
 
 744          *  Penguin really ought to tell us whether we are using internal
 
 747         /* Hopefully we only find one of them.  Otherwise our NuBus
 
 748            code is really broken :-) */
 
 750         while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
 
 753                 if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
 
 754                       && (mac_bi_data.videoaddr <
 
 755                           (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
 
 758                 /* We should probably just use the slot address... */
 
 759                 video_slot = ndev->board->slot;
 
 761                 switch(ndev->dr_hw) {
 
 762                 case NUBUS_DRHW_APPLE_MDC:
 
 763                         strcat( macfb_fix.id, "Display Card" );
 
 764                         macfb_setpalette = mdc_setpalette;
 
 765                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 767                 case NUBUS_DRHW_APPLE_TFB:
 
 768                         strcat( macfb_fix.id, "Toby" );
 
 769                         macfb_setpalette = toby_setpalette;
 
 770                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 772                 case NUBUS_DRHW_APPLE_JET:
 
 773                         strcat( macfb_fix.id, "Jet");
 
 774                         macfb_setpalette = jet_setpalette;
 
 775                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 778                         strcat( macfb_fix.id, "Generic NuBus" );
 
 783         /* If it's not a NuBus card, it must be internal video */
 
 784         /* FIXME: this function is getting way too big.  (this driver
 
 787                 switch( mac_bi_data.id )
 
 789                         /* These don't have onboard video.  Eventually, we may
 
 790                            be able to write separate framebuffer drivers for
 
 791                            them (tobyfb.c, hiresfb.c, etc, etc) */
 
 796                         strcat( macfb_fix.id, "Generic NuBus" );
 
 799                         /* Valkyrie Quadras */
 
 801                         /* I'm not sure about this one */
 
 803                         strcat( macfb_fix.id, "Valkyrie built-in" );
 
 804                         macfb_setpalette = valkyrie_setpalette;
 
 805                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 806                         valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 810                         /* Note: these first four have the v7 DAFB, which is
 
 811                            known to be rather unlike the ones used in the
 
 814                 case MAC_MODEL_P475F:
 
 826                         strcat( macfb_fix.id, "DAFB built-in" );
 
 827                         macfb_setpalette = dafb_setpalette;
 
 828                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 829                         dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
 
 832                         /* LC II uses the V8 framebuffer */
 
 834                         strcat( macfb_fix.id, "V8 built-in" );
 
 835                         macfb_setpalette = v8_brazil_setpalette;
 
 836                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 837                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 840                         /* IIvi, IIvx use the "Brazil" framebuffer (which is
 
 841                            very much like the V8, it seems, and probably uses
 
 846                         strcat( macfb_fix.id, "Brazil built-in" );
 
 847                         macfb_setpalette = v8_brazil_setpalette;
 
 848                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 849                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 852                         /* LC III (and friends) use the Sonora framebuffer */
 
 853                         /* Incidentally this is also used in the non-AV models
 
 854                            of the x100 PowerMacs */
 
 855                         /* These do in fact seem to use the same DAC interface
 
 857                 case MAC_MODEL_LCIII:
 
 861                         macfb_setpalette = v8_brazil_setpalette;
 
 862                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 863                         strcat( macfb_fix.id, "Sonora built-in" );
 
 864                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 867                         /* IIci and IIsi use the infamous RBV chip
 
 868                            (the IIsi is just a rebadged and crippled
 
 869                            IIci in a different case, BTW) */
 
 872                         macfb_setpalette = rbv_setpalette;
 
 873                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 874                         strcat( macfb_fix.id, "RBV built-in" );
 
 875                         rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 878                         /* AVs use the Civic framebuffer */
 
 881                         macfb_setpalette = civic_setpalette;
 
 882                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 883                         strcat( macfb_fix.id, "Civic built-in" );
 
 884                         civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
 
 888                         /* Write a setpalette function for your machine, then
 
 889                            you can add something similar here.  These are
 
 890                            grouped by classes of video chipsets.  Some of this
 
 891                            information is from the VideoToolbox "Bugs" web
 
 893                            http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
 
 895                         /* Assorted weirdos */
 
 896                         /* We think this may be like the LC II */
 
 899                                 macfb_setpalette = v8_brazil_setpalette;
 
 900                                 macfb_defined.activate = FB_ACTIVATE_NOW;
 
 901                                 v8_brazil_cmap_regs =
 
 902                                         ioremap(DAC_BASE, 0x1000);
 
 904                         strcat( macfb_fix.id, "LC built-in" );
 
 906                         /* We think this may be like the LC II */
 
 909                                 macfb_setpalette = v8_brazil_setpalette;
 
 910                                 macfb_defined.activate = FB_ACTIVATE_NOW;
 
 911                                 v8_brazil_cmap_regs =
 
 912                                         ioremap(DAC_BASE, 0x1000);
 
 914                         strcat( macfb_fix.id, "Color Classic built-in" );
 
 917                         /* And we *do* mean "weirdos" */
 
 919                         strcat( macfb_fix.id, "Mac TV built-in" );
 
 922                         /* These don't have colour, so no need to worry */
 
 925                         strcat( macfb_fix.id, "Monochrome built-in" );
 
 928                         /* Powerbooks are particularly difficult.  Many of
 
 929                            them have separate framebuffers for external and
 
 930                            internal video, which is admittedly pretty cool,
 
 931                            but will be a bit of a headache to support here.
 
 932                            Also, many of them are grayscale, and we don't
 
 933                            really support that. */
 
 935                 case MAC_MODEL_PB140:
 
 936                 case MAC_MODEL_PB145:
 
 937                 case MAC_MODEL_PB170:
 
 938                         strcat( macfb_fix.id, "DDC built-in" );
 
 941                         /* Internal is GSC, External (if present) is ViSC */
 
 942                 case MAC_MODEL_PB150:   /* no external video */
 
 943                 case MAC_MODEL_PB160:
 
 944                 case MAC_MODEL_PB165:
 
 945                 case MAC_MODEL_PB180:
 
 946                 case MAC_MODEL_PB210:
 
 947                 case MAC_MODEL_PB230:
 
 948                         strcat( macfb_fix.id, "GSC built-in" );
 
 951                         /* Internal is TIM, External is ViSC */
 
 952                 case MAC_MODEL_PB165C:
 
 953                 case MAC_MODEL_PB180C:
 
 954                         strcat( macfb_fix.id, "TIM built-in" );
 
 957                         /* Internal is CSC, External is Keystone+Ariel. */
 
 958                 case MAC_MODEL_PB190:   /* external video is optional */
 
 959                 case MAC_MODEL_PB520:
 
 960                 case MAC_MODEL_PB250:
 
 961                 case MAC_MODEL_PB270C:
 
 962                 case MAC_MODEL_PB280:
 
 963                 case MAC_MODEL_PB280C:
 
 964                         macfb_setpalette = csc_setpalette;
 
 965                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 966                         strcat( macfb_fix.id, "CSC built-in" );
 
 967                         csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
 
 971                         strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
 
 975         fb_info.fbops           = &macfb_ops;
 
 976         fb_info.var             = macfb_defined;
 
 977         fb_info.fix             = macfb_fix;
 
 978         fb_info.pseudo_palette  = pseudo_palette;
 
 979         fb_info.flags           = FBINFO_DEFAULT;
 
 981         fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
 
 983         err = register_framebuffer(&fb_info);
 
 985                 printk("fb%d: %s frame buffer device\n",
 
 986                        fb_info.node, fb_info.fix.id);
 
 988                 iounmap(fb_info.screen_base);
 
 994 module_init(macfb_init);
 
 995 MODULE_LICENSE("GPL");