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        pr_info("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        pr_info("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                macfb_defined.red.length = macfb_defined.bits_per_pixel;
 617                macfb_defined.green.length = macfb_defined.bits_per_pixel;
 618                macfb_defined.blue.length = macfb_defined.bits_per_pixel;
 619                video_cmap_len = 2;
 620                macfb_fix.visual = FB_VISUAL_MONO01;
 621                break;
 622        case 2:
 623        case 4:
 624        case 8:
 625                macfb_defined.red.length = macfb_defined.bits_per_pixel;
 626                macfb_defined.green.length = macfb_defined.bits_per_pixel;
 627                macfb_defined.blue.length = macfb_defined.bits_per_pixel;
 628                video_cmap_len = 1 << macfb_defined.bits_per_pixel;
 629                macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
 630                break;
 631        case 16:
 632                macfb_defined.transp.offset = 15;
 633                macfb_defined.transp.length = 1;
 634                macfb_defined.red.offset = 10;
 635                macfb_defined.red.length = 5;
 636                macfb_defined.green.offset = 5;
 637                macfb_defined.green.length = 5;
 638                macfb_defined.blue.offset = 0;
 639                macfb_defined.blue.length = 5;
 640                video_cmap_len = 16;
 641                /*
 642                 * Should actually be FB_VISUAL_DIRECTCOLOR, but this
 643                 * works too
 644                 */
 645                macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 646                break;
 647        case 24:
 648        case 32:
 649                macfb_defined.red.offset = 16;
 650                macfb_defined.red.length = 8;
 651                macfb_defined.green.offset = 8;
 652                macfb_defined.green.length = 8;
 653                macfb_defined.blue.offset = 0;
 654                macfb_defined.blue.length = 8;
 655                video_cmap_len = 16;
 656                macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 657                break;
 658        default:
 659                pr_err("macfb: unknown or unsupported bit depth: %d\n",
 660                       macfb_defined.bits_per_pixel);
 661                err = -EINVAL;
 662                goto fail_unmap;
 663        }
 664        
 665        /*
 666         * We take a wild guess that if the video physical address is
 667         * in nubus slot space, that the nubus card is driving video.
 668         * Penguin really ought to tell us whether we are using internal
 669         * video or not.
 670         * Hopefully we only find one of them.  Otherwise our NuBus
 671         * code is really broken :-)
 672         */
 673
 674        while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY,
 675                                       NUBUS_TYPE_VIDEO, ndev)))
 676        {
 677                unsigned long base = ndev->board->slot_addr;
 678
 679                if (mac_bi_data.videoaddr < base ||
 680                    mac_bi_data.videoaddr - base > 0xFFFFFF)
 681                        continue;
 682
 683                video_is_nubus = 1;
 684                slot_addr = (unsigned char *)base;
 685
 686                switch(ndev->dr_hw) {
 687                case NUBUS_DRHW_APPLE_MDC:
 688                        strcpy(macfb_fix.id, "Mac Disp. Card");
 689                        macfb_setpalette = mdc_setpalette;
 690                        macfb_defined.activate = FB_ACTIVATE_NOW;
 691                        break;
 692                case NUBUS_DRHW_APPLE_TFB:
 693                        strcpy(macfb_fix.id, "Toby");
 694                        macfb_setpalette = toby_setpalette;
 695                        macfb_defined.activate = FB_ACTIVATE_NOW;
 696                        break;
 697                case NUBUS_DRHW_APPLE_JET:
 698                        strcpy(macfb_fix.id, "Jet");
 699                        macfb_setpalette = jet_setpalette;
 700                        macfb_defined.activate = FB_ACTIVATE_NOW;
 701                        break;
 702                default:
 703                        strcpy(macfb_fix.id, "Generic NuBus");
 704                        break;
 705                }
 706        }
 707
 708        /* If it's not a NuBus card, it must be internal video */
 709        if (!video_is_nubus)
 710                switch (mac_bi_data.id) {
 711                /*
 712                 * DAFB Quadras
 713                 * Note: these first four have the v7 DAFB, which is
 714                 * known to be rather unlike the ones used in the
 715                 * other models
 716                 */
 717                case MAC_MODEL_P475:
 718                case MAC_MODEL_P475F:
 719                case MAC_MODEL_P575:
 720                case MAC_MODEL_Q605:
 721
 722                case MAC_MODEL_Q800:
 723                case MAC_MODEL_Q650:
 724                case MAC_MODEL_Q610:
 725                case MAC_MODEL_C650:
 726                case MAC_MODEL_C610:
 727                case MAC_MODEL_Q700:
 728                case MAC_MODEL_Q900:
 729                case MAC_MODEL_Q950:
 730                        strcpy(macfb_fix.id, "DAFB");
 731                        macfb_setpalette = dafb_setpalette;
 732                        dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
 733                        macfb_defined.activate = FB_ACTIVATE_NOW;
 734                        break;
 735
 736                /*
 737                 * LC II uses the V8 framebuffer
 738                 */
 739                case MAC_MODEL_LCII:
 740                        strcpy(macfb_fix.id, "V8");
 741                        macfb_setpalette = v8_brazil_setpalette;
 742                        v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 743                        macfb_defined.activate = FB_ACTIVATE_NOW;
 744                        break;
 745
 746                /*
 747                 * IIvi, IIvx use the "Brazil" framebuffer (which is
 748                 * very much like the V8, it seems, and probably uses
 749                 * the same DAC)
 750                 */
 751                case MAC_MODEL_IIVI:
 752                case MAC_MODEL_IIVX:
 753                case MAC_MODEL_P600:
 754                        strcpy(macfb_fix.id, "Brazil");
 755                        macfb_setpalette = v8_brazil_setpalette;
 756                        v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 757                        macfb_defined.activate = FB_ACTIVATE_NOW;
 758                        break;
 759
 760                /*
 761                 * LC III (and friends) use the Sonora framebuffer
 762                 * Incidentally this is also used in the non-AV models
 763                 * of the x100 PowerMacs
 764                 * These do in fact seem to use the same DAC interface
 765                 * as the LC II.
 766                 */
 767                case MAC_MODEL_LCIII:
 768                case MAC_MODEL_P520:
 769                case MAC_MODEL_P550:
 770                case MAC_MODEL_P460:
 771                        strcpy(macfb_fix.id, "Sonora");
 772                        macfb_setpalette = v8_brazil_setpalette;
 773                        v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 774                        macfb_defined.activate = FB_ACTIVATE_NOW;
 775                        break;
 776
 777                /*
 778                 * IIci and IIsi use the infamous RBV chip
 779                 * (the IIsi is just a rebadged and crippled
 780                 * IIci in a different case, BTW)
 781                 */
 782                case MAC_MODEL_IICI:
 783                case MAC_MODEL_IISI:
 784                        strcpy(macfb_fix.id, "RBV");
 785                        macfb_setpalette = rbv_setpalette;
 786                        rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
 787                        macfb_defined.activate = FB_ACTIVATE_NOW;
 788                        break;
 789
 790                /*
 791                 * AVs use the Civic framebuffer
 792                 */
 793                case MAC_MODEL_Q840:
 794                case MAC_MODEL_C660:
 795                        strcpy(macfb_fix.id, "Civic");
 796                        macfb_setpalette = civic_setpalette;
 797                        civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
 798                        macfb_defined.activate = FB_ACTIVATE_NOW;
 799                        break;
 800
 801                
 802                /*
 803                 * Assorted weirdos
 804                 * We think this may be like the LC II
 805                 */
 806                case MAC_MODEL_LC:
 807                        strcpy(macfb_fix.id, "LC");
 808                        if (vidtest) {
 809                                macfb_setpalette = v8_brazil_setpalette;
 810                                v8_brazil_cmap_regs =
 811                                        ioremap(DAC_BASE, 0x1000);
 812                                macfb_defined.activate = FB_ACTIVATE_NOW;
 813                        }
 814                        break;
 815
 816                /*
 817                 * We think this may be like the LC II
 818                 */
 819                case MAC_MODEL_CCL:
 820                        strcpy(macfb_fix.id, "Color Classic");
 821                        if (vidtest) {
 822                                macfb_setpalette = v8_brazil_setpalette;
 823                                v8_brazil_cmap_regs =
 824                                        ioremap(DAC_BASE, 0x1000);
 825                                macfb_defined.activate = FB_ACTIVATE_NOW;
 826                        }
 827                        break;
 828
 829                /*
 830                 * And we *do* mean "weirdos"
 831                 */
 832                case MAC_MODEL_TV:
 833                        strcpy(macfb_fix.id, "Mac TV");
 834                        break;
 835
 836                /*
 837                 * These don't have colour, so no need to worry
 838                 */
 839                case MAC_MODEL_SE30:
 840                case MAC_MODEL_CLII:
 841                        strcpy(macfb_fix.id, "Monochrome");
 842                        break;
 843
 844                /*
 845                 * Powerbooks are particularly difficult.  Many of
 846                 * them have separate framebuffers for external and
 847                 * internal video, which is admittedly pretty cool,
 848                 * but will be a bit of a headache to support here.
 849                 * Also, many of them are grayscale, and we don't
 850                 * really support that.
 851                 */
 852
 853                /*
 854                 * Slot 0 ROM says TIM. No external video. B&W.
 855                 */
 856                case MAC_MODEL_PB140:
 857                case MAC_MODEL_PB145:
 858                case MAC_MODEL_PB170:
 859                        strcpy(macfb_fix.id, "DDC");
 860                        break;
 861
 862                /*
 863                 * Internal is GSC, External (if present) is ViSC
 864                 */
 865                case MAC_MODEL_PB150:   /* no external video */
 866                case MAC_MODEL_PB160:
 867                case MAC_MODEL_PB165:
 868                case MAC_MODEL_PB180:
 869                case MAC_MODEL_PB210:
 870                case MAC_MODEL_PB230:
 871                        strcpy(macfb_fix.id, "GSC");
 872                        break;
 873
 874                /*
 875                 * Internal is TIM, External is ViSC
 876                 */
 877                case MAC_MODEL_PB165C:
 878                case MAC_MODEL_PB180C:
 879                        strcpy(macfb_fix.id, "TIM");
 880                        break;
 881
 882                /*
 883                 * Internal is CSC, External is Keystone+Ariel.
 884                 */
 885                case MAC_MODEL_PB190:   /* external video is optional */
 886                case MAC_MODEL_PB520:
 887                case MAC_MODEL_PB250:
 888                case MAC_MODEL_PB270C:
 889                case MAC_MODEL_PB280:
 890                case MAC_MODEL_PB280C:
 891                        strcpy(macfb_fix.id, "CSC");
 892                        macfb_setpalette = csc_setpalette;
 893                        csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
 894                        macfb_defined.activate = FB_ACTIVATE_NOW;
 895                        break;
 896
 897                default:
 898                        strcpy(macfb_fix.id, "Unknown");
 899                        break;
 900                }
 901
 902        fb_info.fbops           = &macfb_ops;
 903        fb_info.var             = macfb_defined;
 904        fb_info.fix             = macfb_fix;
 905        fb_info.pseudo_palette  = pseudo_palette;
 906        fb_info.flags           = FBINFO_DEFAULT;
 907
 908        err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
 909        if (err)
 910                goto fail_unmap;
 911
 912        err = register_framebuffer(&fb_info);
 913        if (err)
 914                goto fail_dealloc;
 915
 916        pr_info("fb%d: %s frame buffer device\n",
 917                fb_info.node, fb_info.fix.id);
 918
 919        return 0;
 920
 921fail_dealloc:
 922        fb_dealloc_cmap(&fb_info.cmap);
 923fail_unmap:
 924        iounmap(fb_info.screen_base);
 925        iounmap_macfb();
 926        return err;
 927}
 928
 929module_init(macfb_init);
 930MODULE_LICENSE("GPL");
 931
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.