2 * macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
3 * don't know how to set.
5 * (c) 1999 David Huggins-Daines <dhd@debian.org>
7 * Primarily based on vesafb.c, by Gerd Knorr
8 * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
10 * Also uses information and code from:
12 * The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
13 * Mellinger, Mikael Forselius, Michael Schmitz, and others.
15 * valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
16 * Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
18 * The VideoToolbox "Bugs" web page at
19 * http://rajsky.psych.nyu.edu/Tips/VideoBugs.html
21 * This code is free software. You may copy, modify, and distribute
22 * it subject to the terms and conditions of the GNU General Public
23 * License, version 2, or any later version, at your convenience.
26 #include <linux/module.h>
27 #include <linux/kernel.h>
28 #include <linux/errno.h>
29 #include <linux/string.h>
31 #include <linux/delay.h>
32 #include <linux/nubus.h>
33 #include <linux/init.h>
36 #include <asm/setup.h>
37 #include <asm/macintosh.h>
40 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
41 #define DAC_BASE 0x50f24000
43 /* Some addresses for the DAFB */
44 #define DAFB_BASE 0xf9800200
46 /* Address for the built-in Civic framebuffer in Quadra AVs */
47 #define CIVIC_BASE 0x50f30800
49 /* GSC (Gray Scale Controller) base address */
50 #define GSC_BASE 0x50F20000
52 /* CSC (Color Screen Controller) base address */
53 #define CSC_BASE 0x50F20000
55 static int (*macfb_setpalette)(unsigned int regno, unsigned int red,
56 unsigned int green, unsigned int blue,
57 struct fb_info *info);
62 } __iomem *v8_brazil_cmap_regs;
66 char pad1[3]; /* word aligned */
68 char pad2[3]; /* word aligned */
69 unsigned char cntl; /* a guess as to purpose */
70 } __iomem *rbv_cmap_regs;
74 unsigned long pad1[3];
75 unsigned char pad2[3];
77 } __iomem *dafb_cmap_regs;
80 unsigned char addr; /* OFFSET: 0x00 */
81 unsigned char pad1[15];
82 unsigned char lut; /* OFFSET: 0x10 */
83 unsigned char pad2[15];
84 unsigned char status; /* OFFSET: 0x20 */
85 unsigned char pad3[7];
86 unsigned long vbl_addr; /* OFFSET: 0x28 */
87 unsigned int status2; /* OFFSET: 0x2C */
88 } __iomem *civic_cmap_regs;
92 unsigned char clut_waddr; /* 0x40 */
94 unsigned char clut_data; /* 0x42 */
96 unsigned char clut_raddr; /* 0x46 */
97 } __iomem *csc_cmap_regs;
99 /* The registers in these structs are in NuBus slot space */
100 struct mdc_cmap_regs {
107 struct toby_cmap_regs {
109 unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
111 unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
114 struct jet_cmap_regs {
120 #define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */
122 static struct fb_var_screeninfo macfb_defined = {
123 .activate = FB_ACTIVATE_NOW,
128 .vmode = FB_VMODE_NONINTERLACED,
131 static struct fb_fix_screeninfo macfb_fix = {
132 .type = FB_TYPE_PACKED_PIXELS,
133 .accel = FB_ACCEL_NONE,
136 static void *slot_addr;
137 static struct fb_info fb_info;
138 static u32 pseudo_palette[16];
142 * Unlike the Valkyrie, the DAFB cannot set individual colormap
143 * registers. Therefore, we do what the MacOS driver does (no
144 * kidding!) and simply set them one by one until we hit the one we
147 static int dafb_setpalette(unsigned int regno, unsigned int red,
148 unsigned int green, unsigned int blue,
149 struct fb_info *info)
151 static int lastreg = -1;
154 local_irq_save(flags);
157 * fbdev will set an entire colourmap, but X won't. Hopefully
158 * this should accommodate both of them
160 if (regno != lastreg + 1) {
163 /* Stab in the dark trying to reset the CLUT pointer */
164 nubus_writel(0, &dafb_cmap_regs->reset);
167 /* Loop until we get to the register we want */
168 for (i = 0; i < regno; i++) {
169 nubus_writeb(info->cmap.red[i] >> 8,
170 &dafb_cmap_regs->lut);
172 nubus_writeb(info->cmap.green[i] >> 8,
173 &dafb_cmap_regs->lut);
175 nubus_writeb(info->cmap.blue[i] >> 8,
176 &dafb_cmap_regs->lut);
181 nubus_writeb(red, &dafb_cmap_regs->lut);
183 nubus_writeb(green, &dafb_cmap_regs->lut);
185 nubus_writeb(blue, &dafb_cmap_regs->lut);
187 local_irq_restore(flags);
192 /* V8 and Brazil seem to use the same DAC. Sonora does as well. */
193 static int v8_brazil_setpalette(unsigned int regno, unsigned int red,
194 unsigned int green, unsigned int blue,
195 struct fb_info *info)
197 unsigned int bpp = info->var.bits_per_pixel;
200 local_irq_save(flags);
202 /* On these chips, the CLUT register numbers are spread out
203 * across the register space. Thus:
204 * In 8bpp, all regnos are valid.
205 * In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
206 * In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff
208 regno = (regno << (8 - bpp)) | (0xFF >> bpp);
209 nubus_writeb(regno, &v8_brazil_cmap_regs->addr);
212 /* send one color channel at a time */
213 nubus_writeb(red, &v8_brazil_cmap_regs->lut);
215 nubus_writeb(green, &v8_brazil_cmap_regs->lut);
217 nubus_writeb(blue, &v8_brazil_cmap_regs->lut);
219 local_irq_restore(flags);
223 /* RAM-Based Video */
224 static int rbv_setpalette(unsigned int regno, unsigned int red,
225 unsigned int green, unsigned int blue,
226 struct fb_info *info)
230 local_irq_save(flags);
232 /* From the VideoToolbox driver. Seems to be saying that
233 * regno #254 and #255 are the important ones for 1-bit color,
234 * regno #252-255 are the important ones for 2-bit color, etc.
236 regno += 256 - (1 << info->var.bits_per_pixel);
238 /* reset clut? (VideoToolbox sez "not necessary") */
239 nubus_writeb(0xFF, &rbv_cmap_regs->cntl);
242 /* tell clut which address to use. */
243 nubus_writeb(regno, &rbv_cmap_regs->addr);
246 /* send one color channel at a time. */
247 nubus_writeb(red, &rbv_cmap_regs->lut);
249 nubus_writeb(green, &rbv_cmap_regs->lut);
251 nubus_writeb(blue, &rbv_cmap_regs->lut);
253 local_irq_restore(flags);
257 /* Macintosh Display Card (8*24) */
258 static int mdc_setpalette(unsigned int regno, unsigned int red,
259 unsigned int green, unsigned int blue,
260 struct fb_info *info)
262 struct mdc_cmap_regs *cmap_regs = slot_addr;
265 local_irq_save(flags);
267 /* the nop's are there to order writes. */
268 nubus_writeb(regno, &cmap_regs->addr);
270 nubus_writeb(red, &cmap_regs->lut);
272 nubus_writeb(green, &cmap_regs->lut);
274 nubus_writeb(blue, &cmap_regs->lut);
276 local_irq_restore(flags);
280 /* Toby frame buffer */
281 static int toby_setpalette(unsigned int regno, unsigned int red,
282 unsigned int green, unsigned int blue,
283 struct fb_info *info)
285 struct toby_cmap_regs *cmap_regs = slot_addr;
286 unsigned int bpp = info->var.bits_per_pixel;
292 regno = (regno << (8 - bpp)) | (0xFF >> bpp);
294 local_irq_save(flags);
296 nubus_writeb(regno, &cmap_regs->addr);
298 nubus_writeb(red, &cmap_regs->lut);
300 nubus_writeb(green, &cmap_regs->lut);
302 nubus_writeb(blue, &cmap_regs->lut);
304 local_irq_restore(flags);
308 /* Jet frame buffer */
309 static int jet_setpalette(unsigned int regno, unsigned int red,
310 unsigned int green, unsigned int blue,
311 struct fb_info *info)
313 struct jet_cmap_regs *cmap_regs = slot_addr;
316 local_irq_save(flags);
318 nubus_writeb(regno, &cmap_regs->addr);
320 nubus_writeb(red, &cmap_regs->lut);
322 nubus_writeb(green, &cmap_regs->lut);
324 nubus_writeb(blue, &cmap_regs->lut);
326 local_irq_restore(flags);
331 * Civic framebuffer -- Quadra AV built-in video. A chip
332 * called Sebastian holds the actual color palettes, and
333 * apparently, there are two different banks of 512K RAM
334 * which can act as separate framebuffers for doing video
335 * input and viewing the screen at the same time! The 840AV
336 * Can add another 1MB RAM to give the two framebuffers
339 static int civic_setpalette(unsigned int regno, unsigned int red,
340 unsigned int green, unsigned int blue,
341 struct fb_info *info)
346 local_irq_save(flags);
348 /* Set the register address */
349 nubus_writeb(regno, &civic_cmap_regs->addr);
353 * Grab a status word and do some checking;
354 * Then finally write the clut!
356 clut_status = nubus_readb(&civic_cmap_regs->status2);
358 if ((clut_status & 0x0008) == 0)
361 if ((clut_status & 0x000D) != 0)
363 nubus_writeb(0x00, &civic_cmap_regs->lut);
365 nubus_writeb(0x00, &civic_cmap_regs->lut);
370 nubus_writeb(red, &civic_cmap_regs->lut);
372 nubus_writeb(green, &civic_cmap_regs->lut);
374 nubus_writeb(blue, &civic_cmap_regs->lut);
376 nubus_writeb(0x00, &civic_cmap_regs->lut);
382 junk = nubus_readb(&civic_cmap_regs->lut);
384 junk = nubus_readb(&civic_cmap_regs->lut);
386 junk = nubus_readb(&civic_cmap_regs->lut);
388 junk = nubus_readb(&civic_cmap_regs->lut);
391 if ((clut_status & 0x000D) != 0)
393 nubus_writeb(0x00, &civic_cmap_regs->lut);
395 nubus_writeb(0x00, &civic_cmap_regs->lut);
399 nubus_writeb(red, &civic_cmap_regs->lut);
401 nubus_writeb(green, &civic_cmap_regs->lut);
403 nubus_writeb(blue, &civic_cmap_regs->lut);
405 nubus_writeb(junk, &civic_cmap_regs->lut);
408 local_irq_restore(flags);
413 * The CSC is the framebuffer on the PowerBook 190 series
414 * (and the 5300 too, but that's a PowerMac). This function
415 * brought to you in part by the ECSC driver for MkLinux.
417 static int csc_setpalette(unsigned int regno, unsigned int red,
418 unsigned int green, unsigned int blue,
419 struct fb_info *info)
423 local_irq_save(flags);
425 udelay(1); /* mklinux on PB 5300 waits for 260 ns */
426 nubus_writeb(regno, &csc_cmap_regs->clut_waddr);
427 nubus_writeb(red, &csc_cmap_regs->clut_data);
428 nubus_writeb(green, &csc_cmap_regs->clut_data);
429 nubus_writeb(blue, &csc_cmap_regs->clut_data);
431 local_irq_restore(flags);
435 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
436 unsigned blue, unsigned transp,
437 struct fb_info *fb_info)
440 * Set a single color register. The values supplied are
441 * already rounded down to the hardware's capabilities
442 * (according to the entries in the `var' structure).
443 * Return non-zero for invalid regno.
446 if (regno >= fb_info->cmap.len)
449 if (fb_info->var.bits_per_pixel <= 8) {
450 switch (fb_info->var.bits_per_pixel) {
452 /* We shouldn't get here */
457 if (macfb_setpalette)
458 macfb_setpalette(regno, red >> 8, green >> 8,
464 } else if (regno < 16) {
465 switch (fb_info->var.bits_per_pixel) {
467 if (fb_info->var.red.offset == 10) {
469 ((u32*) (fb_info->pseudo_palette))[regno] =
470 ((red & 0xf800) >> 1) |
471 ((green & 0xf800) >> 6) |
472 ((blue & 0xf800) >> 11) |
473 ((transp != 0) << 15);
476 ((u32*) (fb_info->pseudo_palette))[regno] =
477 ((red & 0xf800) >> 0) |
478 ((green & 0xfc00) >> 5) |
479 ((blue & 0xf800) >> 11);
483 * 24-bit colour almost doesn't exist on 68k Macs --
484 * http://support.apple.com/kb/TA28634 (Old Article: 10992)
491 ((u32 *)(fb_info->pseudo_palette))[regno] =
492 (red << fb_info->var.red.offset) |
493 (green << fb_info->var.green.offset) |
494 (blue << fb_info->var.blue.offset);
502 static struct fb_ops macfb_ops = {
503 .owner = THIS_MODULE,
504 .fb_setcolreg = macfb_setcolreg,
505 .fb_fillrect = cfb_fillrect,
506 .fb_copyarea = cfb_copyarea,
507 .fb_imageblit = cfb_imageblit,
510 static void __init macfb_setup(char *options)
514 if (!options || !*options)
517 while ((this_opt = strsep(&options, ",")) != NULL) {
521 if (!strcmp(this_opt, "inverse"))
524 if (!strcmp(this_opt, "vidtest"))
525 vidtest = 1; /* enable experimental CLUT code */
529 static void __init iounmap_macfb(void)
532 iounmap(dafb_cmap_regs);
533 if (v8_brazil_cmap_regs)
534 iounmap(v8_brazil_cmap_regs);
536 iounmap(rbv_cmap_regs);
538 iounmap(civic_cmap_regs);
540 iounmap(csc_cmap_regs);
543 static int __init macfb_init(void)
545 int video_cmap_len, video_is_nubus = 0;
546 struct nubus_rsrc *ndev = NULL;
550 if (fb_get_options("macfb", &option))
557 if (mac_bi_data.id == MAC_MODEL_Q630 ||
558 mac_bi_data.id == MAC_MODEL_P588)
559 return -ENODEV; /* See valkyriefb.c */
561 macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
562 macfb_defined.yres = mac_bi_data.dimensions >> 16;
563 macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
565 macfb_fix.line_length = mac_bi_data.videorow;
566 macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
567 /* Note: physical address (since 2.1.127) */
568 macfb_fix.smem_start = mac_bi_data.videoaddr;
571 * This is actually redundant with the initial mappings.
572 * However, there are some non-obvious aspects to the way
573 * those mappings are set up, so this is in fact the safest
574 * way to ensure that this driver will work on every possible Mac
576 fb_info.screen_base = ioremap(mac_bi_data.videoaddr,
578 if (!fb_info.screen_base)
581 pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
582 macfb_fix.smem_start, fb_info.screen_base,
583 macfb_fix.smem_len / 1024);
584 pr_info("macfb: mode is %dx%dx%d, linelength=%d\n",
585 macfb_defined.xres, macfb_defined.yres,
586 macfb_defined.bits_per_pixel, macfb_fix.line_length);
588 /* Fill in the available video resolution */
589 macfb_defined.xres_virtual = macfb_defined.xres;
590 macfb_defined.yres_virtual = macfb_defined.yres;
591 macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
592 macfb_defined.width = PIXEL_TO_MM(macfb_defined.xres);
594 /* Some dummy values for timing to make fbset happy */
595 macfb_defined.pixclock = 10000000 / macfb_defined.xres *
596 1000 / macfb_defined.yres;
597 macfb_defined.left_margin = (macfb_defined.xres / 8) & 0xf8;
598 macfb_defined.hsync_len = (macfb_defined.xres / 8) & 0xf8;
600 switch (macfb_defined.bits_per_pixel) {
602 macfb_defined.red.length = macfb_defined.bits_per_pixel;
603 macfb_defined.green.length = macfb_defined.bits_per_pixel;
604 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
606 macfb_fix.visual = FB_VISUAL_MONO01;
611 macfb_defined.red.length = macfb_defined.bits_per_pixel;
612 macfb_defined.green.length = macfb_defined.bits_per_pixel;
613 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
614 video_cmap_len = 1 << macfb_defined.bits_per_pixel;
615 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
618 macfb_defined.transp.offset = 15;
619 macfb_defined.transp.length = 1;
620 macfb_defined.red.offset = 10;
621 macfb_defined.red.length = 5;
622 macfb_defined.green.offset = 5;
623 macfb_defined.green.length = 5;
624 macfb_defined.blue.offset = 0;
625 macfb_defined.blue.length = 5;
628 * Should actually be FB_VISUAL_DIRECTCOLOR, but this
631 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
635 macfb_defined.red.offset = 16;
636 macfb_defined.red.length = 8;
637 macfb_defined.green.offset = 8;
638 macfb_defined.green.length = 8;
639 macfb_defined.blue.offset = 0;
640 macfb_defined.blue.length = 8;
642 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
645 pr_err("macfb: unknown or unsupported bit depth: %d\n",
646 macfb_defined.bits_per_pixel);
652 * We take a wild guess that if the video physical address is
653 * in nubus slot space, that the nubus card is driving video.
654 * Penguin really ought to tell us whether we are using internal
656 * Hopefully we only find one of them. Otherwise our NuBus
657 * code is really broken :-)
660 for_each_func_rsrc(ndev) {
661 unsigned long base = ndev->board->slot_addr;
663 if (mac_bi_data.videoaddr < base ||
664 mac_bi_data.videoaddr - base > 0xFFFFFF)
667 if (ndev->category != NUBUS_CAT_DISPLAY ||
668 ndev->type != NUBUS_TYPE_VIDEO)
672 slot_addr = (unsigned char *)base;
674 switch(ndev->dr_hw) {
675 case NUBUS_DRHW_APPLE_MDC:
676 strcpy(macfb_fix.id, "Mac Disp. Card");
677 macfb_setpalette = mdc_setpalette;
679 case NUBUS_DRHW_APPLE_TFB:
680 strcpy(macfb_fix.id, "Toby");
681 macfb_setpalette = toby_setpalette;
683 case NUBUS_DRHW_APPLE_JET:
684 strcpy(macfb_fix.id, "Jet");
685 macfb_setpalette = jet_setpalette;
688 strcpy(macfb_fix.id, "Generic NuBus");
693 /* If it's not a NuBus card, it must be internal video */
695 switch (mac_bi_data.id) {
698 * Note: these first four have the v7 DAFB, which is
699 * known to be rather unlike the ones used in the
703 case MAC_MODEL_P475F:
715 strcpy(macfb_fix.id, "DAFB");
716 macfb_setpalette = dafb_setpalette;
717 dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
721 * LC II uses the V8 framebuffer
724 strcpy(macfb_fix.id, "V8");
725 macfb_setpalette = v8_brazil_setpalette;
726 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
730 * IIvi, IIvx use the "Brazil" framebuffer (which is
731 * very much like the V8, it seems, and probably uses
737 strcpy(macfb_fix.id, "Brazil");
738 macfb_setpalette = v8_brazil_setpalette;
739 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
743 * LC III (and friends) use the Sonora framebuffer
744 * Incidentally this is also used in the non-AV models
745 * of the x100 PowerMacs
746 * These do in fact seem to use the same DAC interface
749 case MAC_MODEL_LCIII:
753 strcpy(macfb_fix.id, "Sonora");
754 macfb_setpalette = v8_brazil_setpalette;
755 v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
759 * IIci and IIsi use the infamous RBV chip
760 * (the IIsi is just a rebadged and crippled
761 * IIci in a different case, BTW)
765 strcpy(macfb_fix.id, "RBV");
766 macfb_setpalette = rbv_setpalette;
767 rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
771 * AVs use the Civic framebuffer
775 strcpy(macfb_fix.id, "Civic");
776 macfb_setpalette = civic_setpalette;
777 civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
783 * We think this may be like the LC II
786 strcpy(macfb_fix.id, "LC");
788 macfb_setpalette = v8_brazil_setpalette;
789 v8_brazil_cmap_regs =
790 ioremap(DAC_BASE, 0x1000);
795 * We think this may be like the LC II
798 strcpy(macfb_fix.id, "Color Classic");
800 macfb_setpalette = v8_brazil_setpalette;
801 v8_brazil_cmap_regs =
802 ioremap(DAC_BASE, 0x1000);
807 * And we *do* mean "weirdos"
810 strcpy(macfb_fix.id, "Mac TV");
814 * These don't have colour, so no need to worry
818 strcpy(macfb_fix.id, "Monochrome");
822 * Powerbooks are particularly difficult. Many of
823 * them have separate framebuffers for external and
824 * internal video, which is admittedly pretty cool,
825 * but will be a bit of a headache to support here.
826 * Also, many of them are grayscale, and we don't
827 * really support that.
831 * Slot 0 ROM says TIM. No external video. B&W.
833 case MAC_MODEL_PB140:
834 case MAC_MODEL_PB145:
835 case MAC_MODEL_PB170:
836 strcpy(macfb_fix.id, "DDC");
840 * Internal is GSC, External (if present) is ViSC
842 case MAC_MODEL_PB150: /* no external video */
843 case MAC_MODEL_PB160:
844 case MAC_MODEL_PB165:
845 case MAC_MODEL_PB180:
846 case MAC_MODEL_PB210:
847 case MAC_MODEL_PB230:
848 strcpy(macfb_fix.id, "GSC");
852 * Internal is TIM, External is ViSC
854 case MAC_MODEL_PB165C:
855 case MAC_MODEL_PB180C:
856 strcpy(macfb_fix.id, "TIM");
860 * Internal is CSC, External is Keystone+Ariel.
862 case MAC_MODEL_PB190: /* external video is optional */
863 case MAC_MODEL_PB520:
864 case MAC_MODEL_PB250:
865 case MAC_MODEL_PB270C:
866 case MAC_MODEL_PB280:
867 case MAC_MODEL_PB280C:
868 strcpy(macfb_fix.id, "CSC");
869 macfb_setpalette = csc_setpalette;
870 csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
874 strcpy(macfb_fix.id, "Unknown");
878 fb_info.fbops = &macfb_ops;
879 fb_info.var = macfb_defined;
880 fb_info.fix = macfb_fix;
881 fb_info.pseudo_palette = pseudo_palette;
882 fb_info.flags = FBINFO_DEFAULT;
884 err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
888 err = register_framebuffer(&fb_info);
892 fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);
897 fb_dealloc_cmap(&fb_info.cmap);
899 iounmap(fb_info.screen_base);
904 module_init(macfb_init);
905 MODULE_LICENSE("GPL");