1 /* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
2 don't know how to set */
4 /* (c) 1999 David Huggins-Daines <dhd@debian.org>
6 Primarily based on vesafb.c, by Gerd Knorr
7 (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
9 Also uses information and code from:
11 The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
12 Mellinger, Mikael Forselius, Michael Schmitz, and others.
14 valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
15 Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
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. */
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/errno.h>
24 #include <linux/string.h>
26 #include <linux/slab.h>
27 #include <linux/delay.h>
28 #include <linux/nubus.h>
29 #include <linux/init.h>
32 #include <asm/setup.h>
33 #include <asm/bootinfo.h>
34 #include <asm/uaccess.h>
35 #include <asm/pgtable.h>
37 #include <asm/macintosh.h>
39 #include <asm/machw.h>
41 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
42 #define DAC_BASE 0x50f24000
44 /* Some addresses for the DAFB */
45 #define DAFB_BASE 0xf9800200
47 /* Address for the built-in Civic framebuffer in Quadra AVs */
48 #define CIVIC_BASE 0x50f30800 /* Only tested on 660AV! */
50 /* GSC (Gray Scale Controller) base address */
51 #define GSC_BASE 0x50F20000
53 /* CSC (Color Screen Controller) base address */
54 #define CSC_BASE 0x50F20000
56 static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
57 unsigned int green, unsigned int blue,
58 struct fb_info *info) = NULL;
59 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
60 unsigned int green, unsigned int blue,
61 struct fb_info *info);
62 static int dafb_setpalette (unsigned int regno, unsigned int red,
63 unsigned int green, unsigned int blue,
64 struct fb_info *fb_info);
65 static int rbv_setpalette (unsigned int regno, unsigned int red,
66 unsigned int green, unsigned int blue,
67 struct fb_info *fb_info);
68 static int mdc_setpalette (unsigned int regno, unsigned int red,
69 unsigned int green, unsigned int blue,
70 struct fb_info *fb_info);
71 static int toby_setpalette (unsigned int regno, unsigned int red,
72 unsigned int green, unsigned int blue,
73 struct fb_info *fb_info);
74 static int civic_setpalette (unsigned int regno, unsigned int red,
75 unsigned int green, unsigned int blue,
76 struct fb_info *fb_info);
77 static int csc_setpalette (unsigned int regno, unsigned int red,
78 unsigned int green, unsigned int blue,
79 struct fb_info *fb_info);
81 static volatile struct {
83 /* Note: word-aligned */
86 } *valkyrie_cmap_regs;
88 static volatile struct {
91 } *v8_brazil_cmap_regs;
93 static volatile struct {
95 char pad1[3]; /* word aligned */
97 char pad2[3]; /* word aligned */
98 unsigned char cntl; /* a guess as to purpose */
101 static volatile struct {
103 unsigned long pad1[3];
104 unsigned char pad2[3];
108 static volatile struct {
109 unsigned char addr; /* OFFSET: 0x00 */
110 unsigned char pad1[15];
111 unsigned char lut; /* OFFSET: 0x10 */
112 unsigned char pad2[15];
113 unsigned char status; /* OFFSET: 0x20 */
114 unsigned char pad3[7];
115 unsigned long vbl_addr; /* OFFSET: 0x28 */
116 unsigned int status2; /* OFFSET: 0x2C */
119 static volatile struct {
121 unsigned char clut_waddr; /* 0x40 */
123 unsigned char clut_data; /* 0x42 */
125 unsigned char clut_raddr; /* 0x46 */
128 /* We will leave these the way they are for the time being */
129 struct mdc_cmap_regs {
136 struct toby_cmap_regs {
138 unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
140 unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
143 struct jet_cmap_regs {
149 #define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */
152 static int video_slot = 0;
154 static struct fb_var_screeninfo macfb_defined = {
156 .activate = FB_ACTIVATE_NOW,
163 .vmode = FB_VMODE_NONINTERLACED,
166 static struct fb_fix_screeninfo macfb_fix = {
167 .type = FB_TYPE_PACKED_PIXELS,
168 .accel = FB_ACCEL_NONE,
171 static struct fb_info fb_info;
172 static u32 pseudo_palette[16];
173 static int inverse = 0;
174 static int vidtest = 0;
176 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
177 unsigned int green, unsigned int blue,
178 struct fb_info *info)
186 local_irq_save(flags);
188 /* tell clut which address to fill */
189 nubus_writeb(regno, &valkyrie_cmap_regs->addr);
192 /* send one color channel at a time */
193 nubus_writeb(red, &valkyrie_cmap_regs->lut);
195 nubus_writeb(green, &valkyrie_cmap_regs->lut);
197 nubus_writeb(blue, &valkyrie_cmap_regs->lut);
199 local_irq_restore(flags);
203 /* Unlike the Valkyrie, the DAFB cannot set individual colormap
204 registers. Therefore, we do what the MacOS driver does (no
205 kidding!) and simply set them one by one until we hit the one we
207 static int dafb_setpalette (unsigned int regno, unsigned int red,
208 unsigned int green, unsigned int blue,
209 struct fb_info *info)
211 /* FIXME: really, really need to use ioremap() here,
212 phys_to_virt() doesn't work anymore */
213 static int lastreg = -1;
220 local_irq_save(flags);
222 /* fbdev will set an entire colourmap, but X won't. Hopefully
223 this should accommodate both of them */
224 if (regno != lastreg+1) {
227 /* Stab in the dark trying to reset the CLUT pointer */
228 nubus_writel(0, &dafb_cmap_regs->reset);
231 /* Loop until we get to the register we want */
232 for (i = 0; i < regno; i++) {
233 nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
235 nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
237 nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
242 nubus_writeb(red, &dafb_cmap_regs->lut);
244 nubus_writeb(green, &dafb_cmap_regs->lut);
246 nubus_writeb(blue, &dafb_cmap_regs->lut);
248 local_irq_restore(flags);
253 /* V8 and Brazil seem to use the same DAC. Sonora does as well. */
254 static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
255 unsigned int green, unsigned int blue,
256 struct fb_info *info)
258 unsigned int bpp = info->var.bits_per_pixel;
259 unsigned char _red =red>>8;
260 unsigned char _green=green>>8;
261 unsigned char _blue =blue>>8;
262 unsigned char _regno;
265 if (bpp > 8) return 1; /* failsafe */
267 local_irq_save(flags);
269 /* On these chips, the CLUT register numbers are spread out
270 across the register space. Thus:
272 In 8bpp, all regnos are valid.
274 In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
276 In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
277 _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
278 nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
280 /* send one color channel at a time */
281 nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
282 nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
283 nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
285 local_irq_restore(flags);
289 static int rbv_setpalette (unsigned int regno, unsigned int red,
290 unsigned int green, unsigned int blue,
291 struct fb_info *info)
294 unsigned char _red =red>>8;
295 unsigned char _green=green>>8;
296 unsigned char _blue =blue>>8;
297 unsigned char _regno;
300 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
302 local_irq_save(flags);
304 /* From the VideoToolbox driver. Seems to be saying that
305 * regno #254 and #255 are the important ones for 1-bit color,
306 * regno #252-255 are the important ones for 2-bit color, etc.
308 _regno = regno + (256-(1 << info->var.bits_per_pixel));
310 /* reset clut? (VideoToolbox sez "not necessary") */
311 nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
313 /* tell clut which address to use. */
314 nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
316 /* send one color channel at a time. */
317 nubus_writeb(_red, &rbv_cmap_regs->lut); nop();
318 nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
319 nubus_writeb(_blue, &rbv_cmap_regs->lut);
321 local_irq_restore(flags); /* done. */
325 /* Macintosh Display Card (8x24) */
326 static int mdc_setpalette(unsigned int regno, unsigned int red,
327 unsigned int green, unsigned int blue,
328 struct fb_info *info)
330 volatile struct mdc_cmap_regs *cmap_regs =
331 nubus_slot_addr(video_slot);
333 unsigned char _red =red>>8;
334 unsigned char _green=green>>8;
335 unsigned char _blue =blue>>8;
336 unsigned char _regno=regno;
339 local_irq_save(flags);
341 /* the nop's are there to order writes. */
342 nubus_writeb(_regno, &cmap_regs->addr); nop();
343 nubus_writeb(_red, &cmap_regs->lut); nop();
344 nubus_writeb(_green, &cmap_regs->lut); nop();
345 nubus_writeb(_blue, &cmap_regs->lut);
347 local_irq_restore(flags);
351 /* Toby frame buffer */
352 static int toby_setpalette(unsigned int regno, unsigned int red,
353 unsigned int green, unsigned int blue,
354 struct fb_info *info)
356 volatile struct toby_cmap_regs *cmap_regs =
357 nubus_slot_addr(video_slot);
358 unsigned int bpp = info->var.bits_per_pixel;
360 unsigned char _red =~(red>>8);
361 unsigned char _green=~(green>>8);
362 unsigned char _blue =~(blue>>8);
363 unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
366 local_irq_save(flags);
368 nubus_writeb(_regno, &cmap_regs->addr); nop();
369 nubus_writeb(_red, &cmap_regs->lut); nop();
370 nubus_writeb(_green, &cmap_regs->lut); nop();
371 nubus_writeb(_blue, &cmap_regs->lut);
373 local_irq_restore(flags);
377 /* Jet frame buffer */
378 static int jet_setpalette(unsigned int regno, unsigned int red,
379 unsigned int green, unsigned int blue,
380 struct fb_info *info)
382 volatile struct jet_cmap_regs *cmap_regs =
383 nubus_slot_addr(video_slot);
385 unsigned char _red = (red>>8);
386 unsigned char _green = (green>>8);
387 unsigned char _blue = (blue>>8);
390 local_irq_save(flags);
392 nubus_writeb(regno, &cmap_regs->addr); nop();
393 nubus_writeb(_red, &cmap_regs->lut); nop();
394 nubus_writeb(_green, &cmap_regs->lut); nop();
395 nubus_writeb(_blue, &cmap_regs->lut);
397 local_irq_restore(flags);
402 * Civic framebuffer -- Quadra AV built-in video. A chip
403 * called Sebastian holds the actual color palettes, and
404 * apparently, there are two different banks of 512K RAM
405 * which can act as separate framebuffers for doing video
406 * input and viewing the screen at the same time! The 840AV
407 * Can add another 1MB RAM to give the two framebuffers
410 * FIXME: this doesn't seem to work anymore.
412 static int civic_setpalette (unsigned int regno, unsigned int red,
413 unsigned int green, unsigned int blue,
414 struct fb_info *info)
416 static int lastreg = -1;
420 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
426 local_irq_save(flags);
429 * Set the register address
431 nubus_writeb(regno, &civic_cmap_regs->addr); nop();
434 * Wait for VBL interrupt here;
435 * They're usually not enabled from Penguin, so we won't check
439 #define CIVIC_VBL_OFFSET 0x120
440 volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
441 /* do interrupt setup stuff here? */
442 *vbl = 0L; nop(); /* clear */
443 *vbl = 1L; nop(); /* set */
444 while (*vbl != 0L) /* wait for next vbl */
446 usleep(10); /* needed? */
448 /* do interrupt shutdown stuff here? */
453 * Grab a status word and do some checking;
454 * Then finally write the clut!
456 clut_status = nubus_readb(&civic_cmap_regs->status2);
458 if ((clut_status & 0x0008) == 0)
461 if ((clut_status & 0x000D) != 0)
463 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
464 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
468 nubus_writeb( red, &civic_cmap_regs->lut); nop();
469 nubus_writeb(green, &civic_cmap_regs->lut); nop();
470 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
471 nubus_writeb( 0x00, &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 junk = nubus_readb(&civic_cmap_regs->lut); nop();
482 if ((clut_status & 0x000D) != 0)
484 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
485 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
488 nubus_writeb( red, &civic_cmap_regs->lut); nop();
489 nubus_writeb(green, &civic_cmap_regs->lut); nop();
490 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
491 nubus_writeb( junk, &civic_cmap_regs->lut); nop();
494 local_irq_restore(flags);
500 * The CSC is the framebuffer on the PowerBook 190 series
501 * (and the 5300 too, but that's a PowerMac). This function
502 * brought to you in part by the ECSC driver for MkLinux.
505 static int csc_setpalette (unsigned int regno, unsigned int red,
506 unsigned int green, unsigned int blue,
507 struct fb_info *info)
510 csc_cmap_regs->clut_waddr = regno;
511 csc_cmap_regs->clut_data = red;
512 csc_cmap_regs->clut_data = green;
513 csc_cmap_regs->clut_data = blue;
517 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
518 unsigned blue, unsigned transp,
519 struct fb_info *fb_info)
522 * Set a single color register. The values supplied are
523 * already rounded down to the hardware's capabilities
524 * (according to the entries in the `var' structure). Return
525 * != 0 for invalid regno.
528 if (regno >= fb_info->cmap.len)
531 if (fb_info->var.bits_per_pixel <= 8) {
532 switch (fb_info->var.bits_per_pixel) {
534 /* We shouldn't get here */
539 if (macfb_setpalette)
540 macfb_setpalette(regno, red, green, blue,
546 } else if (regno < 16) {
547 switch (fb_info->var.bits_per_pixel) {
549 if (fb_info->var.red.offset == 10) {
551 ((u32*) (fb_info->pseudo_palette))[regno] =
552 ((red & 0xf800) >> 1) |
553 ((green & 0xf800) >> 6) |
554 ((blue & 0xf800) >> 11) |
555 ((transp != 0) << 15);
558 ((u32*) (fb_info->pseudo_palette))[regno] =
560 ((green & 0xfc00) >> 5) |
561 ((blue & 0xf800) >> 11);
564 /* I'm pretty sure that one or the other of these
565 doesn't exist on 68k Macs */
570 ((u32 *)(fb_info->pseudo_palette))[regno] =
571 (red << fb_info->var.red.offset) |
572 (green << fb_info->var.green.offset) |
573 (blue << fb_info->var.blue.offset);
579 ((u32 *)(fb_info->pseudo_palette))[regno] =
580 (red << fb_info->var.red.offset) |
581 (green << fb_info->var.green.offset) |
582 (blue << fb_info->var.blue.offset);
590 static struct fb_ops macfb_ops = {
591 .owner = THIS_MODULE,
592 .fb_setcolreg = macfb_setcolreg,
593 .fb_fillrect = cfb_fillrect,
594 .fb_copyarea = cfb_copyarea,
595 .fb_imageblit = cfb_imageblit,
598 static void __init macfb_setup(char *options)
602 if (!options || !*options)
605 while ((this_opt = strsep(&options, ",")) != NULL) {
606 if (!*this_opt) continue;
608 if (! strcmp(this_opt, "inverse"))
610 /* This means "turn on experimental CLUT code" */
611 else if (!strcmp(this_opt, "vidtest"))
616 static void __init iounmap_macfb(void)
618 if (valkyrie_cmap_regs)
619 iounmap(valkyrie_cmap_regs);
621 iounmap(dafb_cmap_regs);
622 if (v8_brazil_cmap_regs)
623 iounmap(v8_brazil_cmap_regs);
625 iounmap(rbv_cmap_regs);
627 iounmap(civic_cmap_regs);
629 iounmap(csc_cmap_regs);
632 static int __init macfb_init(void)
634 int video_cmap_len, video_is_nubus = 0;
635 struct nubus_dev* ndev = NULL;
639 if (fb_get_options("macfb", &option))
646 /* There can only be one internal video controller anyway so
647 we're not too worried about this */
648 macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
649 macfb_defined.yres = mac_bi_data.dimensions >> 16;
650 macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
651 macfb_fix.line_length = mac_bi_data.videorow;
652 macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
653 /* Note: physical address (since 2.1.127) */
654 macfb_fix.smem_start = mac_bi_data.videoaddr;
655 /* This is actually redundant with the initial mappings.
656 However, there are some non-obvious aspects to the way
657 those mappings are set up, so this is in fact the safest
658 way to ensure that this driver will work on every possible
660 fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
662 printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
663 macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
664 printk("macfb: mode is %dx%dx%d, linelength=%d\n",
665 macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
668 * Fill in the available video resolution
671 macfb_defined.xres_virtual = macfb_defined.xres;
672 macfb_defined.yres_virtual = macfb_defined.yres;
673 macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
674 macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres);
676 printk("macfb: scrolling: redraw\n");
677 macfb_defined.yres_virtual = macfb_defined.yres;
679 /* some dummy values for timing to make fbset happy */
680 macfb_defined.pixclock = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
681 macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8;
682 macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8;
684 switch (macfb_defined.bits_per_pixel) {
686 /* XXX: I think this will catch any program that tries
687 to do FBIO_PUTCMAP when the visual is monochrome */
688 macfb_defined.red.length = macfb_defined.bits_per_pixel;
689 macfb_defined.green.length = macfb_defined.bits_per_pixel;
690 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
692 macfb_fix.visual = FB_VISUAL_MONO01;
697 macfb_defined.red.length = macfb_defined.bits_per_pixel;
698 macfb_defined.green.length = macfb_defined.bits_per_pixel;
699 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
700 video_cmap_len = 1 << macfb_defined.bits_per_pixel;
701 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
704 macfb_defined.transp.offset = 15;
705 macfb_defined.transp.length = 1;
706 macfb_defined.red.offset = 10;
707 macfb_defined.red.length = 5;
708 macfb_defined.green.offset = 5;
709 macfb_defined.green.length = 5;
710 macfb_defined.blue.offset = 0;
711 macfb_defined.blue.length = 5;
712 printk("macfb: directcolor: "
713 "size=1:5:5:5, shift=15:10:5:0\n");
715 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
717 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
721 /* XXX: have to test these... can any 68k Macs
722 actually do this on internal video? */
723 macfb_defined.red.offset = 16;
724 macfb_defined.red.length = 8;
725 macfb_defined.green.offset = 8;
726 macfb_defined.green.length = 8;
727 macfb_defined.blue.offset = 0;
728 macfb_defined.blue.length = 8;
729 printk("macfb: truecolor: "
730 "size=0:8:8:8, shift=0:16:8:0\n");
732 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
735 macfb_fix.visual = FB_VISUAL_MONO01;
736 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
740 /* Hardware dependent stuff */
741 /* We take a wild guess that if the video physical address is
742 * in nubus slot space, that the nubus card is driving video.
743 * Penguin really ought to tell us whether we are using internal
746 /* Hopefully we only find one of them. Otherwise our NuBus
747 code is really broken :-) */
749 while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
752 if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
753 && (mac_bi_data.videoaddr <
754 (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
757 /* We should probably just use the slot address... */
758 video_slot = ndev->board->slot;
760 switch(ndev->dr_hw) {
761 case NUBUS_DRHW_APPLE_MDC:
762 strcpy(macfb_fix.id, "Mac Disp. Card");
763 macfb_setpalette = mdc_setpalette;
764 macfb_defined.activate = FB_ACTIVATE_NOW;
766 case NUBUS_DRHW_APPLE_TFB:
767 strcpy(macfb_fix.id, "Toby");
768 macfb_setpalette = toby_setpalette;
769 macfb_defined.activate = FB_ACTIVATE_NOW;
771 case NUBUS_DRHW_APPLE_JET:
772 strcpy(macfb_fix.id, "Jet");
773 macfb_setpalette = jet_setpalette;
774 macfb_defined.activate = FB_ACTIVATE_NOW;
777 strcpy(macfb_fix.id, "Generic NuBus");
782 /* If it's not a NuBus card, it must be internal video */
783 /* FIXME: this function is getting way too big. (this driver
786 switch( mac_bi_data.id )
788 /* Valkyrie Quadras */
790 /* I'm not sure about this one */
792 strcpy(macfb_fix.id, "Valkyrie");
793 macfb_setpalette = valkyrie_setpalette;
794 macfb_defined.activate = FB_ACTIVATE_NOW;
795 valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
799 /* Note: these first four have the v7 DAFB, which is
800 known to be rather unlike the ones used in the
803 case MAC_MODEL_P475F:
815 strcpy(macfb_fix.id, "DAFB");
816 macfb_setpalette = dafb_setpalette;
817 macfb_defined.activate = FB_ACTIVATE_NOW;
818 dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
821 /* LC II uses the V8 framebuffer */
823 strcpy(macfb_fix.id, "V8");
824 macfb_setpalette = v8_brazil_setpalette;
825 macfb_defined.activate = FB_ACTIVATE_NOW;
826 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
829 /* IIvi, IIvx use the "Brazil" framebuffer (which is
830 very much like the V8, it seems, and probably uses
835 strcpy(macfb_fix.id, "Brazil");
836 macfb_setpalette = v8_brazil_setpalette;
837 macfb_defined.activate = FB_ACTIVATE_NOW;
838 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
841 /* LC III (and friends) use the Sonora framebuffer */
842 /* Incidentally this is also used in the non-AV models
843 of the x100 PowerMacs */
844 /* These do in fact seem to use the same DAC interface
846 case MAC_MODEL_LCIII:
850 macfb_setpalette = v8_brazil_setpalette;
851 macfb_defined.activate = FB_ACTIVATE_NOW;
852 strcpy(macfb_fix.id, "Sonora");
853 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
856 /* IIci and IIsi use the infamous RBV chip
857 (the IIsi is just a rebadged and crippled
858 IIci in a different case, BTW) */
861 macfb_setpalette = rbv_setpalette;
862 macfb_defined.activate = FB_ACTIVATE_NOW;
863 strcpy(macfb_fix.id, "RBV");
864 rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
867 /* AVs use the Civic framebuffer */
870 macfb_setpalette = civic_setpalette;
871 macfb_defined.activate = FB_ACTIVATE_NOW;
872 strcpy(macfb_fix.id, "Civic");
873 civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
877 /* Write a setpalette function for your machine, then
878 you can add something similar here. These are
879 grouped by classes of video chipsets. Some of this
880 information is from the VideoToolbox "Bugs" web
882 http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
884 /* Assorted weirdos */
885 /* We think this may be like the LC II */
888 macfb_setpalette = v8_brazil_setpalette;
889 macfb_defined.activate = FB_ACTIVATE_NOW;
890 v8_brazil_cmap_regs =
891 ioremap(DAC_BASE, 0x1000);
893 strcpy(macfb_fix.id, "LC");
895 /* We think this may be like the LC II */
898 macfb_setpalette = v8_brazil_setpalette;
899 macfb_defined.activate = FB_ACTIVATE_NOW;
900 v8_brazil_cmap_regs =
901 ioremap(DAC_BASE, 0x1000);
903 strcpy(macfb_fix.id, "Color Classic");
906 /* And we *do* mean "weirdos" */
908 strcpy(macfb_fix.id, "Mac TV");
911 /* These don't have colour, so no need to worry */
914 strcpy(macfb_fix.id, "Monochrome");
917 /* Powerbooks are particularly difficult. Many of
918 them have separate framebuffers for external and
919 internal video, which is admittedly pretty cool,
920 but will be a bit of a headache to support here.
921 Also, many of them are grayscale, and we don't
922 really support that. */
924 case MAC_MODEL_PB140:
925 case MAC_MODEL_PB145:
926 case MAC_MODEL_PB170:
927 strcpy(macfb_fix.id, "DDC");
930 /* Internal is GSC, External (if present) is ViSC */
931 case MAC_MODEL_PB150: /* no external video */
932 case MAC_MODEL_PB160:
933 case MAC_MODEL_PB165:
934 case MAC_MODEL_PB180:
935 case MAC_MODEL_PB210:
936 case MAC_MODEL_PB230:
937 strcpy(macfb_fix.id, "GSC");
940 /* Internal is TIM, External is ViSC */
941 case MAC_MODEL_PB165C:
942 case MAC_MODEL_PB180C:
943 strcpy(macfb_fix.id, "TIM");
946 /* Internal is CSC, External is Keystone+Ariel. */
947 case MAC_MODEL_PB190: /* external video is optional */
948 case MAC_MODEL_PB520:
949 case MAC_MODEL_PB250:
950 case MAC_MODEL_PB270C:
951 case MAC_MODEL_PB280:
952 case MAC_MODEL_PB280C:
953 macfb_setpalette = csc_setpalette;
954 macfb_defined.activate = FB_ACTIVATE_NOW;
955 strcpy(macfb_fix.id, "CSC");
956 csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
960 strcpy(macfb_fix.id, "Unknown");
964 fb_info.fbops = &macfb_ops;
965 fb_info.var = macfb_defined;
966 fb_info.fix = macfb_fix;
967 fb_info.pseudo_palette = pseudo_palette;
968 fb_info.flags = FBINFO_DEFAULT;
970 err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
974 err = register_framebuffer(&fb_info);
978 printk("fb%d: %s frame buffer device\n",
979 fb_info.node, fb_info.fix.id);
983 fb_dealloc_cmap(&fb_info.cmap);
985 iounmap(fb_info.screen_base);
990 module_init(macfb_init);
991 MODULE_LICENSE("GPL");