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