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