ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / video / macfb.c
1 /* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
2    don't know how to set */
3
4 /* (c) 1999 David Huggins-Daines <dhd@debian.org>
5
6    Primarily based on vesafb.c, by Gerd Knorr
7    (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
8
9    Also uses information and code from:
10    
11    The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
12    Mellinger, Mikael Forselius, Michael Schmitz, and others.
13
14    valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
15    Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
16    
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. */
20
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>
33
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>
42
43 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
44 #define DAC_BASE 0x50f24000
45
46 /* Some addresses for the DAFB */
47 #define DAFB_BASE 0xf9800200
48
49 /* Address for the built-in Civic framebuffer in Quadra AVs */
50 #define CIVIC_BASE 0x50f30800   /* Only tested on 660AV! */
51
52 /* GSC (Gray Scale Controller) base address */
53 #define GSC_BASE 0x50F20000
54
55 /* CSC (Color Screen Controller) base address */
56 #define CSC_BASE 0x50F20000
57
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);
82
83 static volatile struct {
84         unsigned char addr;
85         /* Note: word-aligned */
86         char pad[3];
87         unsigned char lut;
88 } *valkyrie_cmap_regs;
89
90 static volatile struct {
91         unsigned char addr;
92         unsigned char lut;
93 } *v8_brazil_cmap_regs;
94
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;
102
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;
109
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;
120
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;
129
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;
136 };
137
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 */
143 };
144
145 struct jet_cmap_regs {
146         char pad1[0xe0e000];
147         unsigned char addr;
148         unsigned char lut;
149 };
150
151 #define PIXEL_TO_MM(a)  (((a)*10)/28)   /* width in mm at 72 dpi */     
152
153 /* mode */
154 static int  video_slot = 0;
155
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,
166 };
167
168 static struct fb_fix_screeninfo macfb_fix = {
169         .id     = "Macintosh ",
170         .type   = FB_TYPE_PACKED_PIXELS,
171         .accel  = FB_ACCEL_NONE,
172 };
173
174 static struct fb_info fb_info;
175 static u32 pseudo_palette[17];
176 static int inverse   = 0;
177 static int vidtest   = 0;
178
179 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
180                                 unsigned int green, unsigned int blue,
181                                 struct fb_info *info)
182 {
183         unsigned long flags;
184         
185         red >>= 8;
186         green >>= 8;
187         blue >>= 8;
188
189         local_irq_save(flags);
190         
191         /* tell clut which address to fill */
192         nubus_writeb(regno, &valkyrie_cmap_regs->addr);
193         nop();
194
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);
201
202         local_irq_restore(flags);
203         return 0;
204 }
205
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)
213 {
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;
218         
219         red >>= 8;
220         green >>= 8;
221         blue >>= 8;
222
223         local_irq_save(flags);
224         
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;
229                 
230                 /* Stab in the dark trying to reset the CLUT pointer */
231                 nubus_writel(0, &dafb_cmap_regs->reset);
232                 nop();
233                 
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();
242                 }
243         }
244                 
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);
250         
251         local_irq_restore(flags);
252         lastreg = regno;
253         return 0;
254 }
255
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)  
260 {
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;
267
268         if (bpp > 8) return 1; /* failsafe */
269
270         local_irq_save(flags);
271
272         /* On these chips, the CLUT register numbers are spread out
273            across the register space.  Thus:
274
275            In 8bpp, all regnos are valid.
276            
277            In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
278            
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();
282
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);
287
288         local_irq_restore(flags);       
289         return 0;
290 }
291
292 static int rbv_setpalette (unsigned int regno, unsigned int red,
293                            unsigned int green, unsigned int blue,
294                            struct fb_info *info)
295 {
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;
302
303         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
304
305         local_irq_save(flags);
306         
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.
310          */
311         _regno = regno + (256-(1 << info->var.bits_per_pixel));
312
313         /* reset clut? (VideoToolbox sez "not necessary") */
314         nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
315         
316         /* tell clut which address to use. */
317         nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
318         
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);
323         
324         local_irq_restore(flags); /* done. */
325         return 0;
326 }
327
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)
332 {
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;
341
342         local_irq_save(flags);
343         
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);
349
350         local_irq_restore(flags);
351         return 0;
352 }
353
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) 
358 {
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;
368
369         local_irq_save(flags);
370                 
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);
375
376         local_irq_restore(flags);
377         return 0;
378 }
379
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)
384 {
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;
392
393         local_irq_save(flags);
394         
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);
399
400         local_irq_restore(flags);
401         return 0;
402 }
403
404 /*
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.
412  *
413  * FIXME: this doesn't seem to work anymore.
414  */
415 static int civic_setpalette (unsigned int regno, unsigned int red,
416                              unsigned int green, unsigned int blue,
417                              struct fb_info *info)
418 {
419         static int lastreg = -1;
420         unsigned long flags;
421         int clut_status;
422         
423         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
424
425         red   >>= 8;
426         green >>= 8;
427         blue  >>= 8;
428
429         local_irq_save(flags);
430         
431         /*
432          * Set the register address
433          */
434         nubus_writeb(regno, &civic_cmap_regs->addr); nop();
435
436         /*
437          * Wait for VBL interrupt here;
438          * They're usually not enabled from Penguin, so we won't check
439          */
440 #if 0
441         {
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 */
448                 {
449                         usleep(10);     /* needed? */
450                 }
451                 /* do interrupt shutdown stuff here? */
452         }
453 #endif
454
455         /*
456          * Grab a status word and do some checking;
457          * Then finally write the clut!
458          */
459         clut_status =  nubus_readb(&civic_cmap_regs->status2);
460
461         if ((clut_status & 0x0008) == 0)
462         {
463 #if 0
464                 if ((clut_status & 0x000D) != 0)
465                 {
466                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
467                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
468                 }
469 #endif
470
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();
475         }
476         else
477         {
478                 unsigned char junk;
479
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();
484
485                 if ((clut_status & 0x000D) != 0)
486                 {
487                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
488                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
489                 }
490
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();
495         }
496
497         local_irq_restore(flags);
498         lastreg = regno;
499         return 0;
500 }
501
502 /*
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.
506  */
507
508 static int csc_setpalette (unsigned int regno, unsigned int red,
509                            unsigned int green, unsigned int blue,
510                            struct fb_info *info)
511 {
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;
518 }
519
520 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
521                            unsigned blue, unsigned transp,
522                            struct fb_info *fb_info)
523 {
524         /*
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.
529          */
530         
531         if (regno >= fb_info->cmap.len)
532                 return 1;
533
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);
560                 }
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;
582     }
583     return 0;
584 }
585
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,
592         .fb_cursor      = soft_cursor,
593 };
594
595 void __init macfb_setup(char *options)
596 {
597         char *this_opt;
598         
599         if (!options || !*options)
600                 return;
601         
602         while ((this_opt = strsep(&options, ",")) != NULL) {
603                 if (!*this_opt) continue;
604                 
605                 if (! strcmp(this_opt, "inverse"))
606                         inverse=1;
607                 /* This means "turn on experimental CLUT code" */
608                 else if (!strcmp(this_opt, "vidtest"))
609                         vidtest=1;
610         }
611 }
612
613 void __init macfb_init(void)
614 {
615         int video_cmap_len, video_is_nubus = 0;
616         struct nubus_dev* ndev = NULL;
617
618         if (!MACH_IS_MAC) 
619                 return;
620
621         /* There can only be one internal video controller anyway so
622            we're not too worried about this */
623         macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
624         macfb_defined.yres = mac_bi_data.dimensions >> 16;
625         macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
626         macfb_fix.line_length = mac_bi_data.videorow;
627         macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
628         /* Note: physical address (since 2.1.127) */
629         macfb_fix.smem_start = mac_bi_data.videoaddr;
630         /* This is actually redundant with the initial mappings.
631            However, there are some non-obvious aspects to the way
632            those mappings are set up, so this is in fact the safest
633            way to ensure that this driver will work on every possible
634            Mac */
635         fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
636         
637         printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
638                macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
639         printk("macfb: mode is %dx%dx%d, linelength=%d\n",
640                macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
641         
642         /*
643          *      Fill in the available video resolution
644          */
645          
646         macfb_defined.xres_virtual   = macfb_defined.xres;
647         macfb_defined.yres_virtual   = macfb_defined.yres;
648         macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
649         macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);  
650
651         printk("macfb: scrolling: redraw\n");
652         macfb_defined.yres_virtual = macfb_defined.yres;
653
654         /* some dummy values for timing to make fbset happy */
655         macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
656         macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
657         macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
658
659         switch (macfb_defined.bits_per_pixel) {
660         case 1:
661                 /* XXX: I think this will catch any program that tries
662                    to do FBIO_PUTCMAP when the visual is monochrome */
663                 video_cmap_len = 0;
664                 macfb_fix.visual = FB_VISUAL_MONO01;
665                 break;
666         case 2:
667         case 4:
668         case 8:
669                 macfb_defined.red.length = macfb_defined.bits_per_pixel;
670                 macfb_defined.green.length = macfb_defined.bits_per_pixel;
671                 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
672                 video_cmap_len = 1 << macfb_defined.bits_per_pixel;
673                 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
674                 break;
675         case 16:
676                 macfb_defined.transp.offset = 15;
677                 macfb_defined.transp.length = 1;
678                 macfb_defined.red.offset = 10;
679                 macfb_defined.red.length = 5;
680                 macfb_defined.green.offset = 5;
681                 macfb_defined.green.length = 5;
682                 macfb_defined.blue.offset = 0;
683                 macfb_defined.blue.length = 5;
684                 printk("macfb: directcolor: "
685                        "size=1:5:5:5, shift=15:10:5:0\n");
686                 video_cmap_len = 16;
687                 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
688                    works too */
689                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
690                 break;
691         case 24:
692         case 32:
693                 /* XXX: have to test these... can any 68k Macs
694                    actually do this on internal video? */
695                 macfb_defined.red.offset = 16;
696                 macfb_defined.red.length = 8;
697                 macfb_defined.green.offset = 8;
698                 macfb_defined.green.length = 8;
699                 macfb_defined.blue.offset = 0;
700                 macfb_defined.blue.length = 8;
701                 printk("macfb: truecolor: "
702                        "size=0:8:8:8, shift=0:16:8:0\n");
703                 video_cmap_len = 16;
704                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
705         default:
706                 video_cmap_len = 0;
707                 macfb_fix.visual = FB_VISUAL_MONO01;
708                 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
709                 break;
710         }
711         
712         /* Hardware dependent stuff */
713         /*  We take a wild guess that if the video physical address is
714          *  in nubus slot space, that the nubus card is driving video.
715          *  Penguin really ought to tell us whether we are using internal
716          *  video or not.
717          */
718         /* Hopefully we only find one of them.  Otherwise our NuBus
719            code is really broken :-) */
720
721         while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
722                 != NULL)
723         {
724                 if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
725                       && (mac_bi_data.videoaddr <
726                           (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
727                         continue;
728                 video_is_nubus = 1;
729                 /* We should probably just use the slot address... */
730                 video_slot = ndev->board->slot;
731
732                 switch(ndev->dr_hw) {
733                 case NUBUS_DRHW_APPLE_MDC:
734                         strcat( macfb_fix.id, "Display Card" );
735                         macfb_setpalette = mdc_setpalette;
736                         macfb_defined.activate = FB_ACTIVATE_NOW;
737                         break;
738                 case NUBUS_DRHW_APPLE_TFB:
739                         strcat( macfb_fix.id, "Toby" );
740                         macfb_setpalette = toby_setpalette;
741                         macfb_defined.activate = FB_ACTIVATE_NOW;
742                         break;
743                 case NUBUS_DRHW_APPLE_JET:
744                         strcat( macfb_fix.id, "Jet");
745                         macfb_setpalette = jet_setpalette;
746                         macfb_defined.activate = FB_ACTIVATE_NOW;
747                         break;                  
748                 default:
749                         strcat( macfb_fix.id, "Generic NuBus" );
750                         break;
751                 }
752         }
753
754         /* If it's not a NuBus card, it must be internal video */
755         /* FIXME: this function is getting way too big.  (this driver
756            is too...) */
757         if (!video_is_nubus)
758                 switch( mac_bi_data.id )
759                 {
760                         /* These don't have onboard video.  Eventually, we may
761                            be able to write separate framebuffer drivers for
762                            them (tobyfb.c, hiresfb.c, etc, etc) */
763                 case MAC_MODEL_II:
764                 case MAC_MODEL_IIX:
765                 case MAC_MODEL_IICX:
766                 case MAC_MODEL_IIFX:
767                         strcat( macfb_fix.id, "Generic NuBus" );
768                         break;
769
770                         /* Valkyrie Quadras */
771                 case MAC_MODEL_Q630:
772                         /* I'm not sure about this one */
773                 case MAC_MODEL_P588:
774                         strcat( macfb_fix.id, "Valkyrie built-in" );
775                         macfb_setpalette = valkyrie_setpalette;
776                         macfb_defined.activate = FB_ACTIVATE_NOW;
777                         valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
778                         break;
779
780                         /* DAFB Quadras */
781                         /* Note: these first four have the v7 DAFB, which is
782                            known to be rather unlike the ones used in the
783                            other models */
784                 case MAC_MODEL_P475:
785                 case MAC_MODEL_P475F:
786                 case MAC_MODEL_P575:
787                 case MAC_MODEL_Q605:
788         
789                 case MAC_MODEL_Q800:
790                 case MAC_MODEL_Q650:
791                 case MAC_MODEL_Q610:
792                 case MAC_MODEL_C650:
793                 case MAC_MODEL_C610:
794                 case MAC_MODEL_Q700:
795                 case MAC_MODEL_Q900:
796                 case MAC_MODEL_Q950:
797                         strcat( macfb_fix.id, "DAFB built-in" );
798                         macfb_setpalette = dafb_setpalette;
799                         macfb_defined.activate = FB_ACTIVATE_NOW;
800                         dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
801                         break;
802
803                         /* LC II uses the V8 framebuffer */
804                 case MAC_MODEL_LCII:
805                         strcat( macfb_fix.id, "V8 built-in" );
806                         macfb_setpalette = v8_brazil_setpalette;
807                         macfb_defined.activate = FB_ACTIVATE_NOW;
808                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
809                         break;
810                 
811                         /* IIvi, IIvx use the "Brazil" framebuffer (which is
812                            very much like the V8, it seems, and probably uses
813                            the same DAC) */
814                 case MAC_MODEL_IIVI:
815                 case MAC_MODEL_IIVX:
816                 case MAC_MODEL_P600:
817                         strcat( macfb_fix.id, "Brazil built-in" );
818                         macfb_setpalette = v8_brazil_setpalette;
819                         macfb_defined.activate = FB_ACTIVATE_NOW;
820                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
821                         break;
822                 
823                         /* LC III (and friends) use the Sonora framebuffer */
824                         /* Incidentally this is also used in the non-AV models
825                            of the x100 PowerMacs */
826                         /* These do in fact seem to use the same DAC interface
827                            as the LC II. */
828                 case MAC_MODEL_LCIII:
829                 case MAC_MODEL_P520:
830                 case MAC_MODEL_P550:
831                 case MAC_MODEL_P460:
832                         macfb_setpalette = v8_brazil_setpalette;
833                         macfb_defined.activate = FB_ACTIVATE_NOW;
834                         strcat( macfb_fix.id, "Sonora built-in" );
835                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
836                         break;
837
838                         /* IIci and IIsi use the infamous RBV chip
839                            (the IIsi is just a rebadged and crippled
840                            IIci in a different case, BTW) */
841                 case MAC_MODEL_IICI:
842                 case MAC_MODEL_IISI:
843                         macfb_setpalette = rbv_setpalette;
844                         macfb_defined.activate = FB_ACTIVATE_NOW;
845                         strcat( macfb_fix.id, "RBV built-in" );
846                         rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
847                         break;
848
849                         /* AVs use the Civic framebuffer */
850                 case MAC_MODEL_Q840:
851                 case MAC_MODEL_C660:
852                         macfb_setpalette = civic_setpalette;
853                         macfb_defined.activate = FB_ACTIVATE_NOW;
854                         strcat( macfb_fix.id, "Civic built-in" );
855                         civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
856                         break;
857
858                 
859                         /* Write a setpalette function for your machine, then
860                            you can add something similar here.  These are
861                            grouped by classes of video chipsets.  Some of this
862                            information is from the VideoToolbox "Bugs" web
863                            page at
864                            http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
865
866                         /* Assorted weirdos */
867                         /* We think this may be like the LC II */
868                 case MAC_MODEL_LC:
869                         if (vidtest) {
870                                 macfb_setpalette = v8_brazil_setpalette;
871                                 macfb_defined.activate = FB_ACTIVATE_NOW;
872                                 v8_brazil_cmap_regs =
873                                         ioremap(DAC_BASE, 0x1000);
874                         }
875                         strcat( macfb_fix.id, "LC built-in" );
876                         break;
877                         /* We think this may be like the LC II */
878                 case MAC_MODEL_CCL:
879                         if (vidtest) {
880                                 macfb_setpalette = v8_brazil_setpalette;
881                                 macfb_defined.activate = FB_ACTIVATE_NOW;
882                                 v8_brazil_cmap_regs =
883                                         ioremap(DAC_BASE, 0x1000);
884                         }
885                         strcat( macfb_fix.id, "Color Classic built-in" );
886                         break;
887
888                         /* And we *do* mean "weirdos" */
889                 case MAC_MODEL_TV:
890                         strcat( macfb_fix.id, "Mac TV built-in" );
891                         break;
892
893                         /* These don't have colour, so no need to worry */
894                 case MAC_MODEL_SE30:
895                 case MAC_MODEL_CLII:
896                         strcat( macfb_fix.id, "Monochrome built-in" );
897                         break;
898
899                         /* Powerbooks are particularly difficult.  Many of
900                            them have separate framebuffers for external and
901                            internal video, which is admittedly pretty cool,
902                            but will be a bit of a headache to support here.
903                            Also, many of them are grayscale, and we don't
904                            really support that. */
905
906                 case MAC_MODEL_PB140:
907                 case MAC_MODEL_PB145:
908                 case MAC_MODEL_PB170:
909                         strcat( macfb_fix.id, "DDC built-in" );
910                         break;
911
912                         /* Internal is GSC, External (if present) is ViSC */
913                 case MAC_MODEL_PB150:   /* no external video */
914                 case MAC_MODEL_PB160:
915                 case MAC_MODEL_PB165:
916                 case MAC_MODEL_PB180:
917                 case MAC_MODEL_PB210:
918                 case MAC_MODEL_PB230:
919                         strcat( macfb_fix.id, "GSC built-in" );
920                         break;
921
922                         /* Internal is TIM, External is ViSC */
923                 case MAC_MODEL_PB165C:
924                 case MAC_MODEL_PB180C:
925                         strcat( macfb_fix.id, "TIM built-in" );
926                         break;
927
928                         /* Internal is CSC, External is Keystone+Ariel. */
929                 case MAC_MODEL_PB190:   /* external video is optional */
930                 case MAC_MODEL_PB520:
931                 case MAC_MODEL_PB250:
932                 case MAC_MODEL_PB270C:
933                 case MAC_MODEL_PB280:
934                 case MAC_MODEL_PB280C:
935                         macfb_setpalette = csc_setpalette;
936                         macfb_defined.activate = FB_ACTIVATE_NOW;
937                         strcat( macfb_fix.id, "CSC built-in" );
938                         csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
939                         break;
940                 
941                 default:
942                         strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
943                         break;
944                 }
945
946         fb_info.fbops           = &macfb_ops;
947         fb_info.var             = macfb_defined;
948         fb_info.fix             = macfb_fix;
949         fb_info.pseudo_palette  = pseudo_palette;
950         fb_info.flags           = FBINFO_FLAG_DEFAULT;
951
952         fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
953         
954         if (register_framebuffer(&fb_info) < 0)
955                 return;
956
957         printk("fb%d: %s frame buffer device\n",
958                fb_info.node, fb_info.fix.id);
959 }
960
961 MODULE_LICENSE("GPL");