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/sched.h>
 
  24 #include <linux/errno.h>
 
  25 #include <linux/string.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>
 
  34 #include <asm/setup.h>
 
  35 #include <asm/bootinfo.h>
 
  36 #include <asm/uaccess.h>
 
  37 #include <asm/pgtable.h>
 
  39 #include <asm/macintosh.h>
 
  41 #include <asm/machw.h>
 
  43 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
 
  44 #define DAC_BASE 0x50f24000
 
  46 /* Some addresses for the DAFB */
 
  47 #define DAFB_BASE 0xf9800200
 
  49 /* Address for the built-in Civic framebuffer in Quadra AVs */
 
  50 #define CIVIC_BASE 0x50f30800   /* Only tested on 660AV! */
 
  52 /* GSC (Gray Scale Controller) base address */
 
  53 #define GSC_BASE 0x50F20000
 
  55 /* CSC (Color Screen Controller) base address */
 
  56 #define CSC_BASE 0x50F20000
 
  58 static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
 
  59                                 unsigned int green, unsigned int blue,
 
  60                                 struct fb_info *info) = NULL;
 
  61 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
 
  62                                 unsigned int green, unsigned int blue,
 
  63                                 struct fb_info *info);
 
  64 static int dafb_setpalette (unsigned int regno, unsigned int red,
 
  65                             unsigned int green, unsigned int blue,
 
  66                             struct fb_info *fb_info);
 
  67 static int rbv_setpalette (unsigned int regno, unsigned int red,
 
  68                            unsigned int green, unsigned int blue,
 
  69                            struct fb_info *fb_info);
 
  70 static int mdc_setpalette (unsigned int regno, unsigned int red,
 
  71                            unsigned int green, unsigned int blue,
 
  72                            struct fb_info *fb_info);
 
  73 static int toby_setpalette (unsigned int regno, unsigned int red,
 
  74                             unsigned int green, unsigned int blue,
 
  75                             struct fb_info *fb_info);
 
  76 static int civic_setpalette (unsigned int regno, unsigned int red,
 
  77                              unsigned int green, unsigned int blue,
 
  78                              struct fb_info *fb_info);
 
  79 static int csc_setpalette (unsigned int regno, unsigned int red,
 
  80                            unsigned int green, unsigned int blue,
 
  81                            struct fb_info *fb_info);
 
  83 static volatile struct {
 
  85         /* Note: word-aligned */
 
  88 } *valkyrie_cmap_regs;
 
  90 static volatile struct {
 
  93 } *v8_brazil_cmap_regs;
 
  95 static volatile struct {
 
  97         char pad1[3]; /* word aligned */
 
  99         char pad2[3]; /* word aligned */
 
 100         unsigned char cntl; /* a guess as to purpose */
 
 103 static volatile struct {
 
 105         unsigned long pad1[3];
 
 106         unsigned char pad2[3];
 
 110 static 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 */
 
 121 static volatile struct {
 
 123         unsigned char   clut_waddr;     /* 0x40 */
 
 125         unsigned char   clut_data;      /* 0x42 */
 
 127         unsigned char   clut_raddr;     /* 0x46 */
 
 130 /* We will leave these the way they are for the time being */
 
 131 struct mdc_cmap_regs {
 
 138 struct toby_cmap_regs {
 
 140         unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
 
 142         unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
 
 145 struct jet_cmap_regs {
 
 151 #define PIXEL_TO_MM(a)  (((a)*10)/28)   /* width in mm at 72 dpi */     
 
 154 static int  video_slot = 0;
 
 156 static struct fb_var_screeninfo macfb_defined = {
 
 158         .activate       = FB_ACTIVATE_NOW,
 
 165         .vmode          = FB_VMODE_NONINTERLACED,
 
 168 static struct fb_fix_screeninfo macfb_fix = {
 
 170         .type   = FB_TYPE_PACKED_PIXELS,
 
 171         .accel  = FB_ACCEL_NONE,
 
 174 static struct fb_info fb_info;
 
 175 static u32 pseudo_palette[17];
 
 176 static int inverse   = 0;
 
 177 static int vidtest   = 0;
 
 179 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
 
 180                                 unsigned int green, unsigned int blue,
 
 181                                 struct fb_info *info)
 
 189         local_irq_save(flags);
 
 191         /* tell clut which address to fill */
 
 192         nubus_writeb(regno, &valkyrie_cmap_regs->addr);
 
 195         /* send one color channel at a time */
 
 196         nubus_writeb(red, &valkyrie_cmap_regs->lut);
 
 198         nubus_writeb(green, &valkyrie_cmap_regs->lut);
 
 200         nubus_writeb(blue, &valkyrie_cmap_regs->lut);
 
 202         local_irq_restore(flags);
 
 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
 
 210 static int dafb_setpalette (unsigned int regno, unsigned int red,
 
 211                             unsigned int green, unsigned int blue,
 
 212                             struct fb_info *info)
 
 214         /* FIXME: really, really need to use ioremap() here,
 
 215            phys_to_virt() doesn't work anymore */
 
 216         static int lastreg = -1;
 
 223         local_irq_save(flags);
 
 225         /* fbdev will set an entire colourmap, but X won't.  Hopefully
 
 226            this should accommodate both of them */
 
 227         if (regno != lastreg+1) {
 
 230                 /* Stab in the dark trying to reset the CLUT pointer */
 
 231                 nubus_writel(0, &dafb_cmap_regs->reset);
 
 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);
 
 238                         nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
 
 240                         nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
 
 245         nubus_writeb(red, &dafb_cmap_regs->lut);
 
 247         nubus_writeb(green, &dafb_cmap_regs->lut);
 
 249         nubus_writeb(blue, &dafb_cmap_regs->lut);
 
 251         local_irq_restore(flags);
 
 256 /* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
 
 257 static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
 
 258                                  unsigned int green, unsigned int blue,
 
 259                                  struct fb_info *info)  
 
 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;
 
 268         if (bpp > 8) return 1; /* failsafe */
 
 270         local_irq_save(flags);
 
 272         /* On these chips, the CLUT register numbers are spread out
 
 273            across the register space.  Thus:
 
 275            In 8bpp, all regnos are valid.
 
 277            In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
 
 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();
 
 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);
 
 288         local_irq_restore(flags);       
 
 292 static int rbv_setpalette (unsigned int regno, unsigned int red,
 
 293                            unsigned int green, unsigned int blue,
 
 294                            struct fb_info *info)
 
 297         unsigned char _red  =red>>8;
 
 298         unsigned char _green=green>>8;
 
 299         unsigned char _blue =blue>>8;
 
 300         unsigned char _regno;
 
 303         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
 
 305         local_irq_save(flags);
 
 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.
 
 311         _regno = regno + (256-(1 << info->var.bits_per_pixel));
 
 313         /* reset clut? (VideoToolbox sez "not necessary") */
 
 314         nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
 
 316         /* tell clut which address to use. */
 
 317         nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
 
 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);
 
 324         local_irq_restore(flags); /* done. */
 
 328 /* Macintosh Display Card (8x24) */
 
 329 static int mdc_setpalette(unsigned int regno, unsigned int red,
 
 330                           unsigned int green, unsigned int blue,
 
 331                           struct fb_info *info)
 
 333         volatile struct mdc_cmap_regs *cmap_regs =
 
 334                 nubus_slot_addr(video_slot);
 
 336         unsigned char _red  =red>>8;
 
 337         unsigned char _green=green>>8;
 
 338         unsigned char _blue =blue>>8;
 
 339         unsigned char _regno=regno;
 
 342         local_irq_save(flags);
 
 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);
 
 350         local_irq_restore(flags);
 
 354 /* Toby frame buffer */
 
 355 static int toby_setpalette(unsigned int regno, unsigned int red,
 
 356                            unsigned int green, unsigned int blue,
 
 357                            struct fb_info *info) 
 
 359         volatile struct toby_cmap_regs *cmap_regs =
 
 360                 nubus_slot_addr(video_slot);
 
 361         unsigned int bpp = info->var.bits_per_pixel;
 
 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);
 
 369         local_irq_save(flags);
 
 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);
 
 376         local_irq_restore(flags);
 
 380 /* Jet frame buffer */
 
 381 static int jet_setpalette(unsigned int regno, unsigned int red,
 
 382                           unsigned int green, unsigned int blue,
 
 383                           struct fb_info *info)
 
 385         volatile struct jet_cmap_regs *cmap_regs =
 
 386                 nubus_slot_addr(video_slot);
 
 388         unsigned char _red   = (red>>8);
 
 389         unsigned char _green = (green>>8);
 
 390         unsigned char _blue  = (blue>>8);
 
 393         local_irq_save(flags);
 
 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);
 
 400         local_irq_restore(flags);
 
 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 
 
 413  * FIXME: this doesn't seem to work anymore.
 
 415 static int civic_setpalette (unsigned int regno, unsigned int red,
 
 416                              unsigned int green, unsigned int blue,
 
 417                              struct fb_info *info)
 
 419         static int lastreg = -1;
 
 423         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
 
 429         local_irq_save(flags);
 
 432          * Set the register address
 
 434         nubus_writeb(regno, &civic_cmap_regs->addr); nop();
 
 437          * Wait for VBL interrupt here;
 
 438          * They're usually not enabled from Penguin, so we won't check
 
 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 */
 
 449                         usleep(10);     /* needed? */
 
 451                 /* do interrupt shutdown stuff here? */
 
 456          * Grab a status word and do some checking;
 
 457          * Then finally write the clut!
 
 459         clut_status =  nubus_readb(&civic_cmap_regs->status2);
 
 461         if ((clut_status & 0x0008) == 0)
 
 464                 if ((clut_status & 0x000D) != 0)
 
 466                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 467                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 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();
 
 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();
 
 485                 if ((clut_status & 0x000D) != 0)
 
 487                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 488                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
 
 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();
 
 497         local_irq_restore(flags);
 
 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.
 
 508 static int csc_setpalette (unsigned int regno, unsigned int red,
 
 509                            unsigned int green, unsigned int blue,
 
 510                            struct fb_info *info)
 
 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;
 
 520 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 
 521                            unsigned blue, unsigned transp,
 
 522                            struct fb_info *fb_info)
 
 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.
 
 531         if (regno >= fb_info->cmap.len)
 
 534         switch (fb_info->var.bits_per_pixel) {
 
 536                 /* We shouldn't get here */
 
 541                 if (macfb_setpalette)
 
 542                         macfb_setpalette(regno, red, green, blue, fb_info);
 
 547                 if (fb_info->var.red.offset == 10) {
 
 549                         ((u32*) (fb_info->pseudo_palette))[regno] =
 
 550                                         ((red   & 0xf800) >>  1) |
 
 551                                         ((green & 0xf800) >>  6) |
 
 552                                         ((blue  & 0xf800) >> 11) |
 
 553                                         ((transp != 0) << 15);
 
 556                         ((u32*) (fb_info->pseudo_palette))[regno] =
 
 558                                         ((green & 0xfc00) >>  5) |
 
 559                                         ((blue  & 0xf800) >> 11);
 
 562                 /* I'm pretty sure that one or the other of these
 
 563                    doesn't exist on 68k Macs */
 
 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);
 
 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);
 
 586 static 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,
 
 594 void __init macfb_setup(char *options)
 
 598         if (!options || !*options)
 
 601         while ((this_opt = strsep(&options, ",")) != NULL) {
 
 602                 if (!*this_opt) continue;
 
 604                 if (! strcmp(this_opt, "inverse"))
 
 606                 /* This means "turn on experimental CLUT code" */
 
 607                 else if (!strcmp(this_opt, "vidtest"))
 
 612 void __init macfb_init(void)
 
 614         int video_cmap_len, video_is_nubus = 0;
 
 615         struct nubus_dev* ndev = NULL;
 
 618         if (fb_get_options("macfb", &option))
 
 625         /* There can only be one internal video controller anyway so
 
 626            we're not too worried about this */
 
 627         macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
 
 628         macfb_defined.yres = mac_bi_data.dimensions >> 16;
 
 629         macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
 
 630         macfb_fix.line_length = mac_bi_data.videorow;
 
 631         macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
 
 632         /* Note: physical address (since 2.1.127) */
 
 633         macfb_fix.smem_start = mac_bi_data.videoaddr;
 
 634         /* This is actually redundant with the initial mappings.
 
 635            However, there are some non-obvious aspects to the way
 
 636            those mappings are set up, so this is in fact the safest
 
 637            way to ensure that this driver will work on every possible
 
 639         fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
 
 641         printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
 
 642                macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
 
 643         printk("macfb: mode is %dx%dx%d, linelength=%d\n",
 
 644                macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
 
 647          *      Fill in the available video resolution
 
 650         macfb_defined.xres_virtual   = macfb_defined.xres;
 
 651         macfb_defined.yres_virtual   = macfb_defined.yres;
 
 652         macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
 
 653         macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);  
 
 655         printk("macfb: scrolling: redraw\n");
 
 656         macfb_defined.yres_virtual = macfb_defined.yres;
 
 658         /* some dummy values for timing to make fbset happy */
 
 659         macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
 
 660         macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
 
 661         macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
 
 663         switch (macfb_defined.bits_per_pixel) {
 
 665                 /* XXX: I think this will catch any program that tries
 
 666                    to do FBIO_PUTCMAP when the visual is monochrome */
 
 667                 macfb_defined.red.length = macfb_defined.bits_per_pixel;
 
 668                 macfb_defined.green.length = macfb_defined.bits_per_pixel;
 
 669                 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
 
 671                 macfb_fix.visual = FB_VISUAL_MONO01;
 
 676                 macfb_defined.red.length = macfb_defined.bits_per_pixel;
 
 677                 macfb_defined.green.length = macfb_defined.bits_per_pixel;
 
 678                 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
 
 679                 video_cmap_len = 1 << macfb_defined.bits_per_pixel;
 
 680                 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
 
 683                 macfb_defined.transp.offset = 15;
 
 684                 macfb_defined.transp.length = 1;
 
 685                 macfb_defined.red.offset = 10;
 
 686                 macfb_defined.red.length = 5;
 
 687                 macfb_defined.green.offset = 5;
 
 688                 macfb_defined.green.length = 5;
 
 689                 macfb_defined.blue.offset = 0;
 
 690                 macfb_defined.blue.length = 5;
 
 691                 printk("macfb: directcolor: "
 
 692                        "size=1:5:5:5, shift=15:10:5:0\n");
 
 694                 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
 
 696                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 
 700                 /* XXX: have to test these... can any 68k Macs
 
 701                    actually do this on internal video? */
 
 702                 macfb_defined.red.offset = 16;
 
 703                 macfb_defined.red.length = 8;
 
 704                 macfb_defined.green.offset = 8;
 
 705                 macfb_defined.green.length = 8;
 
 706                 macfb_defined.blue.offset = 0;
 
 707                 macfb_defined.blue.length = 8;
 
 708                 printk("macfb: truecolor: "
 
 709                        "size=0:8:8:8, shift=0:16:8:0\n");
 
 711                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 
 714                 macfb_fix.visual = FB_VISUAL_MONO01;
 
 715                 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
 
 719         /* Hardware dependent stuff */
 
 720         /*  We take a wild guess that if the video physical address is
 
 721          *  in nubus slot space, that the nubus card is driving video.
 
 722          *  Penguin really ought to tell us whether we are using internal
 
 725         /* Hopefully we only find one of them.  Otherwise our NuBus
 
 726            code is really broken :-) */
 
 728         while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
 
 731                 if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
 
 732                       && (mac_bi_data.videoaddr <
 
 733                           (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
 
 736                 /* We should probably just use the slot address... */
 
 737                 video_slot = ndev->board->slot;
 
 739                 switch(ndev->dr_hw) {
 
 740                 case NUBUS_DRHW_APPLE_MDC:
 
 741                         strcat( macfb_fix.id, "Display Card" );
 
 742                         macfb_setpalette = mdc_setpalette;
 
 743                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 745                 case NUBUS_DRHW_APPLE_TFB:
 
 746                         strcat( macfb_fix.id, "Toby" );
 
 747                         macfb_setpalette = toby_setpalette;
 
 748                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 750                 case NUBUS_DRHW_APPLE_JET:
 
 751                         strcat( macfb_fix.id, "Jet");
 
 752                         macfb_setpalette = jet_setpalette;
 
 753                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 756                         strcat( macfb_fix.id, "Generic NuBus" );
 
 761         /* If it's not a NuBus card, it must be internal video */
 
 762         /* FIXME: this function is getting way too big.  (this driver
 
 765                 switch( mac_bi_data.id )
 
 767                         /* These don't have onboard video.  Eventually, we may
 
 768                            be able to write separate framebuffer drivers for
 
 769                            them (tobyfb.c, hiresfb.c, etc, etc) */
 
 774                         strcat( macfb_fix.id, "Generic NuBus" );
 
 777                         /* Valkyrie Quadras */
 
 779                         /* I'm not sure about this one */
 
 781                         strcat( macfb_fix.id, "Valkyrie built-in" );
 
 782                         macfb_setpalette = valkyrie_setpalette;
 
 783                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 784                         valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 788                         /* Note: these first four have the v7 DAFB, which is
 
 789                            known to be rather unlike the ones used in the
 
 792                 case MAC_MODEL_P475F:
 
 804                         strcat( macfb_fix.id, "DAFB built-in" );
 
 805                         macfb_setpalette = dafb_setpalette;
 
 806                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 807                         dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
 
 810                         /* LC II uses the V8 framebuffer */
 
 812                         strcat( macfb_fix.id, "V8 built-in" );
 
 813                         macfb_setpalette = v8_brazil_setpalette;
 
 814                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 815                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 818                         /* IIvi, IIvx use the "Brazil" framebuffer (which is
 
 819                            very much like the V8, it seems, and probably uses
 
 824                         strcat( macfb_fix.id, "Brazil built-in" );
 
 825                         macfb_setpalette = v8_brazil_setpalette;
 
 826                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 827                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 830                         /* LC III (and friends) use the Sonora framebuffer */
 
 831                         /* Incidentally this is also used in the non-AV models
 
 832                            of the x100 PowerMacs */
 
 833                         /* These do in fact seem to use the same DAC interface
 
 835                 case MAC_MODEL_LCIII:
 
 839                         macfb_setpalette = v8_brazil_setpalette;
 
 840                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 841                         strcat( macfb_fix.id, "Sonora built-in" );
 
 842                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 845                         /* IIci and IIsi use the infamous RBV chip
 
 846                            (the IIsi is just a rebadged and crippled
 
 847                            IIci in a different case, BTW) */
 
 850                         macfb_setpalette = rbv_setpalette;
 
 851                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 852                         strcat( macfb_fix.id, "RBV built-in" );
 
 853                         rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
 
 856                         /* AVs use the Civic framebuffer */
 
 859                         macfb_setpalette = civic_setpalette;
 
 860                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 861                         strcat( macfb_fix.id, "Civic built-in" );
 
 862                         civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
 
 866                         /* Write a setpalette function for your machine, then
 
 867                            you can add something similar here.  These are
 
 868                            grouped by classes of video chipsets.  Some of this
 
 869                            information is from the VideoToolbox "Bugs" web
 
 871                            http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
 
 873                         /* Assorted weirdos */
 
 874                         /* We think this may be like the LC II */
 
 877                                 macfb_setpalette = v8_brazil_setpalette;
 
 878                                 macfb_defined.activate = FB_ACTIVATE_NOW;
 
 879                                 v8_brazil_cmap_regs =
 
 880                                         ioremap(DAC_BASE, 0x1000);
 
 882                         strcat( macfb_fix.id, "LC built-in" );
 
 884                         /* We think this may be like the LC II */
 
 887                                 macfb_setpalette = v8_brazil_setpalette;
 
 888                                 macfb_defined.activate = FB_ACTIVATE_NOW;
 
 889                                 v8_brazil_cmap_regs =
 
 890                                         ioremap(DAC_BASE, 0x1000);
 
 892                         strcat( macfb_fix.id, "Color Classic built-in" );
 
 895                         /* And we *do* mean "weirdos" */
 
 897                         strcat( macfb_fix.id, "Mac TV built-in" );
 
 900                         /* These don't have colour, so no need to worry */
 
 903                         strcat( macfb_fix.id, "Monochrome built-in" );
 
 906                         /* Powerbooks are particularly difficult.  Many of
 
 907                            them have separate framebuffers for external and
 
 908                            internal video, which is admittedly pretty cool,
 
 909                            but will be a bit of a headache to support here.
 
 910                            Also, many of them are grayscale, and we don't
 
 911                            really support that. */
 
 913                 case MAC_MODEL_PB140:
 
 914                 case MAC_MODEL_PB145:
 
 915                 case MAC_MODEL_PB170:
 
 916                         strcat( macfb_fix.id, "DDC built-in" );
 
 919                         /* Internal is GSC, External (if present) is ViSC */
 
 920                 case MAC_MODEL_PB150:   /* no external video */
 
 921                 case MAC_MODEL_PB160:
 
 922                 case MAC_MODEL_PB165:
 
 923                 case MAC_MODEL_PB180:
 
 924                 case MAC_MODEL_PB210:
 
 925                 case MAC_MODEL_PB230:
 
 926                         strcat( macfb_fix.id, "GSC built-in" );
 
 929                         /* Internal is TIM, External is ViSC */
 
 930                 case MAC_MODEL_PB165C:
 
 931                 case MAC_MODEL_PB180C:
 
 932                         strcat( macfb_fix.id, "TIM built-in" );
 
 935                         /* Internal is CSC, External is Keystone+Ariel. */
 
 936                 case MAC_MODEL_PB190:   /* external video is optional */
 
 937                 case MAC_MODEL_PB520:
 
 938                 case MAC_MODEL_PB250:
 
 939                 case MAC_MODEL_PB270C:
 
 940                 case MAC_MODEL_PB280:
 
 941                 case MAC_MODEL_PB280C:
 
 942                         macfb_setpalette = csc_setpalette;
 
 943                         macfb_defined.activate = FB_ACTIVATE_NOW;
 
 944                         strcat( macfb_fix.id, "CSC built-in" );
 
 945                         csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
 
 949                         strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
 
 953         fb_info.fbops           = &macfb_ops;
 
 954         fb_info.var             = macfb_defined;
 
 955         fb_info.fix             = macfb_fix;
 
 956         fb_info.pseudo_palette  = pseudo_palette;
 
 957         fb_info.flags           = FBINFO_DEFAULT;
 
 959         fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
 
 961         if (register_framebuffer(&fb_info) < 0)
 
 964         printk("fb%d: %s frame buffer device\n",
 
 965                fb_info.node, fb_info.fix.id);
 
 968 module_init(macfb_init);
 
 969 MODULE_LICENSE("GPL");