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