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