Merge branch 'topic/oxygen' into for-linus
[linux-2.6] / 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/errno.h>
24 #include <linux/string.h>
25 #include <linux/mm.h>
26 #include <linux/slab.h>
27 #include <linux/delay.h>
28 #include <linux/nubus.h>
29 #include <linux/init.h>
30 #include <linux/fb.h>
31
32 #include <asm/setup.h>
33 #include <asm/bootinfo.h>
34 #include <asm/uaccess.h>
35 #include <asm/pgtable.h>
36 #include <asm/irq.h>
37 #include <asm/macintosh.h>
38 #include <asm/io.h>
39
40 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
41 #define DAC_BASE 0x50f24000
42
43 /* Some addresses for the DAFB */
44 #define DAFB_BASE 0xf9800200
45
46 /* Address for the built-in Civic framebuffer in Quadra AVs */
47 #define CIVIC_BASE 0x50f30800   /* Only tested on 660AV! */
48
49 /* GSC (Gray Scale Controller) base address */
50 #define GSC_BASE 0x50F20000
51
52 /* CSC (Color Screen Controller) base address */
53 #define CSC_BASE 0x50F20000
54
55 static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
56                                 unsigned int green, unsigned int blue,
57                                 struct fb_info *info) = NULL;
58 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
59                                 unsigned int green, unsigned int blue,
60                                 struct fb_info *info);
61 static int dafb_setpalette (unsigned int regno, unsigned int red,
62                             unsigned int green, unsigned int blue,
63                             struct fb_info *fb_info);
64 static int rbv_setpalette (unsigned int regno, unsigned int red,
65                            unsigned int green, unsigned int blue,
66                            struct fb_info *fb_info);
67 static int mdc_setpalette (unsigned int regno, unsigned int red,
68                            unsigned int green, unsigned int blue,
69                            struct fb_info *fb_info);
70 static int toby_setpalette (unsigned int regno, unsigned int red,
71                             unsigned int green, unsigned int blue,
72                             struct fb_info *fb_info);
73 static int civic_setpalette (unsigned int regno, unsigned int red,
74                              unsigned int green, unsigned int blue,
75                              struct fb_info *fb_info);
76 static int csc_setpalette (unsigned int regno, unsigned int red,
77                            unsigned int green, unsigned int blue,
78                            struct fb_info *fb_info);
79
80 static struct {
81         unsigned char addr;
82         /* Note: word-aligned */
83         char pad[3];
84         unsigned char lut;
85 } __iomem *valkyrie_cmap_regs;
86
87 static struct {
88         unsigned char addr;
89         unsigned char lut;
90 } __iomem *v8_brazil_cmap_regs;
91
92 static struct {
93         unsigned char addr;
94         char pad1[3]; /* word aligned */
95         unsigned char lut;
96         char pad2[3]; /* word aligned */
97         unsigned char cntl; /* a guess as to purpose */
98 } __iomem *rbv_cmap_regs;
99
100 static struct {
101         unsigned long reset;
102         unsigned long pad1[3];
103         unsigned char pad2[3];
104         unsigned char lut;
105 } __iomem *dafb_cmap_regs;
106
107 static struct {
108         unsigned char addr;     /* OFFSET: 0x00 */
109         unsigned char pad1[15];
110         unsigned char lut;      /* OFFSET: 0x10 */
111         unsigned char pad2[15];
112         unsigned char status;   /* OFFSET: 0x20 */
113         unsigned char pad3[7];
114         unsigned long vbl_addr; /* OFFSET: 0x28 */
115         unsigned int  status2;  /* OFFSET: 0x2C */
116 } __iomem *civic_cmap_regs;
117
118 static struct {
119         char    pad1[0x40];
120         unsigned char   clut_waddr;     /* 0x40 */
121         char    pad2;
122         unsigned char   clut_data;      /* 0x42 */
123         char    pad3[0x3];
124         unsigned char   clut_raddr;     /* 0x46 */
125 } __iomem *csc_cmap_regs;
126
127 /* We will leave these the way they are for the time being */
128 struct mdc_cmap_regs {
129         char pad1[0x200200];
130         unsigned char addr;
131         char pad2[6];
132         unsigned char lut;
133 };
134
135 struct toby_cmap_regs {
136         char pad1[0x90018];
137         unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
138         char pad2[3];
139         unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
140 };
141
142 struct jet_cmap_regs {
143         char pad1[0xe0e000];
144         unsigned char addr;
145         unsigned char lut;
146 };
147
148 #define PIXEL_TO_MM(a)  (((a)*10)/28)   /* width in mm at 72 dpi */     
149
150 /* mode */
151 static int  video_slot = 0;
152
153 static struct fb_var_screeninfo macfb_defined = {
154         .bits_per_pixel = 8,    
155         .activate       = FB_ACTIVATE_NOW,
156         .width          = -1,
157         .height         = -1,
158         .right_margin   = 32,
159         .upper_margin   = 16,
160         .lower_margin   = 4,
161         .vsync_len      = 4,
162         .vmode          = FB_VMODE_NONINTERLACED,
163 };
164
165 static struct fb_fix_screeninfo macfb_fix = {
166         .type   = FB_TYPE_PACKED_PIXELS,
167         .accel  = FB_ACCEL_NONE,
168 };
169
170 static struct fb_info fb_info;
171 static u32 pseudo_palette[16];
172 static int inverse   = 0;
173 static int vidtest   = 0;
174
175 static int valkyrie_setpalette (unsigned int regno, unsigned int red,
176                                 unsigned int green, unsigned int blue,
177                                 struct fb_info *info)
178 {
179         unsigned long flags;
180         
181         red >>= 8;
182         green >>= 8;
183         blue >>= 8;
184
185         local_irq_save(flags);
186         
187         /* tell clut which address to fill */
188         nubus_writeb(regno, &valkyrie_cmap_regs->addr);
189         nop();
190
191         /* send one color channel at a time */
192         nubus_writeb(red, &valkyrie_cmap_regs->lut);
193         nop();
194         nubus_writeb(green, &valkyrie_cmap_regs->lut);
195         nop();
196         nubus_writeb(blue, &valkyrie_cmap_regs->lut);
197
198         local_irq_restore(flags);
199         return 0;
200 }
201
202 /* Unlike the Valkyrie, the DAFB cannot set individual colormap
203    registers.  Therefore, we do what the MacOS driver does (no
204    kidding!) and simply set them one by one until we hit the one we
205    want. */
206 static int dafb_setpalette (unsigned int regno, unsigned int red,
207                             unsigned int green, unsigned int blue,
208                             struct fb_info *info)
209 {
210         /* FIXME: really, really need to use ioremap() here,
211            phys_to_virt() doesn't work anymore */
212         static int lastreg = -1;
213         unsigned long flags;
214         
215         red >>= 8;
216         green >>= 8;
217         blue >>= 8;
218
219         local_irq_save(flags);
220         
221         /* fbdev will set an entire colourmap, but X won't.  Hopefully
222            this should accommodate both of them */
223         if (regno != lastreg+1) {
224                 int i;
225                 
226                 /* Stab in the dark trying to reset the CLUT pointer */
227                 nubus_writel(0, &dafb_cmap_regs->reset);
228                 nop();
229                 
230                 /* Loop until we get to the register we want */
231                 for (i = 0; i < regno; i++) {
232                         nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
233                         nop();
234                         nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
235                         nop();
236                         nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
237                         nop();
238                 }
239         }
240                 
241         nubus_writeb(red, &dafb_cmap_regs->lut);
242         nop();
243         nubus_writeb(green, &dafb_cmap_regs->lut);
244         nop();
245         nubus_writeb(blue, &dafb_cmap_regs->lut);
246         
247         local_irq_restore(flags);
248         lastreg = regno;
249         return 0;
250 }
251
252 /* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
253 static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
254                                  unsigned int green, unsigned int blue,
255                                  struct fb_info *info)  
256 {
257         unsigned int bpp = info->var.bits_per_pixel;
258         unsigned char _red  =red>>8;
259         unsigned char _green=green>>8;
260         unsigned char _blue =blue>>8;
261         unsigned char _regno;
262         unsigned long flags;
263
264         if (bpp > 8) return 1; /* failsafe */
265
266         local_irq_save(flags);
267
268         /* On these chips, the CLUT register numbers are spread out
269            across the register space.  Thus:
270
271            In 8bpp, all regnos are valid.
272            
273            In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
274            
275            In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
276         _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
277         nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
278
279         /* send one color channel at a time */
280         nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
281         nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
282         nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
283
284         local_irq_restore(flags);       
285         return 0;
286 }
287
288 static int rbv_setpalette (unsigned int regno, unsigned int red,
289                            unsigned int green, unsigned int blue,
290                            struct fb_info *info)
291 {
292         /* use MSBs */
293         unsigned char _red  =red>>8;
294         unsigned char _green=green>>8;
295         unsigned char _blue =blue>>8;
296         unsigned char _regno;
297         unsigned long flags;
298
299         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
300
301         local_irq_save(flags);
302         
303         /* From the VideoToolbox driver.  Seems to be saying that
304          * regno #254 and #255 are the important ones for 1-bit color,
305          * regno #252-255 are the important ones for 2-bit color, etc.
306          */
307         _regno = regno + (256-(1 << info->var.bits_per_pixel));
308
309         /* reset clut? (VideoToolbox sez "not necessary") */
310         nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
311         
312         /* tell clut which address to use. */
313         nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
314         
315         /* send one color channel at a time. */
316         nubus_writeb(_red,   &rbv_cmap_regs->lut); nop();
317         nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
318         nubus_writeb(_blue,  &rbv_cmap_regs->lut);
319         
320         local_irq_restore(flags); /* done. */
321         return 0;
322 }
323
324 /* Macintosh Display Card (8x24) */
325 static int mdc_setpalette(unsigned int regno, unsigned int red,
326                           unsigned int green, unsigned int blue,
327                           struct fb_info *info)
328 {
329         volatile struct mdc_cmap_regs *cmap_regs =
330                 nubus_slot_addr(video_slot);
331         /* use MSBs */
332         unsigned char _red  =red>>8;
333         unsigned char _green=green>>8;
334         unsigned char _blue =blue>>8;
335         unsigned char _regno=regno;
336         unsigned long flags;
337
338         local_irq_save(flags);
339         
340         /* the nop's are there to order writes. */
341         nubus_writeb(_regno, &cmap_regs->addr); nop();
342         nubus_writeb(_red, &cmap_regs->lut);    nop();
343         nubus_writeb(_green, &cmap_regs->lut);  nop();
344         nubus_writeb(_blue, &cmap_regs->lut);
345
346         local_irq_restore(flags);
347         return 0;
348 }
349
350 /* Toby frame buffer */
351 static int toby_setpalette(unsigned int regno, unsigned int red,
352                            unsigned int green, unsigned int blue,
353                            struct fb_info *info) 
354 {
355         volatile struct toby_cmap_regs *cmap_regs =
356                 nubus_slot_addr(video_slot);
357         unsigned int bpp = info->var.bits_per_pixel;
358         /* use MSBs */
359         unsigned char _red  =~(red>>8);
360         unsigned char _green=~(green>>8);
361         unsigned char _blue =~(blue>>8);
362         unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
363         unsigned long flags;
364
365         local_irq_save(flags);
366                 
367         nubus_writeb(_regno, &cmap_regs->addr); nop();
368         nubus_writeb(_red, &cmap_regs->lut);    nop();
369         nubus_writeb(_green, &cmap_regs->lut);  nop();
370         nubus_writeb(_blue, &cmap_regs->lut);
371
372         local_irq_restore(flags);
373         return 0;
374 }
375
376 /* Jet frame buffer */
377 static int jet_setpalette(unsigned int regno, unsigned int red,
378                           unsigned int green, unsigned int blue,
379                           struct fb_info *info)
380 {
381         volatile struct jet_cmap_regs *cmap_regs =
382                 nubus_slot_addr(video_slot);
383         /* use MSBs */
384         unsigned char _red   = (red>>8);
385         unsigned char _green = (green>>8);
386         unsigned char _blue  = (blue>>8);
387         unsigned long flags;
388
389         local_irq_save(flags);
390         
391         nubus_writeb(regno, &cmap_regs->addr); nop();
392         nubus_writeb(_red, &cmap_regs->lut); nop();
393         nubus_writeb(_green, &cmap_regs->lut); nop();
394         nubus_writeb(_blue, &cmap_regs->lut);
395
396         local_irq_restore(flags);
397         return 0;
398 }
399
400 /*
401  * Civic framebuffer -- Quadra AV built-in video.  A chip
402  * called Sebastian holds the actual color palettes, and
403  * apparently, there are two different banks of 512K RAM 
404  * which can act as separate framebuffers for doing video
405  * input and viewing the screen at the same time!  The 840AV
406  * Can add another 1MB RAM to give the two framebuffers 
407  * 1MB RAM apiece.
408  *
409  * FIXME: this doesn't seem to work anymore.
410  */
411 static int civic_setpalette (unsigned int regno, unsigned int red,
412                              unsigned int green, unsigned int blue,
413                              struct fb_info *info)
414 {
415         static int lastreg = -1;
416         unsigned long flags;
417         int clut_status;
418         
419         if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
420
421         red   >>= 8;
422         green >>= 8;
423         blue  >>= 8;
424
425         local_irq_save(flags);
426         
427         /*
428          * Set the register address
429          */
430         nubus_writeb(regno, &civic_cmap_regs->addr); nop();
431
432         /*
433          * Wait for VBL interrupt here;
434          * They're usually not enabled from Penguin, so we won't check
435          */
436 #if 0
437         {
438 #define CIVIC_VBL_OFFSET        0x120
439                 volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
440                 /* do interrupt setup stuff here? */
441                 *vbl = 0L; nop();       /* clear */
442                 *vbl = 1L; nop();       /* set */
443                 while (*vbl != 0L)      /* wait for next vbl */
444                 {
445                         usleep(10);     /* needed? */
446                 }
447                 /* do interrupt shutdown stuff here? */
448         }
449 #endif
450
451         /*
452          * Grab a status word and do some checking;
453          * Then finally write the clut!
454          */
455         clut_status =  nubus_readb(&civic_cmap_regs->status2);
456
457         if ((clut_status & 0x0008) == 0)
458         {
459 #if 0
460                 if ((clut_status & 0x000D) != 0)
461                 {
462                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
463                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
464                 }
465 #endif
466
467                 nubus_writeb(  red, &civic_cmap_regs->lut); nop();
468                 nubus_writeb(green, &civic_cmap_regs->lut); nop();
469                 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
470                 nubus_writeb( 0x00, &civic_cmap_regs->lut); nop();
471         }
472         else
473         {
474                 unsigned char junk;
475
476                 junk = nubus_readb(&civic_cmap_regs->lut); nop();
477                 junk = nubus_readb(&civic_cmap_regs->lut); nop();
478                 junk = nubus_readb(&civic_cmap_regs->lut); nop();
479                 junk = nubus_readb(&civic_cmap_regs->lut); nop();
480
481                 if ((clut_status & 0x000D) != 0)
482                 {
483                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
484                         nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
485                 }
486
487                 nubus_writeb(  red, &civic_cmap_regs->lut); nop();
488                 nubus_writeb(green, &civic_cmap_regs->lut); nop();
489                 nubus_writeb( blue, &civic_cmap_regs->lut); nop();
490                 nubus_writeb( junk, &civic_cmap_regs->lut); nop();
491         }
492
493         local_irq_restore(flags);
494         lastreg = regno;
495         return 0;
496 }
497
498 /*
499  * The CSC is the framebuffer on the PowerBook 190 series
500  * (and the 5300 too, but that's a PowerMac). This function
501  * brought to you in part by the ECSC driver for MkLinux.
502  */
503
504 static int csc_setpalette (unsigned int regno, unsigned int red,
505                            unsigned int green, unsigned int blue,
506                            struct fb_info *info)
507 {
508         mdelay(1);
509         nubus_writeb(regno, &csc_cmap_regs->clut_waddr);
510         nubus_writeb(red,   &csc_cmap_regs->clut_data);
511         nubus_writeb(green, &csc_cmap_regs->clut_data);
512         nubus_writeb(blue,  &csc_cmap_regs->clut_data);
513         return 0;
514 }
515
516 static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
517                            unsigned blue, unsigned transp,
518                            struct fb_info *fb_info)
519 {
520         /*
521          *  Set a single color register. The values supplied are
522          *  already rounded down to the hardware's capabilities
523          *  (according to the entries in the `var' structure). Return
524          *  != 0 for invalid regno.
525          */
526         
527         if (regno >= fb_info->cmap.len)
528                 return 1;
529
530         if (fb_info->var.bits_per_pixel <= 8) {
531                 switch (fb_info->var.bits_per_pixel) {
532                 case 1:
533                         /* We shouldn't get here */
534                         break;
535                 case 2:
536                 case 4:
537                 case 8:
538                         if (macfb_setpalette)
539                                 macfb_setpalette(regno, red, green, blue,
540                                                  fb_info);
541                         else
542                                 return 1;
543                         break;
544                 }
545         } else if (regno < 16) {
546                 switch (fb_info->var.bits_per_pixel) {
547                 case 16:
548                         if (fb_info->var.red.offset == 10) {
549                                 /* 1:5:5:5 */
550                                 ((u32*) (fb_info->pseudo_palette))[regno] =
551                                         ((red   & 0xf800) >>  1) |
552                                         ((green & 0xf800) >>  6) |
553                                         ((blue  & 0xf800) >> 11) |
554                                         ((transp != 0) << 15);
555                         } else {
556                                 /* 0:5:6:5 */
557                                 ((u32*) (fb_info->pseudo_palette))[regno] =
558                                         ((red   & 0xf800)      ) |
559                                         ((green & 0xfc00) >>  5) |
560                                         ((blue  & 0xf800) >> 11);
561                         }
562                         break;
563                         /* I'm pretty sure that one or the other of these
564                            doesn't exist on 68k Macs */
565                 case 24:
566                         red   >>= 8;
567                         green >>= 8;
568                         blue  >>= 8;
569                         ((u32 *)(fb_info->pseudo_palette))[regno] =
570                                 (red   << fb_info->var.red.offset)   |
571                                 (green << fb_info->var.green.offset) |
572                                 (blue  << fb_info->var.blue.offset);
573                         break;
574                 case 32:
575                         red   >>= 8;
576                         green >>= 8;
577                         blue  >>= 8;
578                         ((u32 *)(fb_info->pseudo_palette))[regno] =
579                                 (red   << fb_info->var.red.offset)   |
580                                 (green << fb_info->var.green.offset) |
581                                 (blue  << fb_info->var.blue.offset);
582                         break;
583                 }
584         }
585
586         return 0;
587 }
588
589 static struct fb_ops macfb_ops = {
590         .owner          = THIS_MODULE,
591         .fb_setcolreg   = macfb_setcolreg,
592         .fb_fillrect    = cfb_fillrect,
593         .fb_copyarea    = cfb_copyarea,
594         .fb_imageblit   = cfb_imageblit,
595 };
596
597 static void __init macfb_setup(char *options)
598 {
599         char *this_opt;
600         
601         if (!options || !*options)
602                 return;
603         
604         while ((this_opt = strsep(&options, ",")) != NULL) {
605                 if (!*this_opt) continue;
606                 
607                 if (! strcmp(this_opt, "inverse"))
608                         inverse=1;
609                 /* This means "turn on experimental CLUT code" */
610                 else if (!strcmp(this_opt, "vidtest"))
611                         vidtest=1;
612         }
613 }
614
615 static void __init iounmap_macfb(void)
616 {
617         if (valkyrie_cmap_regs)
618                 iounmap(valkyrie_cmap_regs);
619         if (dafb_cmap_regs)
620                 iounmap(dafb_cmap_regs);
621         if (v8_brazil_cmap_regs)
622                 iounmap(v8_brazil_cmap_regs);
623         if (rbv_cmap_regs)
624                 iounmap(rbv_cmap_regs);
625         if (civic_cmap_regs)
626                 iounmap(civic_cmap_regs);
627         if (csc_cmap_regs)
628                 iounmap(csc_cmap_regs);
629 }
630
631 static int __init macfb_init(void)
632 {
633         int video_cmap_len, video_is_nubus = 0;
634         struct nubus_dev* ndev = NULL;
635         char *option = NULL;
636         int err;
637
638         if (fb_get_options("macfb", &option))
639                 return -ENODEV;
640         macfb_setup(option);
641
642         if (!MACH_IS_MAC) 
643                 return -ENODEV;
644
645         /* There can only be one internal video controller anyway so
646            we're not too worried about this */
647         macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
648         macfb_defined.yres = mac_bi_data.dimensions >> 16;
649         macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
650         macfb_fix.line_length = mac_bi_data.videorow;
651         macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
652         /* Note: physical address (since 2.1.127) */
653         macfb_fix.smem_start = mac_bi_data.videoaddr;
654         /* This is actually redundant with the initial mappings.
655            However, there are some non-obvious aspects to the way
656            those mappings are set up, so this is in fact the safest
657            way to ensure that this driver will work on every possible
658            Mac */
659         fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
660         
661         printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
662                macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
663         printk("macfb: mode is %dx%dx%d, linelength=%d\n",
664                macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
665         
666         /*
667          *      Fill in the available video resolution
668          */
669          
670         macfb_defined.xres_virtual   = macfb_defined.xres;
671         macfb_defined.yres_virtual   = macfb_defined.yres;
672         macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
673         macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);  
674
675         printk("macfb: scrolling: redraw\n");
676         macfb_defined.yres_virtual = macfb_defined.yres;
677
678         /* some dummy values for timing to make fbset happy */
679         macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
680         macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
681         macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
682
683         switch (macfb_defined.bits_per_pixel) {
684         case 1:
685                 /* XXX: I think this will catch any program that tries
686                    to do FBIO_PUTCMAP when the visual is monochrome */
687                 macfb_defined.red.length = macfb_defined.bits_per_pixel;
688                 macfb_defined.green.length = macfb_defined.bits_per_pixel;
689                 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
690                 video_cmap_len = 0;
691                 macfb_fix.visual = FB_VISUAL_MONO01;
692                 break;
693         case 2:
694         case 4:
695         case 8:
696                 macfb_defined.red.length = macfb_defined.bits_per_pixel;
697                 macfb_defined.green.length = macfb_defined.bits_per_pixel;
698                 macfb_defined.blue.length = macfb_defined.bits_per_pixel;
699                 video_cmap_len = 1 << macfb_defined.bits_per_pixel;
700                 macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
701                 break;
702         case 16:
703                 macfb_defined.transp.offset = 15;
704                 macfb_defined.transp.length = 1;
705                 macfb_defined.red.offset = 10;
706                 macfb_defined.red.length = 5;
707                 macfb_defined.green.offset = 5;
708                 macfb_defined.green.length = 5;
709                 macfb_defined.blue.offset = 0;
710                 macfb_defined.blue.length = 5;
711                 printk("macfb: directcolor: "
712                        "size=1:5:5:5, shift=15:10:5:0\n");
713                 video_cmap_len = 16;
714                 /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
715                    works too */
716                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
717                 break;
718         case 24:
719         case 32:
720                 /* XXX: have to test these... can any 68k Macs
721                    actually do this on internal video? */
722                 macfb_defined.red.offset = 16;
723                 macfb_defined.red.length = 8;
724                 macfb_defined.green.offset = 8;
725                 macfb_defined.green.length = 8;
726                 macfb_defined.blue.offset = 0;
727                 macfb_defined.blue.length = 8;
728                 printk("macfb: truecolor: "
729                        "size=0:8:8:8, shift=0:16:8:0\n");
730                 video_cmap_len = 16;
731                 macfb_fix.visual = FB_VISUAL_TRUECOLOR;
732         default:
733                 video_cmap_len = 0;
734                 macfb_fix.visual = FB_VISUAL_MONO01;
735                 printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
736                 break;
737         }
738         
739         /* Hardware dependent stuff */
740         /*  We take a wild guess that if the video physical address is
741          *  in nubus slot space, that the nubus card is driving video.
742          *  Penguin really ought to tell us whether we are using internal
743          *  video or not.
744          */
745         /* Hopefully we only find one of them.  Otherwise our NuBus
746            code is really broken :-) */
747
748         while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
749                 != NULL)
750         {
751                 if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
752                       && (mac_bi_data.videoaddr <
753                           (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
754                         continue;
755                 video_is_nubus = 1;
756                 /* We should probably just use the slot address... */
757                 video_slot = ndev->board->slot;
758
759                 switch(ndev->dr_hw) {
760                 case NUBUS_DRHW_APPLE_MDC:
761                         strcpy(macfb_fix.id, "Mac Disp. Card");
762                         macfb_setpalette = mdc_setpalette;
763                         macfb_defined.activate = FB_ACTIVATE_NOW;
764                         break;
765                 case NUBUS_DRHW_APPLE_TFB:
766                         strcpy(macfb_fix.id, "Toby");
767                         macfb_setpalette = toby_setpalette;
768                         macfb_defined.activate = FB_ACTIVATE_NOW;
769                         break;
770                 case NUBUS_DRHW_APPLE_JET:
771                         strcpy(macfb_fix.id, "Jet");
772                         macfb_setpalette = jet_setpalette;
773                         macfb_defined.activate = FB_ACTIVATE_NOW;
774                         break;                  
775                 default:
776                         strcpy(macfb_fix.id, "Generic NuBus");
777                         break;
778                 }
779         }
780
781         /* If it's not a NuBus card, it must be internal video */
782         /* FIXME: this function is getting way too big.  (this driver
783            is too...) */
784         if (!video_is_nubus)
785                 switch( mac_bi_data.id )
786                 {
787                         /* Valkyrie Quadras */
788                 case MAC_MODEL_Q630:
789                         /* I'm not sure about this one */
790                 case MAC_MODEL_P588:
791                         strcpy(macfb_fix.id, "Valkyrie");
792                         macfb_setpalette = valkyrie_setpalette;
793                         macfb_defined.activate = FB_ACTIVATE_NOW;
794                         valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
795                         break;
796
797                         /* DAFB Quadras */
798                         /* Note: these first four have the v7 DAFB, which is
799                            known to be rather unlike the ones used in the
800                            other models */
801                 case MAC_MODEL_P475:
802                 case MAC_MODEL_P475F:
803                 case MAC_MODEL_P575:
804                 case MAC_MODEL_Q605:
805         
806                 case MAC_MODEL_Q800:
807                 case MAC_MODEL_Q650:
808                 case MAC_MODEL_Q610:
809                 case MAC_MODEL_C650:
810                 case MAC_MODEL_C610:
811                 case MAC_MODEL_Q700:
812                 case MAC_MODEL_Q900:
813                 case MAC_MODEL_Q950:
814                         strcpy(macfb_fix.id, "DAFB");
815                         macfb_setpalette = dafb_setpalette;
816                         macfb_defined.activate = FB_ACTIVATE_NOW;
817                         dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
818                         break;
819
820                         /* LC II uses the V8 framebuffer */
821                 case MAC_MODEL_LCII:
822                         strcpy(macfb_fix.id, "V8");
823                         macfb_setpalette = v8_brazil_setpalette;
824                         macfb_defined.activate = FB_ACTIVATE_NOW;
825                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
826                         break;
827                 
828                         /* IIvi, IIvx use the "Brazil" framebuffer (which is
829                            very much like the V8, it seems, and probably uses
830                            the same DAC) */
831                 case MAC_MODEL_IIVI:
832                 case MAC_MODEL_IIVX:
833                 case MAC_MODEL_P600:
834                         strcpy(macfb_fix.id, "Brazil");
835                         macfb_setpalette = v8_brazil_setpalette;
836                         macfb_defined.activate = FB_ACTIVATE_NOW;
837                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
838                         break;
839                 
840                         /* LC III (and friends) use the Sonora framebuffer */
841                         /* Incidentally this is also used in the non-AV models
842                            of the x100 PowerMacs */
843                         /* These do in fact seem to use the same DAC interface
844                            as the LC II. */
845                 case MAC_MODEL_LCIII:
846                 case MAC_MODEL_P520:
847                 case MAC_MODEL_P550:
848                 case MAC_MODEL_P460:
849                         macfb_setpalette = v8_brazil_setpalette;
850                         macfb_defined.activate = FB_ACTIVATE_NOW;
851                         strcpy(macfb_fix.id, "Sonora");
852                         v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
853                         break;
854
855                         /* IIci and IIsi use the infamous RBV chip
856                            (the IIsi is just a rebadged and crippled
857                            IIci in a different case, BTW) */
858                 case MAC_MODEL_IICI:
859                 case MAC_MODEL_IISI:
860                         macfb_setpalette = rbv_setpalette;
861                         macfb_defined.activate = FB_ACTIVATE_NOW;
862                         strcpy(macfb_fix.id, "RBV");
863                         rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
864                         break;
865
866                         /* AVs use the Civic framebuffer */
867                 case MAC_MODEL_Q840:
868                 case MAC_MODEL_C660:
869                         macfb_setpalette = civic_setpalette;
870                         macfb_defined.activate = FB_ACTIVATE_NOW;
871                         strcpy(macfb_fix.id, "Civic");
872                         civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
873                         break;
874
875                 
876                         /* Write a setpalette function for your machine, then
877                            you can add something similar here.  These are
878                            grouped by classes of video chipsets.  Some of this
879                            information is from the VideoToolbox "Bugs" web
880                            page at
881                            http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
882
883                         /* Assorted weirdos */
884                         /* We think this may be like the LC II */
885                 case MAC_MODEL_LC:
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);
891                         }
892                         strcpy(macfb_fix.id, "LC");
893                         break;
894                         /* We think this may be like the LC II */
895                 case MAC_MODEL_CCL:
896                         if (vidtest) {
897                                 macfb_setpalette = v8_brazil_setpalette;
898                                 macfb_defined.activate = FB_ACTIVATE_NOW;
899                                 v8_brazil_cmap_regs =
900                                         ioremap(DAC_BASE, 0x1000);
901                         }
902                         strcpy(macfb_fix.id, "Color Classic");
903                         break;
904
905                         /* And we *do* mean "weirdos" */
906                 case MAC_MODEL_TV:
907                         strcpy(macfb_fix.id, "Mac TV");
908                         break;
909
910                         /* These don't have colour, so no need to worry */
911                 case MAC_MODEL_SE30:
912                 case MAC_MODEL_CLII:
913                         strcpy(macfb_fix.id, "Monochrome");
914                         break;
915
916                         /* Powerbooks are particularly difficult.  Many of
917                            them have separate framebuffers for external and
918                            internal video, which is admittedly pretty cool,
919                            but will be a bit of a headache to support here.
920                            Also, many of them are grayscale, and we don't
921                            really support that. */
922
923                 case MAC_MODEL_PB140:
924                 case MAC_MODEL_PB145:
925                 case MAC_MODEL_PB170:
926                         strcpy(macfb_fix.id, "DDC");
927                         break;
928
929                         /* Internal is GSC, External (if present) is ViSC */
930                 case MAC_MODEL_PB150:   /* no external video */
931                 case MAC_MODEL_PB160:
932                 case MAC_MODEL_PB165:
933                 case MAC_MODEL_PB180:
934                 case MAC_MODEL_PB210:
935                 case MAC_MODEL_PB230:
936                         strcpy(macfb_fix.id, "GSC");
937                         break;
938
939                         /* Internal is TIM, External is ViSC */
940                 case MAC_MODEL_PB165C:
941                 case MAC_MODEL_PB180C:
942                         strcpy(macfb_fix.id, "TIM");
943                         break;
944
945                         /* Internal is CSC, External is Keystone+Ariel. */
946                 case MAC_MODEL_PB190:   /* external video is optional */
947                 case MAC_MODEL_PB520:
948                 case MAC_MODEL_PB250:
949                 case MAC_MODEL_PB270C:
950                 case MAC_MODEL_PB280:
951                 case MAC_MODEL_PB280C:
952                         macfb_setpalette = csc_setpalette;
953                         macfb_defined.activate = FB_ACTIVATE_NOW;
954                         strcpy(macfb_fix.id, "CSC");
955                         csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
956                         break;
957                 
958                 default:
959                         strcpy(macfb_fix.id, "Unknown");
960                         break;
961                 }
962
963         fb_info.fbops           = &macfb_ops;
964         fb_info.var             = macfb_defined;
965         fb_info.fix             = macfb_fix;
966         fb_info.pseudo_palette  = pseudo_palette;
967         fb_info.flags           = FBINFO_DEFAULT;
968
969         err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
970         if (err)
971                 goto fail_unmap;
972         
973         err = register_framebuffer(&fb_info);
974         if (err)
975                 goto fail_dealloc;
976
977         printk("fb%d: %s frame buffer device\n",
978                fb_info.node, fb_info.fix.id);
979         return 0;
980
981 fail_dealloc:
982         fb_dealloc_cmap(&fb_info.cmap);
983 fail_unmap:
984         iounmap(fb_info.screen_base);
985         iounmap_macfb();
986         return err;
987 }
988
989 module_init(macfb_init);
990 MODULE_LICENSE("GPL");