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