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