blob: 180d94c2b4d232e21d02a5b6d90ff8825018da5a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* 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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#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
57static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
58 unsigned int green, unsigned int blue,
59 struct fb_info *info) = NULL;
60static int valkyrie_setpalette (unsigned int regno, unsigned int red,
61 unsigned int green, unsigned int blue,
62 struct fb_info *info);
63static int dafb_setpalette (unsigned int regno, unsigned int red,
64 unsigned int green, unsigned int blue,
65 struct fb_info *fb_info);
66static int rbv_setpalette (unsigned int regno, unsigned int red,
67 unsigned int green, unsigned int blue,
68 struct fb_info *fb_info);
69static int mdc_setpalette (unsigned int regno, unsigned int red,
70 unsigned int green, unsigned int blue,
71 struct fb_info *fb_info);
72static int toby_setpalette (unsigned int regno, unsigned int red,
73 unsigned int green, unsigned int blue,
74 struct fb_info *fb_info);
75static int civic_setpalette (unsigned int regno, unsigned int red,
76 unsigned int green, unsigned int blue,
77 struct fb_info *fb_info);
78static int csc_setpalette (unsigned int regno, unsigned int red,
79 unsigned int green, unsigned int blue,
80 struct fb_info *fb_info);
81
82static volatile struct {
83 unsigned char addr;
84 /* Note: word-aligned */
85 char pad[3];
86 unsigned char lut;
87} *valkyrie_cmap_regs;
88
89static volatile struct {
90 unsigned char addr;
91 unsigned char lut;
92} *v8_brazil_cmap_regs;
93
94static 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
102static 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
109static 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
120static 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 */
130struct mdc_cmap_regs {
131 char pad1[0x200200];
132 unsigned char addr;
133 char pad2[6];
134 unsigned char lut;
135};
136
137struct 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
144struct 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 */
153static int video_slot = 0;
154
155static 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
167static struct fb_fix_screeninfo macfb_fix = {
168 .id = "Macintosh ",
169 .type = FB_TYPE_PACKED_PIXELS,
170 .accel = FB_ACCEL_NONE,
171};
172
173static struct fb_info fb_info;
174static u32 pseudo_palette[17];
175static int inverse = 0;
176static int vidtest = 0;
177
178static 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. */
209static 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. */
256static 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
291static 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) */
328static 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 */
354static 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 */
380static 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 */
414static 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
507static 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
519static 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
585static 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,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591};
592
593void __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
Amol Lad164a7652006-12-08 02:40:09 -0800611static 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
Al Viroed1705a2006-01-12 01:06:39 -0800627static int __init macfb_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628{
629 int video_cmap_len, video_is_nubus = 0;
630 struct nubus_dev* ndev = NULL;
631 char *option = NULL;
Al Viroed1705a2006-01-12 01:06:39 -0800632 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
634 if (fb_get_options("macfb", &option))
635 return -ENODEV;
636 macfb_setup(option);
637
638 if (!MACH_IS_MAC)
Al Viroed1705a2006-01-12 01:06:39 -0800639 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640
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
Al Viroed1705a2006-01-12 01:06:39 -0800977 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);
Amol Lad164a7652006-12-08 02:40:09 -0800981 else {
982 iounmap(fb_info.screen_base);
983 iounmap_macfb();
984 }
Al Viroed1705a2006-01-12 01:06:39 -0800985 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986}
987
988module_init(macfb_init);
989MODULE_LICENSE("GPL");