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