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/sched.h>
24 #include <linux/errno.h>
25 #include <linux/string.h>
27 #include <linux/slab.h>
28 #include <linux/delay.h>
29 #include <linux/nubus.h>
30 #include <linux/init.h>
33 #include <asm/setup.h>
34 #include <asm/bootinfo.h>
35 #include <asm/uaccess.h>
36 #include <asm/pgtable.h>
38 #include <asm/macintosh.h>
40 #include <asm/machw.h>
42 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
43 #define DAC_BASE 0x50f24000
45 /* Some addresses for the DAFB */
46 #define DAFB_BASE 0xf9800200
48 /* Address for the built-in Civic framebuffer in Quadra AVs */
49 #define CIVIC_BASE 0x50f30800 /* Only tested on 660AV! */
51 /* GSC (Gray Scale Controller) base address */
52 #define GSC_BASE 0x50F20000
54 /* CSC (Color Screen Controller) base address */
55 #define CSC_BASE 0x50F20000
57 static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
58 unsigned int green, unsigned int blue,
59 struct fb_info *info) = NULL;
60 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
61 unsigned int green, unsigned int blue,
62 struct fb_info *info);
63 static int dafb_setpalette (unsigned int regno, unsigned int red,
64 unsigned int green, unsigned int blue,
65 struct fb_info *fb_info);
66 static int rbv_setpalette (unsigned int regno, unsigned int red,
67 unsigned int green, unsigned int blue,
68 struct fb_info *fb_info);
69 static int mdc_setpalette (unsigned int regno, unsigned int red,
70 unsigned int green, unsigned int blue,
71 struct fb_info *fb_info);
72 static int toby_setpalette (unsigned int regno, unsigned int red,
73 unsigned int green, unsigned int blue,
74 struct fb_info *fb_info);
75 static int civic_setpalette (unsigned int regno, unsigned int red,
76 unsigned int green, unsigned int blue,
77 struct fb_info *fb_info);
78 static int csc_setpalette (unsigned int regno, unsigned int red,
79 unsigned int green, unsigned int blue,
80 struct fb_info *fb_info);
82 static volatile struct {
84 /* Note: word-aligned */
87 } *valkyrie_cmap_regs;
89 static volatile struct {
92 } *v8_brazil_cmap_regs;
94 static volatile struct {
96 char pad1[3]; /* word aligned */
98 char pad2[3]; /* word aligned */
99 unsigned char cntl; /* a guess as to purpose */
102 static volatile struct {
104 unsigned long pad1[3];
105 unsigned char pad2[3];
109 static volatile struct {
110 unsigned char addr; /* OFFSET: 0x00 */
111 unsigned char pad1[15];
112 unsigned char lut; /* OFFSET: 0x10 */
113 unsigned char pad2[15];
114 unsigned char status; /* OFFSET: 0x20 */
115 unsigned char pad3[7];
116 unsigned long vbl_addr; /* OFFSET: 0x28 */
117 unsigned int status2; /* OFFSET: 0x2C */
120 static volatile struct {
122 unsigned char clut_waddr; /* 0x40 */
124 unsigned char clut_data; /* 0x42 */
126 unsigned char clut_raddr; /* 0x46 */
129 /* We will leave these the way they are for the time being */
130 struct mdc_cmap_regs {
137 struct toby_cmap_regs {
139 unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
141 unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
144 struct jet_cmap_regs {
150 #define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */
153 static int video_slot = 0;
155 static struct fb_var_screeninfo macfb_defined = {
157 .activate = FB_ACTIVATE_NOW,
164 .vmode = FB_VMODE_NONINTERLACED,
167 static struct fb_fix_screeninfo macfb_fix = {
169 .type = FB_TYPE_PACKED_PIXELS,
170 .accel = FB_ACCEL_NONE,
173 static struct fb_info fb_info;
174 static u32 pseudo_palette[17];
175 static int inverse = 0;
176 static int vidtest = 0;
178 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
179 unsigned int green, unsigned int blue,
180 struct fb_info *info)
188 local_irq_save(flags);
190 /* tell clut which address to fill */
191 nubus_writeb(regno, &valkyrie_cmap_regs->addr);
194 /* send one color channel at a time */
195 nubus_writeb(red, &valkyrie_cmap_regs->lut);
197 nubus_writeb(green, &valkyrie_cmap_regs->lut);
199 nubus_writeb(blue, &valkyrie_cmap_regs->lut);
201 local_irq_restore(flags);
205 /* Unlike the Valkyrie, the DAFB cannot set individual colormap
206 registers. Therefore, we do what the MacOS driver does (no
207 kidding!) and simply set them one by one until we hit the one we
209 static int dafb_setpalette (unsigned int regno, unsigned int red,
210 unsigned int green, unsigned int blue,
211 struct fb_info *info)
213 /* FIXME: really, really need to use ioremap() here,
214 phys_to_virt() doesn't work anymore */
215 static int lastreg = -1;
222 local_irq_save(flags);
224 /* fbdev will set an entire colourmap, but X won't. Hopefully
225 this should accommodate both of them */
226 if (regno != lastreg+1) {
229 /* Stab in the dark trying to reset the CLUT pointer */
230 nubus_writel(0, &dafb_cmap_regs->reset);
233 /* Loop until we get to the register we want */
234 for (i = 0; i < regno; i++) {
235 nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
237 nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
239 nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
244 nubus_writeb(red, &dafb_cmap_regs->lut);
246 nubus_writeb(green, &dafb_cmap_regs->lut);
248 nubus_writeb(blue, &dafb_cmap_regs->lut);
250 local_irq_restore(flags);
255 /* V8 and Brazil seem to use the same DAC. Sonora does as well. */
256 static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
257 unsigned int green, unsigned int blue,
258 struct fb_info *info)
260 unsigned int bpp = info->var.bits_per_pixel;
261 unsigned char _red =red>>8;
262 unsigned char _green=green>>8;
263 unsigned char _blue =blue>>8;
264 unsigned char _regno;
267 if (bpp > 8) return 1; /* failsafe */
269 local_irq_save(flags);
271 /* On these chips, the CLUT register numbers are spread out
272 across the register space. Thus:
274 In 8bpp, all regnos are valid.
276 In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
278 In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
279 _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
280 nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
282 /* send one color channel at a time */
283 nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
284 nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
285 nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
287 local_irq_restore(flags);
291 static int rbv_setpalette (unsigned int regno, unsigned int red,
292 unsigned int green, unsigned int blue,
293 struct fb_info *info)
296 unsigned char _red =red>>8;
297 unsigned char _green=green>>8;
298 unsigned char _blue =blue>>8;
299 unsigned char _regno;
302 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
304 local_irq_save(flags);
306 /* From the VideoToolbox driver. Seems to be saying that
307 * regno #254 and #255 are the important ones for 1-bit color,
308 * regno #252-255 are the important ones for 2-bit color, etc.
310 _regno = regno + (256-(1 << info->var.bits_per_pixel));
312 /* reset clut? (VideoToolbox sez "not necessary") */
313 nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
315 /* tell clut which address to use. */
316 nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
318 /* send one color channel at a time. */
319 nubus_writeb(_red, &rbv_cmap_regs->lut); nop();
320 nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
321 nubus_writeb(_blue, &rbv_cmap_regs->lut);
323 local_irq_restore(flags); /* done. */
327 /* Macintosh Display Card (8x24) */
328 static int mdc_setpalette(unsigned int regno, unsigned int red,
329 unsigned int green, unsigned int blue,
330 struct fb_info *info)
332 volatile struct mdc_cmap_regs *cmap_regs =
333 nubus_slot_addr(video_slot);
335 unsigned char _red =red>>8;
336 unsigned char _green=green>>8;
337 unsigned char _blue =blue>>8;
338 unsigned char _regno=regno;
341 local_irq_save(flags);
343 /* the nop's are there to order writes. */
344 nubus_writeb(_regno, &cmap_regs->addr); nop();
345 nubus_writeb(_red, &cmap_regs->lut); nop();
346 nubus_writeb(_green, &cmap_regs->lut); nop();
347 nubus_writeb(_blue, &cmap_regs->lut);
349 local_irq_restore(flags);
353 /* Toby frame buffer */
354 static int toby_setpalette(unsigned int regno, unsigned int red,
355 unsigned int green, unsigned int blue,
356 struct fb_info *info)
358 volatile struct toby_cmap_regs *cmap_regs =
359 nubus_slot_addr(video_slot);
360 unsigned int bpp = info->var.bits_per_pixel;
362 unsigned char _red =~(red>>8);
363 unsigned char _green=~(green>>8);
364 unsigned char _blue =~(blue>>8);
365 unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
368 local_irq_save(flags);
370 nubus_writeb(_regno, &cmap_regs->addr); nop();
371 nubus_writeb(_red, &cmap_regs->lut); nop();
372 nubus_writeb(_green, &cmap_regs->lut); nop();
373 nubus_writeb(_blue, &cmap_regs->lut);
375 local_irq_restore(flags);
379 /* Jet frame buffer */
380 static int jet_setpalette(unsigned int regno, unsigned int red,
381 unsigned int green, unsigned int blue,
382 struct fb_info *info)
384 volatile struct jet_cmap_regs *cmap_regs =
385 nubus_slot_addr(video_slot);
387 unsigned char _red = (red>>8);
388 unsigned char _green = (green>>8);
389 unsigned char _blue = (blue>>8);
392 local_irq_save(flags);
394 nubus_writeb(regno, &cmap_regs->addr); nop();
395 nubus_writeb(_red, &cmap_regs->lut); nop();
396 nubus_writeb(_green, &cmap_regs->lut); nop();
397 nubus_writeb(_blue, &cmap_regs->lut);
399 local_irq_restore(flags);
404 * Civic framebuffer -- Quadra AV built-in video. A chip
405 * called Sebastian holds the actual color palettes, and
406 * apparently, there are two different banks of 512K RAM
407 * which can act as separate framebuffers for doing video
408 * input and viewing the screen at the same time! The 840AV
409 * Can add another 1MB RAM to give the two framebuffers
412 * FIXME: this doesn't seem to work anymore.
414 static int civic_setpalette (unsigned int regno, unsigned int red,
415 unsigned int green, unsigned int blue,
416 struct fb_info *info)
418 static int lastreg = -1;
422 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
428 local_irq_save(flags);
431 * Set the register address
433 nubus_writeb(regno, &civic_cmap_regs->addr); nop();
436 * Wait for VBL interrupt here;
437 * They're usually not enabled from Penguin, so we won't check
441 #define CIVIC_VBL_OFFSET 0x120
442 volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
443 /* do interrupt setup stuff here? */
444 *vbl = 0L; nop(); /* clear */
445 *vbl = 1L; nop(); /* set */
446 while (*vbl != 0L) /* wait for next vbl */
448 usleep(10); /* needed? */
450 /* do interrupt shutdown stuff here? */
455 * Grab a status word and do some checking;
456 * Then finally write the clut!
458 clut_status = nubus_readb(&civic_cmap_regs->status2);
460 if ((clut_status & 0x0008) == 0)
463 if ((clut_status & 0x000D) != 0)
465 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
466 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
470 nubus_writeb( red, &civic_cmap_regs->lut); nop();
471 nubus_writeb(green, &civic_cmap_regs->lut); nop();
472 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
473 nubus_writeb( 0x00, &civic_cmap_regs->lut); nop();
479 junk = nubus_readb(&civic_cmap_regs->lut); nop();
480 junk = nubus_readb(&civic_cmap_regs->lut); nop();
481 junk = nubus_readb(&civic_cmap_regs->lut); nop();
482 junk = nubus_readb(&civic_cmap_regs->lut); nop();
484 if ((clut_status & 0x000D) != 0)
486 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
487 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
490 nubus_writeb( red, &civic_cmap_regs->lut); nop();
491 nubus_writeb(green, &civic_cmap_regs->lut); nop();
492 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
493 nubus_writeb( junk, &civic_cmap_regs->lut); nop();
496 local_irq_restore(flags);
502 * The CSC is the framebuffer on the PowerBook 190 series
503 * (and the 5300 too, but that's a PowerMac). This function
504 * brought to you in part by the ECSC driver for MkLinux.
507 static int csc_setpalette (unsigned int regno, unsigned int red,
508 unsigned int green, unsigned int blue,
509 struct fb_info *info)
512 csc_cmap_regs->clut_waddr = regno;
513 csc_cmap_regs->clut_data = red;
514 csc_cmap_regs->clut_data = green;
515 csc_cmap_regs->clut_data = blue;
519 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
520 unsigned blue, unsigned transp,
521 struct fb_info *fb_info)
524 * Set a single color register. The values supplied are
525 * already rounded down to the hardware's capabilities
526 * (according to the entries in the `var' structure). Return
527 * != 0 for invalid regno.
530 if (regno >= fb_info->cmap.len)
533 switch (fb_info->var.bits_per_pixel) {
535 /* We shouldn't get here */
540 if (macfb_setpalette)
541 macfb_setpalette(regno, red, green, blue, fb_info);
546 if (fb_info->var.red.offset == 10) {
548 ((u32*) (fb_info->pseudo_palette))[regno] =
549 ((red & 0xf800) >> 1) |
550 ((green & 0xf800) >> 6) |
551 ((blue & 0xf800) >> 11) |
552 ((transp != 0) << 15);
555 ((u32*) (fb_info->pseudo_palette))[regno] =
557 ((green & 0xfc00) >> 5) |
558 ((blue & 0xf800) >> 11);
561 /* I'm pretty sure that one or the other of these
562 doesn't exist on 68k Macs */
567 ((u32 *)(fb_info->pseudo_palette))[regno] =
568 (red << fb_info->var.red.offset) |
569 (green << fb_info->var.green.offset) |
570 (blue << fb_info->var.blue.offset);
576 ((u32 *)(fb_info->pseudo_palette))[regno] =
577 (red << fb_info->var.red.offset) |
578 (green << fb_info->var.green.offset) |
579 (blue << fb_info->var.blue.offset);
585 static struct fb_ops macfb_ops = {
586 .owner = THIS_MODULE,
587 .fb_setcolreg = macfb_setcolreg,
588 .fb_fillrect = cfb_fillrect,
589 .fb_copyarea = cfb_copyarea,
590 .fb_imageblit = cfb_imageblit,
593 void __init macfb_setup(char *options)
597 if (!options || !*options)
600 while ((this_opt = strsep(&options, ",")) != NULL) {
601 if (!*this_opt) continue;
603 if (! strcmp(this_opt, "inverse"))
605 /* This means "turn on experimental CLUT code" */
606 else if (!strcmp(this_opt, "vidtest"))
611 static int __init macfb_init(void)
613 int video_cmap_len, video_is_nubus = 0;
614 struct nubus_dev* ndev = NULL;
618 if (fb_get_options("macfb", &option))
625 /* There can only be one internal video controller anyway so
626 we're not too worried about this */
627 macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
628 macfb_defined.yres = mac_bi_data.dimensions >> 16;
629 macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
630 macfb_fix.line_length = mac_bi_data.videorow;
631 macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
632 /* Note: physical address (since 2.1.127) */
633 macfb_fix.smem_start = mac_bi_data.videoaddr;
634 /* This is actually redundant with the initial mappings.
635 However, there are some non-obvious aspects to the way
636 those mappings are set up, so this is in fact the safest
637 way to ensure that this driver will work on every possible
639 fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
641 printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
642 macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
643 printk("macfb: mode is %dx%dx%d, linelength=%d\n",
644 macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
647 * Fill in the available video resolution
650 macfb_defined.xres_virtual = macfb_defined.xres;
651 macfb_defined.yres_virtual = macfb_defined.yres;
652 macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
653 macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres);
655 printk("macfb: scrolling: redraw\n");
656 macfb_defined.yres_virtual = macfb_defined.yres;
658 /* some dummy values for timing to make fbset happy */
659 macfb_defined.pixclock = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
660 macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8;
661 macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8;
663 switch (macfb_defined.bits_per_pixel) {
665 /* XXX: I think this will catch any program that tries
666 to do FBIO_PUTCMAP when the visual is monochrome */
667 macfb_defined.red.length = macfb_defined.bits_per_pixel;
668 macfb_defined.green.length = macfb_defined.bits_per_pixel;
669 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
671 macfb_fix.visual = FB_VISUAL_MONO01;
676 macfb_defined.red.length = macfb_defined.bits_per_pixel;
677 macfb_defined.green.length = macfb_defined.bits_per_pixel;
678 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
679 video_cmap_len = 1 << macfb_defined.bits_per_pixel;
680 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
683 macfb_defined.transp.offset = 15;
684 macfb_defined.transp.length = 1;
685 macfb_defined.red.offset = 10;
686 macfb_defined.red.length = 5;
687 macfb_defined.green.offset = 5;
688 macfb_defined.green.length = 5;
689 macfb_defined.blue.offset = 0;
690 macfb_defined.blue.length = 5;
691 printk("macfb: directcolor: "
692 "size=1:5:5:5, shift=15:10:5:0\n");
694 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
696 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
700 /* XXX: have to test these... can any 68k Macs
701 actually do this on internal video? */
702 macfb_defined.red.offset = 16;
703 macfb_defined.red.length = 8;
704 macfb_defined.green.offset = 8;
705 macfb_defined.green.length = 8;
706 macfb_defined.blue.offset = 0;
707 macfb_defined.blue.length = 8;
708 printk("macfb: truecolor: "
709 "size=0:8:8:8, shift=0:16:8:0\n");
711 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
714 macfb_fix.visual = FB_VISUAL_MONO01;
715 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
719 /* Hardware dependent stuff */
720 /* We take a wild guess that if the video physical address is
721 * in nubus slot space, that the nubus card is driving video.
722 * Penguin really ought to tell us whether we are using internal
725 /* Hopefully we only find one of them. Otherwise our NuBus
726 code is really broken :-) */
728 while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
731 if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
732 && (mac_bi_data.videoaddr <
733 (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
736 /* We should probably just use the slot address... */
737 video_slot = ndev->board->slot;
739 switch(ndev->dr_hw) {
740 case NUBUS_DRHW_APPLE_MDC:
741 strcat( macfb_fix.id, "Display Card" );
742 macfb_setpalette = mdc_setpalette;
743 macfb_defined.activate = FB_ACTIVATE_NOW;
745 case NUBUS_DRHW_APPLE_TFB:
746 strcat( macfb_fix.id, "Toby" );
747 macfb_setpalette = toby_setpalette;
748 macfb_defined.activate = FB_ACTIVATE_NOW;
750 case NUBUS_DRHW_APPLE_JET:
751 strcat( macfb_fix.id, "Jet");
752 macfb_setpalette = jet_setpalette;
753 macfb_defined.activate = FB_ACTIVATE_NOW;
756 strcat( macfb_fix.id, "Generic NuBus" );
761 /* If it's not a NuBus card, it must be internal video */
762 /* FIXME: this function is getting way too big. (this driver
765 switch( mac_bi_data.id )
767 /* These don't have onboard video. Eventually, we may
768 be able to write separate framebuffer drivers for
769 them (tobyfb.c, hiresfb.c, etc, etc) */
774 strcat( macfb_fix.id, "Generic NuBus" );
777 /* Valkyrie Quadras */
779 /* I'm not sure about this one */
781 strcat( macfb_fix.id, "Valkyrie built-in" );
782 macfb_setpalette = valkyrie_setpalette;
783 macfb_defined.activate = FB_ACTIVATE_NOW;
784 valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
788 /* Note: these first four have the v7 DAFB, which is
789 known to be rather unlike the ones used in the
792 case MAC_MODEL_P475F:
804 strcat( macfb_fix.id, "DAFB built-in" );
805 macfb_setpalette = dafb_setpalette;
806 macfb_defined.activate = FB_ACTIVATE_NOW;
807 dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
810 /* LC II uses the V8 framebuffer */
812 strcat( macfb_fix.id, "V8 built-in" );
813 macfb_setpalette = v8_brazil_setpalette;
814 macfb_defined.activate = FB_ACTIVATE_NOW;
815 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
818 /* IIvi, IIvx use the "Brazil" framebuffer (which is
819 very much like the V8, it seems, and probably uses
824 strcat( macfb_fix.id, "Brazil built-in" );
825 macfb_setpalette = v8_brazil_setpalette;
826 macfb_defined.activate = FB_ACTIVATE_NOW;
827 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
830 /* LC III (and friends) use the Sonora framebuffer */
831 /* Incidentally this is also used in the non-AV models
832 of the x100 PowerMacs */
833 /* These do in fact seem to use the same DAC interface
835 case MAC_MODEL_LCIII:
839 macfb_setpalette = v8_brazil_setpalette;
840 macfb_defined.activate = FB_ACTIVATE_NOW;
841 strcat( macfb_fix.id, "Sonora built-in" );
842 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
845 /* IIci and IIsi use the infamous RBV chip
846 (the IIsi is just a rebadged and crippled
847 IIci in a different case, BTW) */
850 macfb_setpalette = rbv_setpalette;
851 macfb_defined.activate = FB_ACTIVATE_NOW;
852 strcat( macfb_fix.id, "RBV built-in" );
853 rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
856 /* AVs use the Civic framebuffer */
859 macfb_setpalette = civic_setpalette;
860 macfb_defined.activate = FB_ACTIVATE_NOW;
861 strcat( macfb_fix.id, "Civic built-in" );
862 civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
866 /* Write a setpalette function for your machine, then
867 you can add something similar here. These are
868 grouped by classes of video chipsets. Some of this
869 information is from the VideoToolbox "Bugs" web
871 http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
873 /* Assorted weirdos */
874 /* We think this may be like the LC II */
877 macfb_setpalette = v8_brazil_setpalette;
878 macfb_defined.activate = FB_ACTIVATE_NOW;
879 v8_brazil_cmap_regs =
880 ioremap(DAC_BASE, 0x1000);
882 strcat( macfb_fix.id, "LC built-in" );
884 /* We think this may be like the LC II */
887 macfb_setpalette = v8_brazil_setpalette;
888 macfb_defined.activate = FB_ACTIVATE_NOW;
889 v8_brazil_cmap_regs =
890 ioremap(DAC_BASE, 0x1000);
892 strcat( macfb_fix.id, "Color Classic built-in" );
895 /* And we *do* mean "weirdos" */
897 strcat( macfb_fix.id, "Mac TV built-in" );
900 /* These don't have colour, so no need to worry */
903 strcat( macfb_fix.id, "Monochrome built-in" );
906 /* Powerbooks are particularly difficult. Many of
907 them have separate framebuffers for external and
908 internal video, which is admittedly pretty cool,
909 but will be a bit of a headache to support here.
910 Also, many of them are grayscale, and we don't
911 really support that. */
913 case MAC_MODEL_PB140:
914 case MAC_MODEL_PB145:
915 case MAC_MODEL_PB170:
916 strcat( macfb_fix.id, "DDC built-in" );
919 /* Internal is GSC, External (if present) is ViSC */
920 case MAC_MODEL_PB150: /* no external video */
921 case MAC_MODEL_PB160:
922 case MAC_MODEL_PB165:
923 case MAC_MODEL_PB180:
924 case MAC_MODEL_PB210:
925 case MAC_MODEL_PB230:
926 strcat( macfb_fix.id, "GSC built-in" );
929 /* Internal is TIM, External is ViSC */
930 case MAC_MODEL_PB165C:
931 case MAC_MODEL_PB180C:
932 strcat( macfb_fix.id, "TIM built-in" );
935 /* Internal is CSC, External is Keystone+Ariel. */
936 case MAC_MODEL_PB190: /* external video is optional */
937 case MAC_MODEL_PB520:
938 case MAC_MODEL_PB250:
939 case MAC_MODEL_PB270C:
940 case MAC_MODEL_PB280:
941 case MAC_MODEL_PB280C:
942 macfb_setpalette = csc_setpalette;
943 macfb_defined.activate = FB_ACTIVATE_NOW;
944 strcat( macfb_fix.id, "CSC built-in" );
945 csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
949 strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
953 fb_info.fbops = &macfb_ops;
954 fb_info.var = macfb_defined;
955 fb_info.fix = macfb_fix;
956 fb_info.pseudo_palette = pseudo_palette;
957 fb_info.flags = FBINFO_DEFAULT;
959 fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
961 err = register_framebuffer(&fb_info);
963 printk("fb%d: %s frame buffer device\n",
964 fb_info.node, fb_info.fix.id);
968 module_init(macfb_init);
969 MODULE_LICENSE("GPL");