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