Auto-update from upstream
[firewire-audio.git] / drivers / video / macfb.c
blobcfc748e9427260037a075a0ad78ebdc8e90c4560
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>
26 #include <linux/mm.h>
27 #include <linux/tty.h>
28 #include <linux/slab.h>
29 #include <linux/delay.h>
30 #include <linux/nubus.h>
31 #include <linux/init.h>
32 #include <linux/fb.h>
34 #include <asm/setup.h>
35 #include <asm/bootinfo.h>
36 #include <asm/uaccess.h>
37 #include <asm/pgtable.h>
38 #include <asm/irq.h>
39 #include <asm/macintosh.h>
40 #include <asm/io.h>
41 #include <asm/machw.h>
43 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
44 #define DAC_BASE 0x50f24000
46 /* Some addresses for the DAFB */
47 #define DAFB_BASE 0xf9800200
49 /* Address for the built-in Civic framebuffer in Quadra AVs */
50 #define CIVIC_BASE 0x50f30800 /* Only tested on 660AV! */
52 /* GSC (Gray Scale Controller) base address */
53 #define GSC_BASE 0x50F20000
55 /* CSC (Color Screen Controller) base address */
56 #define CSC_BASE 0x50F20000
58 static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
59 unsigned int green, unsigned int blue,
60 struct fb_info *info) = NULL;
61 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
62 unsigned int green, unsigned int blue,
63 struct fb_info *info);
64 static int dafb_setpalette (unsigned int regno, unsigned int red,
65 unsigned int green, unsigned int blue,
66 struct fb_info *fb_info);
67 static int rbv_setpalette (unsigned int regno, unsigned int red,
68 unsigned int green, unsigned int blue,
69 struct fb_info *fb_info);
70 static int mdc_setpalette (unsigned int regno, unsigned int red,
71 unsigned int green, unsigned int blue,
72 struct fb_info *fb_info);
73 static int toby_setpalette (unsigned int regno, unsigned int red,
74 unsigned int green, unsigned int blue,
75 struct fb_info *fb_info);
76 static int civic_setpalette (unsigned int regno, unsigned int red,
77 unsigned int green, unsigned int blue,
78 struct fb_info *fb_info);
79 static int csc_setpalette (unsigned int regno, unsigned int red,
80 unsigned int green, unsigned int blue,
81 struct fb_info *fb_info);
83 static volatile struct {
84 unsigned char addr;
85 /* Note: word-aligned */
86 char pad[3];
87 unsigned char lut;
88 } *valkyrie_cmap_regs;
90 static volatile struct {
91 unsigned char addr;
92 unsigned char lut;
93 } *v8_brazil_cmap_regs;
95 static volatile struct {
96 unsigned char addr;
97 char pad1[3]; /* word aligned */
98 unsigned char lut;
99 char pad2[3]; /* word aligned */
100 unsigned char cntl; /* a guess as to purpose */
101 } *rbv_cmap_regs;
103 static volatile struct {
104 unsigned long reset;
105 unsigned long pad1[3];
106 unsigned char pad2[3];
107 unsigned char lut;
108 } *dafb_cmap_regs;
110 static volatile struct {
111 unsigned char addr; /* OFFSET: 0x00 */
112 unsigned char pad1[15];
113 unsigned char lut; /* OFFSET: 0x10 */
114 unsigned char pad2[15];
115 unsigned char status; /* OFFSET: 0x20 */
116 unsigned char pad3[7];
117 unsigned long vbl_addr; /* OFFSET: 0x28 */
118 unsigned int status2; /* OFFSET: 0x2C */
119 } *civic_cmap_regs;
121 static volatile struct {
122 char pad1[0x40];
123 unsigned char clut_waddr; /* 0x40 */
124 char pad2;
125 unsigned char clut_data; /* 0x42 */
126 char pad3[0x3];
127 unsigned char clut_raddr; /* 0x46 */
128 } *csc_cmap_regs;
130 /* We will leave these the way they are for the time being */
131 struct mdc_cmap_regs {
132 char pad1[0x200200];
133 unsigned char addr;
134 char pad2[6];
135 unsigned char lut;
138 struct toby_cmap_regs {
139 char pad1[0x90018];
140 unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
141 char pad2[3];
142 unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
145 struct jet_cmap_regs {
146 char pad1[0xe0e000];
147 unsigned char addr;
148 unsigned char lut;
151 #define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */
153 /* mode */
154 static int video_slot = 0;
156 static struct fb_var_screeninfo macfb_defined = {
157 .bits_per_pixel = 8,
158 .activate = FB_ACTIVATE_NOW,
159 .width = -1,
160 .height = -1,
161 .right_margin = 32,
162 .upper_margin = 16,
163 .lower_margin = 4,
164 .vsync_len = 4,
165 .vmode = FB_VMODE_NONINTERLACED,
168 static struct fb_fix_screeninfo macfb_fix = {
169 .id = "Macintosh ",
170 .type = FB_TYPE_PACKED_PIXELS,
171 .accel = FB_ACCEL_NONE,
174 static struct fb_info fb_info;
175 static u32 pseudo_palette[17];
176 static int inverse = 0;
177 static int vidtest = 0;
179 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
180 unsigned int green, unsigned int blue,
181 struct fb_info *info)
183 unsigned long flags;
185 red >>= 8;
186 green >>= 8;
187 blue >>= 8;
189 local_irq_save(flags);
191 /* tell clut which address to fill */
192 nubus_writeb(regno, &valkyrie_cmap_regs->addr);
193 nop();
195 /* send one color channel at a time */
196 nubus_writeb(red, &valkyrie_cmap_regs->lut);
197 nop();
198 nubus_writeb(green, &valkyrie_cmap_regs->lut);
199 nop();
200 nubus_writeb(blue, &valkyrie_cmap_regs->lut);
202 local_irq_restore(flags);
203 return 0;
206 /* Unlike the Valkyrie, the DAFB cannot set individual colormap
207 registers. Therefore, we do what the MacOS driver does (no
208 kidding!) and simply set them one by one until we hit the one we
209 want. */
210 static int dafb_setpalette (unsigned int regno, unsigned int red,
211 unsigned int green, unsigned int blue,
212 struct fb_info *info)
214 /* FIXME: really, really need to use ioremap() here,
215 phys_to_virt() doesn't work anymore */
216 static int lastreg = -1;
217 unsigned long flags;
219 red >>= 8;
220 green >>= 8;
221 blue >>= 8;
223 local_irq_save(flags);
225 /* fbdev will set an entire colourmap, but X won't. Hopefully
226 this should accommodate both of them */
227 if (regno != lastreg+1) {
228 int i;
230 /* Stab in the dark trying to reset the CLUT pointer */
231 nubus_writel(0, &dafb_cmap_regs->reset);
232 nop();
234 /* Loop until we get to the register we want */
235 for (i = 0; i < regno; i++) {
236 nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
237 nop();
238 nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
239 nop();
240 nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
241 nop();
245 nubus_writeb(red, &dafb_cmap_regs->lut);
246 nop();
247 nubus_writeb(green, &dafb_cmap_regs->lut);
248 nop();
249 nubus_writeb(blue, &dafb_cmap_regs->lut);
251 local_irq_restore(flags);
252 lastreg = regno;
253 return 0;
256 /* V8 and Brazil seem to use the same DAC. Sonora does as well. */
257 static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
258 unsigned int green, unsigned int blue,
259 struct fb_info *info)
261 unsigned int bpp = info->var.bits_per_pixel;
262 unsigned char _red =red>>8;
263 unsigned char _green=green>>8;
264 unsigned char _blue =blue>>8;
265 unsigned char _regno;
266 unsigned long flags;
268 if (bpp > 8) return 1; /* failsafe */
270 local_irq_save(flags);
272 /* On these chips, the CLUT register numbers are spread out
273 across the register space. Thus:
275 In 8bpp, all regnos are valid.
277 In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
279 In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
280 _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
281 nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
283 /* send one color channel at a time */
284 nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
285 nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
286 nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
288 local_irq_restore(flags);
289 return 0;
292 static int rbv_setpalette (unsigned int regno, unsigned int red,
293 unsigned int green, unsigned int blue,
294 struct fb_info *info)
296 /* use MSBs */
297 unsigned char _red =red>>8;
298 unsigned char _green=green>>8;
299 unsigned char _blue =blue>>8;
300 unsigned char _regno;
301 unsigned long flags;
303 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
305 local_irq_save(flags);
307 /* From the VideoToolbox driver. Seems to be saying that
308 * regno #254 and #255 are the important ones for 1-bit color,
309 * regno #252-255 are the important ones for 2-bit color, etc.
311 _regno = regno + (256-(1 << info->var.bits_per_pixel));
313 /* reset clut? (VideoToolbox sez "not necessary") */
314 nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
316 /* tell clut which address to use. */
317 nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
319 /* send one color channel at a time. */
320 nubus_writeb(_red, &rbv_cmap_regs->lut); nop();
321 nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
322 nubus_writeb(_blue, &rbv_cmap_regs->lut);
324 local_irq_restore(flags); /* done. */
325 return 0;
328 /* Macintosh Display Card (8x24) */
329 static int mdc_setpalette(unsigned int regno, unsigned int red,
330 unsigned int green, unsigned int blue,
331 struct fb_info *info)
333 volatile struct mdc_cmap_regs *cmap_regs =
334 nubus_slot_addr(video_slot);
335 /* use MSBs */
336 unsigned char _red =red>>8;
337 unsigned char _green=green>>8;
338 unsigned char _blue =blue>>8;
339 unsigned char _regno=regno;
340 unsigned long flags;
342 local_irq_save(flags);
344 /* the nop's are there to order writes. */
345 nubus_writeb(_regno, &cmap_regs->addr); nop();
346 nubus_writeb(_red, &cmap_regs->lut); nop();
347 nubus_writeb(_green, &cmap_regs->lut); nop();
348 nubus_writeb(_blue, &cmap_regs->lut);
350 local_irq_restore(flags);
351 return 0;
354 /* Toby frame buffer */
355 static int toby_setpalette(unsigned int regno, unsigned int red,
356 unsigned int green, unsigned int blue,
357 struct fb_info *info)
359 volatile struct toby_cmap_regs *cmap_regs =
360 nubus_slot_addr(video_slot);
361 unsigned int bpp = info->var.bits_per_pixel;
362 /* use MSBs */
363 unsigned char _red =~(red>>8);
364 unsigned char _green=~(green>>8);
365 unsigned char _blue =~(blue>>8);
366 unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
367 unsigned long flags;
369 local_irq_save(flags);
371 nubus_writeb(_regno, &cmap_regs->addr); nop();
372 nubus_writeb(_red, &cmap_regs->lut); nop();
373 nubus_writeb(_green, &cmap_regs->lut); nop();
374 nubus_writeb(_blue, &cmap_regs->lut);
376 local_irq_restore(flags);
377 return 0;
380 /* Jet frame buffer */
381 static int jet_setpalette(unsigned int regno, unsigned int red,
382 unsigned int green, unsigned int blue,
383 struct fb_info *info)
385 volatile struct jet_cmap_regs *cmap_regs =
386 nubus_slot_addr(video_slot);
387 /* use MSBs */
388 unsigned char _red = (red>>8);
389 unsigned char _green = (green>>8);
390 unsigned char _blue = (blue>>8);
391 unsigned long flags;
393 local_irq_save(flags);
395 nubus_writeb(regno, &cmap_regs->addr); nop();
396 nubus_writeb(_red, &cmap_regs->lut); nop();
397 nubus_writeb(_green, &cmap_regs->lut); nop();
398 nubus_writeb(_blue, &cmap_regs->lut);
400 local_irq_restore(flags);
401 return 0;
405 * Civic framebuffer -- Quadra AV built-in video. A chip
406 * called Sebastian holds the actual color palettes, and
407 * apparently, there are two different banks of 512K RAM
408 * which can act as separate framebuffers for doing video
409 * input and viewing the screen at the same time! The 840AV
410 * Can add another 1MB RAM to give the two framebuffers
411 * 1MB RAM apiece.
413 * FIXME: this doesn't seem to work anymore.
415 static int civic_setpalette (unsigned int regno, unsigned int red,
416 unsigned int green, unsigned int blue,
417 struct fb_info *info)
419 static int lastreg = -1;
420 unsigned long flags;
421 int clut_status;
423 if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
425 red >>= 8;
426 green >>= 8;
427 blue >>= 8;
429 local_irq_save(flags);
432 * Set the register address
434 nubus_writeb(regno, &civic_cmap_regs->addr); nop();
437 * Wait for VBL interrupt here;
438 * They're usually not enabled from Penguin, so we won't check
440 #if 0
442 #define CIVIC_VBL_OFFSET 0x120
443 volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
444 /* do interrupt setup stuff here? */
445 *vbl = 0L; nop(); /* clear */
446 *vbl = 1L; nop(); /* set */
447 while (*vbl != 0L) /* wait for next vbl */
449 usleep(10); /* needed? */
451 /* do interrupt shutdown stuff here? */
453 #endif
456 * Grab a status word and do some checking;
457 * Then finally write the clut!
459 clut_status = nubus_readb(&civic_cmap_regs->status2);
461 if ((clut_status & 0x0008) == 0)
463 #if 0
464 if ((clut_status & 0x000D) != 0)
466 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
467 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
469 #endif
471 nubus_writeb( red, &civic_cmap_regs->lut); nop();
472 nubus_writeb(green, &civic_cmap_regs->lut); nop();
473 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
474 nubus_writeb( 0x00, &civic_cmap_regs->lut); nop();
476 else
478 unsigned char junk;
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();
483 junk = nubus_readb(&civic_cmap_regs->lut); nop();
485 if ((clut_status & 0x000D) != 0)
487 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
488 nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
491 nubus_writeb( red, &civic_cmap_regs->lut); nop();
492 nubus_writeb(green, &civic_cmap_regs->lut); nop();
493 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
494 nubus_writeb( junk, &civic_cmap_regs->lut); nop();
497 local_irq_restore(flags);
498 lastreg = regno;
499 return 0;
503 * The CSC is the framebuffer on the PowerBook 190 series
504 * (and the 5300 too, but that's a PowerMac). This function
505 * brought to you in part by the ECSC driver for MkLinux.
508 static int csc_setpalette (unsigned int regno, unsigned int red,
509 unsigned int green, unsigned int blue,
510 struct fb_info *info)
512 mdelay(1);
513 csc_cmap_regs->clut_waddr = regno;
514 csc_cmap_regs->clut_data = red;
515 csc_cmap_regs->clut_data = green;
516 csc_cmap_regs->clut_data = blue;
517 return 0;
520 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
521 unsigned blue, unsigned transp,
522 struct fb_info *fb_info)
525 * Set a single color register. The values supplied are
526 * already rounded down to the hardware's capabilities
527 * (according to the entries in the `var' structure). Return
528 * != 0 for invalid regno.
531 if (regno >= fb_info->cmap.len)
532 return 1;
534 switch (fb_info->var.bits_per_pixel) {
535 case 1:
536 /* We shouldn't get here */
537 break;
538 case 2:
539 case 4:
540 case 8:
541 if (macfb_setpalette)
542 macfb_setpalette(regno, red, green, blue, fb_info);
543 else
544 return 1;
545 break;
546 case 16:
547 if (fb_info->var.red.offset == 10) {
548 /* 1:5:5:5 */
549 ((u32*) (fb_info->pseudo_palette))[regno] =
550 ((red & 0xf800) >> 1) |
551 ((green & 0xf800) >> 6) |
552 ((blue & 0xf800) >> 11) |
553 ((transp != 0) << 15);
554 } else {
555 /* 0:5:6:5 */
556 ((u32*) (fb_info->pseudo_palette))[regno] =
557 ((red & 0xf800) ) |
558 ((green & 0xfc00) >> 5) |
559 ((blue & 0xf800) >> 11);
561 break;
562 /* I'm pretty sure that one or the other of these
563 doesn't exist on 68k Macs */
564 case 24:
565 red >>= 8;
566 green >>= 8;
567 blue >>= 8;
568 ((u32 *)(fb_info->pseudo_palette))[regno] =
569 (red << fb_info->var.red.offset) |
570 (green << fb_info->var.green.offset) |
571 (blue << fb_info->var.blue.offset);
572 break;
573 case 32:
574 red >>= 8;
575 green >>= 8;
576 blue >>= 8;
577 ((u32 *)(fb_info->pseudo_palette))[regno] =
578 (red << fb_info->var.red.offset) |
579 (green << fb_info->var.green.offset) |
580 (blue << fb_info->var.blue.offset);
581 break;
583 return 0;
586 static struct fb_ops macfb_ops = {
587 .owner = THIS_MODULE,
588 .fb_setcolreg = macfb_setcolreg,
589 .fb_fillrect = cfb_fillrect,
590 .fb_copyarea = cfb_copyarea,
591 .fb_imageblit = cfb_imageblit,
594 void __init macfb_setup(char *options)
596 char *this_opt;
598 if (!options || !*options)
599 return;
601 while ((this_opt = strsep(&options, ",")) != NULL) {
602 if (!*this_opt) continue;
604 if (! strcmp(this_opt, "inverse"))
605 inverse=1;
606 /* This means "turn on experimental CLUT code" */
607 else if (!strcmp(this_opt, "vidtest"))
608 vidtest=1;
612 void __init macfb_init(void)
614 int video_cmap_len, video_is_nubus = 0;
615 struct nubus_dev* ndev = NULL;
616 char *option = NULL;
618 if (fb_get_options("macfb", &option))
619 return -ENODEV;
620 macfb_setup(option);
622 if (!MACH_IS_MAC)
623 return;
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
638 Mac */
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) {
664 case 1:
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;
670 video_cmap_len = 0;
671 macfb_fix.visual = FB_VISUAL_MONO01;
672 break;
673 case 2:
674 case 4:
675 case 8:
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;
681 break;
682 case 16:
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");
693 video_cmap_len = 16;
694 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
695 works too */
696 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
697 break;
698 case 24:
699 case 32:
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");
710 video_cmap_len = 16;
711 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
712 default:
713 video_cmap_len = 0;
714 macfb_fix.visual = FB_VISUAL_MONO01;
715 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
716 break;
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
723 * video or not.
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))
729 != NULL)
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))))
734 continue;
735 video_is_nubus = 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;
744 break;
745 case NUBUS_DRHW_APPLE_TFB:
746 strcat( macfb_fix.id, "Toby" );
747 macfb_setpalette = toby_setpalette;
748 macfb_defined.activate = FB_ACTIVATE_NOW;
749 break;
750 case NUBUS_DRHW_APPLE_JET:
751 strcat( macfb_fix.id, "Jet");
752 macfb_setpalette = jet_setpalette;
753 macfb_defined.activate = FB_ACTIVATE_NOW;
754 break;
755 default:
756 strcat( macfb_fix.id, "Generic NuBus" );
757 break;
761 /* If it's not a NuBus card, it must be internal video */
762 /* FIXME: this function is getting way too big. (this driver
763 is too...) */
764 if (!video_is_nubus)
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) */
770 case MAC_MODEL_II:
771 case MAC_MODEL_IIX:
772 case MAC_MODEL_IICX:
773 case MAC_MODEL_IIFX:
774 strcat( macfb_fix.id, "Generic NuBus" );
775 break;
777 /* Valkyrie Quadras */
778 case MAC_MODEL_Q630:
779 /* I'm not sure about this one */
780 case MAC_MODEL_P588:
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);
785 break;
787 /* DAFB Quadras */
788 /* Note: these first four have the v7 DAFB, which is
789 known to be rather unlike the ones used in the
790 other models */
791 case MAC_MODEL_P475:
792 case MAC_MODEL_P475F:
793 case MAC_MODEL_P575:
794 case MAC_MODEL_Q605:
796 case MAC_MODEL_Q800:
797 case MAC_MODEL_Q650:
798 case MAC_MODEL_Q610:
799 case MAC_MODEL_C650:
800 case MAC_MODEL_C610:
801 case MAC_MODEL_Q700:
802 case MAC_MODEL_Q900:
803 case MAC_MODEL_Q950:
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);
808 break;
810 /* LC II uses the V8 framebuffer */
811 case MAC_MODEL_LCII:
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);
816 break;
818 /* IIvi, IIvx use the "Brazil" framebuffer (which is
819 very much like the V8, it seems, and probably uses
820 the same DAC) */
821 case MAC_MODEL_IIVI:
822 case MAC_MODEL_IIVX:
823 case MAC_MODEL_P600:
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);
828 break;
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
834 as the LC II. */
835 case MAC_MODEL_LCIII:
836 case MAC_MODEL_P520:
837 case MAC_MODEL_P550:
838 case MAC_MODEL_P460:
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);
843 break;
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) */
848 case MAC_MODEL_IICI:
849 case MAC_MODEL_IISI:
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);
854 break;
856 /* AVs use the Civic framebuffer */
857 case MAC_MODEL_Q840:
858 case MAC_MODEL_C660:
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);
863 break;
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
870 page at
871 http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
873 /* Assorted weirdos */
874 /* We think this may be like the LC II */
875 case MAC_MODEL_LC:
876 if (vidtest) {
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" );
883 break;
884 /* We think this may be like the LC II */
885 case MAC_MODEL_CCL:
886 if (vidtest) {
887 macfb_setpalette = v8_brazil_setpalette;
888 macfb_defined.activate = FB_ACTIVATE_NOW;
889 v8_brazil_cmap_regs =
890 ioremap(DAC_BASE, 0x1000);
892 strcat( macfb_fix.id, "Color Classic built-in" );
893 break;
895 /* And we *do* mean "weirdos" */
896 case MAC_MODEL_TV:
897 strcat( macfb_fix.id, "Mac TV built-in" );
898 break;
900 /* These don't have colour, so no need to worry */
901 case MAC_MODEL_SE30:
902 case MAC_MODEL_CLII:
903 strcat( macfb_fix.id, "Monochrome built-in" );
904 break;
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" );
917 break;
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" );
927 break;
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" );
933 break;
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);
946 break;
948 default:
949 strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
950 break;
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 if (register_framebuffer(&fb_info) < 0)
962 return;
964 printk("fb%d: %s frame buffer device\n",
965 fb_info.node, fb_info.fix.id);
968 module_init(macfb_init);
969 MODULE_LICENSE("GPL");