root/drivers/video/fbdev/macfb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dafb_setpalette
  2. v8_brazil_setpalette
  3. rbv_setpalette
  4. mdc_setpalette
  5. toby_setpalette
  6. jet_setpalette
  7. civic_setpalette
  8. csc_setpalette
  9. macfb_setcolreg
  10. macfb_setup
  11. iounmap_macfb
  12. macfb_init

   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 
  52 static int (*macfb_setpalette)(unsigned int regno, unsigned int red,
  53                                unsigned int green, unsigned int blue,
  54                                struct fb_info *info);
  55 
  56 static struct {
  57         unsigned char addr;
  58         unsigned char lut;
  59 } __iomem *v8_brazil_cmap_regs;
  60 
  61 static 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 
  69 static 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 
  76 static 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 
  87 static 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 */
  97 struct mdc_cmap_regs {
  98         char pad1[0x200200];
  99         unsigned char addr;
 100         char pad2[6];
 101         unsigned char lut;
 102 };
 103 
 104 struct 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 
 111 struct 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 
 119 static 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 
 128 static struct fb_fix_screeninfo macfb_fix = {
 129         .type   = FB_TYPE_PACKED_PIXELS,
 130         .accel  = FB_ACCEL_NONE,
 131 };
 132 
 133 static void *slot_addr;
 134 static struct fb_info fb_info;
 135 static u32 pseudo_palette[16];
 136 static 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  */
 144 static 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. */
 190 static 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 */
 221 static 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) */
 255 static 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 */
 278 static 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 */
 306 static 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  */
 336 static 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  */
 414 static 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 
 432 static 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                  * http://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 
 499 static 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 
 507 static 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 
 526 static 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 
 540 static 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 
 893 fail_dealloc:
 894         fb_dealloc_cmap(&fb_info.cmap);
 895 fail_unmap:
 896         iounmap(fb_info.screen_base);
 897         iounmap_macfb();
 898         return err;
 899 }
 900 
 901 module_init(macfb_init);
 902 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */