macfb.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   don't know how to set */
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* (c) 1999 David Huggins-Daines <dhd@debian.org>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   Primarily based on vesafb.c, by Gerd Knorr
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   Also uses information and code from:
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   Mellinger, Mikael Forselius, Michael Schmitz, and others.
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   This code is free software.  You may copy, modify, and distribute
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   it subject to the terms and conditions of the GNU General Public
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   License, version 2, or any later version, at your convenience. */
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h>
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/tty.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/nubus.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fb.h>
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/setup.h>
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bootinfo.h>
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pgtable.h>
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/macintosh.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/machw.h>
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DAC_BASE 0x50f24000
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Some addresses for the DAFB */
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DAFB_BASE 0xf9800200
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Address for the built-in Civic framebuffer in Quadra AVs */
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CIVIC_BASE 0x50f30800	/* Only tested on 660AV! */
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* GSC (Gray Scale Controller) base address */
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define GSC_BASE 0x50F20000
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* CSC (Color Screen Controller) base address */
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSC_BASE 0x50F20000
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int (*macfb_setpalette) (unsigned int regno, unsigned int red,
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				unsigned int green, unsigned int blue,
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				struct fb_info *info) = NULL;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int valkyrie_setpalette (unsigned int regno, unsigned int red,
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				unsigned int green, unsigned int blue,
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				struct fb_info *info);
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dafb_setpalette (unsigned int regno, unsigned int red,
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    unsigned int green, unsigned int blue,
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    struct fb_info *fb_info);
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int rbv_setpalette (unsigned int regno, unsigned int red,
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *fb_info);
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mdc_setpalette (unsigned int regno, unsigned int red,
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *fb_info);
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int toby_setpalette (unsigned int regno, unsigned int red,
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    unsigned int green, unsigned int blue,
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    struct fb_info *fb_info);
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int civic_setpalette (unsigned int regno, unsigned int red,
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     unsigned int green, unsigned int blue,
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     struct fb_info *fb_info);
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int csc_setpalette (unsigned int regno, unsigned int red,
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *fb_info);
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic volatile struct {
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Note: word-aligned */
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad[3];
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} *valkyrie_cmap_regs;
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic volatile struct {
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} *v8_brazil_cmap_regs;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic volatile struct {
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[3]; /* word aligned */
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[3]; /* word aligned */
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char cntl; /* a guess as to purpose */
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} *rbv_cmap_regs;
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic volatile struct {
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long reset;
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long pad1[3];
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad2[3];
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} *dafb_cmap_regs;
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic volatile struct {
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;	/* OFFSET: 0x00 */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad1[15];
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;	/* OFFSET: 0x10 */
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad2[15];
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char status;	/* OFFSET: 0x20 */
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad3[7];
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long vbl_addr;	/* OFFSET: 0x28 */
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int  status2;	/* OFFSET: 0x2C */
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} *civic_cmap_regs;
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic volatile struct {
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char    pad1[0x40];
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        unsigned char	clut_waddr;	/* 0x40 */
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        char    pad2;
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        unsigned char	clut_data;	/* 0x42 */
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        char	pad3[0x3];
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        unsigned char	clut_raddr;	/* 0x46 */
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} *csc_cmap_regs;
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* We will leave these the way they are for the time being */
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mdc_cmap_regs {
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0x200200];
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[6];
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct toby_cmap_regs {
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0x90018];
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[3];
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct jet_cmap_regs {
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0xe0e000];
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PIXEL_TO_MM(a)	(((a)*10)/28)	/* width in mm at 72 dpi */
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* mode */
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int  video_slot = 0;
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_var_screeninfo macfb_defined = {
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.bits_per_pixel	= 8,
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.activate	= FB_ACTIVATE_NOW,
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.width		= -1,
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.height		= -1,
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.right_margin	= 32,
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.upper_margin	= 16,
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.lower_margin	= 4,
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.vsync_len	= 4,
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.vmode		= FB_VMODE_NONINTERLACED,
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_fix_screeninfo macfb_fix = {
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.id	= "Macintosh ",
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.type	= FB_TYPE_PACKED_PIXELS,
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.accel	= FB_ACCEL_NONE,
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_info fb_info;
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u32 pseudo_palette[17];
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int inverse   = 0;
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int vidtest   = 0;
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int valkyrie_setpalette (unsigned int regno, unsigned int red,
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				unsigned int green, unsigned int blue,
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				struct fb_info *info)
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	red >>= 8;
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	green >>= 8;
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	blue >>= 8;
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* tell clut which address to fill */
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(regno, &valkyrie_cmap_regs->addr);
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* send one color channel at a time */
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(red, &valkyrie_cmap_regs->lut);
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(green, &valkyrie_cmap_regs->lut);
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(blue, &valkyrie_cmap_regs->lut);
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Unlike the Valkyrie, the DAFB cannot set individual colormap
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   registers.  Therefore, we do what the MacOS driver does (no
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   kidding!) and simply set them one by one until we hit the one we
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   want. */
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dafb_setpalette (unsigned int regno, unsigned int red,
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    unsigned int green, unsigned int blue,
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    struct fb_info *info)
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* FIXME: really, really need to use ioremap() here,
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds           phys_to_virt() doesn't work anymore */
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static int lastreg = -1;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	red >>= 8;
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	green >>= 8;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	blue >>= 8;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* fbdev will set an entire colourmap, but X won't.  Hopefully
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   this should accommodate both of them */
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (regno != lastreg+1) {
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int i;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Stab in the dark trying to reset the CLUT pointer */
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writel(0, &dafb_cmap_regs->reset);
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nop();
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Loop until we get to the register we want */
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < regno; i++) {
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(red, &dafb_cmap_regs->lut);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(green, &dafb_cmap_regs->lut);
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(blue, &dafb_cmap_regs->lut);
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lastreg = regno;
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int v8_brazil_setpalette (unsigned int regno, unsigned int red,
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 unsigned int green, unsigned int blue,
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 struct fb_info *info)
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int bpp = info->var.bits_per_pixel;
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =red>>8;
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=green>>8;
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =blue>>8;
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno;
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bpp > 8) return 1; /* failsafe */
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* On these chips, the CLUT register numbers are spread out
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   across the register space.  Thus:
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   In 8bpp, all regnos are valid.
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  	_regno = (regno << (8 - bpp)) | (0xFF >> bpp);
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* send one color channel at a time */
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int rbv_setpalette (unsigned int regno, unsigned int red,
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *info)
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =red>>8;
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=green>>8;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =blue>>8;
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno;
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* From the VideoToolbox driver.  Seems to be saying that
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * regno #254 and #255 are the important ones for 1-bit color,
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * regno #252-255 are the important ones for 2-bit color, etc.
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	_regno = regno + (256-(1 << info->var.bits_per_pixel));
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* reset clut? (VideoToolbox sez "not necessary") */
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* tell clut which address to use. */
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* send one color channel at a time. */
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_red,   &rbv_cmap_regs->lut); nop();
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue,  &rbv_cmap_regs->lut);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags); /* done. */
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Macintosh Display Card (8x24) */
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mdc_setpalette(unsigned int regno, unsigned int red,
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  unsigned int green, unsigned int blue,
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  struct fb_info *info)
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile struct mdc_cmap_regs *cmap_regs =
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_slot_addr(video_slot);
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =red>>8;
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=green>>8;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =blue>>8;
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno=regno;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* the nop's are there to order writes. */
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_regno, &cmap_regs->addr); nop();
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_red, &cmap_regs->lut);    nop();
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_green, &cmap_regs->lut);  nop();
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &cmap_regs->lut);
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Toby frame buffer */
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int toby_setpalette(unsigned int regno, unsigned int red,
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *info)
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile struct toby_cmap_regs *cmap_regs =
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_slot_addr(video_slot);
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int bpp = info->var.bits_per_pixel;
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =~(red>>8);
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=~(green>>8);
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =~(blue>>8);
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_regno, &cmap_regs->addr); nop();
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_red, &cmap_regs->lut);    nop();
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_green, &cmap_regs->lut);  nop();
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &cmap_regs->lut);
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Jet frame buffer */
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int jet_setpalette(unsigned int regno, unsigned int red,
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  unsigned int green, unsigned int blue,
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  struct fb_info *info)
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile struct jet_cmap_regs *cmap_regs =
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_slot_addr(video_slot);
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red   = (red>>8);
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green = (green>>8);
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue  = (blue>>8);
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(regno, &cmap_regs->addr); nop();
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_red, &cmap_regs->lut); nop();
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_green, &cmap_regs->lut); nop();
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &cmap_regs->lut);
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Civic framebuffer -- Quadra AV built-in video.  A chip
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * called Sebastian holds the actual color palettes, and
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * apparently, there are two different banks of 512K RAM
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * which can act as separate framebuffers for doing video
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * input and viewing the screen at the same time!  The 840AV
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Can add another 1MB RAM to give the two framebuffers
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1MB RAM apiece.
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FIXME: this doesn't seem to work anymore.
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int civic_setpalette (unsigned int regno, unsigned int red,
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     unsigned int green, unsigned int blue,
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     struct fb_info *info)
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static int lastreg = -1;
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int clut_status;
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	red   >>= 8;
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	green >>= 8;
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	blue  >>= 8;
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Set the register address
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(regno, &civic_cmap_regs->addr); nop();
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Wait for VBL interrupt here;
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * They're usually not enabled from Penguin, so we won't check
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CIVIC_VBL_OFFSET	0x120
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* do interrupt setup stuff here? */
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*vbl = 0L; nop();	/* clear */
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*vbl = 1L; nop();	/* set */
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (*vbl != 0L)	/* wait for next vbl */
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			usleep(10);	/* needed? */
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* do interrupt shutdown stuff here? */
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Grab a status word and do some checking;
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Then finally write the clut!
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	clut_status =  nubus_readb(&civic_cmap_regs->status2);
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((clut_status & 0x0008) == 0)
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((clut_status & 0x000D) != 0)
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb(  red, &civic_cmap_regs->lut); nop();
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb(green, &civic_cmap_regs->lut); nop();
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb( blue, &civic_cmap_regs->lut); nop();
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb( 0x00, &civic_cmap_regs->lut); nop();
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned char junk;
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		junk = nubus_readb(&civic_cmap_regs->lut); nop();
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		junk = nubus_readb(&civic_cmap_regs->lut); nop();
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		junk = nubus_readb(&civic_cmap_regs->lut); nop();
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		junk = nubus_readb(&civic_cmap_regs->lut); nop();
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((clut_status & 0x000D) != 0)
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb(  red, &civic_cmap_regs->lut); nop();
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb(green, &civic_cmap_regs->lut); nop();
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb( blue, &civic_cmap_regs->lut); nop();
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writeb( junk, &civic_cmap_regs->lut); nop();
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lastreg = regno;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The CSC is the framebuffer on the PowerBook 190 series
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (and the 5300 too, but that's a PowerMac). This function
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * brought to you in part by the ECSC driver for MkLinux.
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int csc_setpalette (unsigned int regno, unsigned int red,
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *info)
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mdelay(1);
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	csc_cmap_regs->clut_waddr = regno;
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	csc_cmap_regs->clut_data = red;
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	csc_cmap_regs->clut_data = green;
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	csc_cmap_regs->clut_data = blue;
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned blue, unsigned transp,
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *fb_info)
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  Set a single color register. The values supplied are
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  already rounded down to the hardware's capabilities
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  (according to the entries in the `var' structure). Return
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  != 0 for invalid regno.
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (regno >= fb_info->cmap.len)
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (fb_info->var.bits_per_pixel) {
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 1:
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* We shouldn't get here */
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 2:
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 4:
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 8:
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (macfb_setpalette)
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette(regno, red, green, blue, fb_info);
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 16:
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (fb_info->var.red.offset == 10) {
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* 1:5:5:5 */
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			((u32*) (fb_info->pseudo_palette))[regno] =
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((red   & 0xf800) >>  1) |
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((green & 0xf800) >>  6) |
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((blue  & 0xf800) >> 11) |
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((transp != 0) << 15);
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* 0:5:6:5 */
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			((u32*) (fb_info->pseudo_palette))[regno] =
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((red   & 0xf800)      ) |
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((green & 0xfc00) >>  5) |
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((blue  & 0xf800) >> 11);
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* I'm pretty sure that one or the other of these
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   doesn't exist on 68k Macs */
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 24:
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		red   >>= 8;
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		green >>= 8;
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		blue  >>= 8;
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		((u32 *)(fb_info->pseudo_palette))[regno] =
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(red   << fb_info->var.red.offset)   |
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(green << fb_info->var.green.offset) |
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(blue  << fb_info->var.blue.offset);
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 32:
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		red   >>= 8;
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		green >>= 8;
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		blue  >>= 8;
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		((u32 *)(fb_info->pseudo_palette))[regno] =
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(red   << fb_info->var.red.offset)   |
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(green << fb_info->var.green.offset) |
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(blue  << fb_info->var.blue.offset);
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    }
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    return 0;
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_ops macfb_ops = {
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.owner		= THIS_MODULE,
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_setcolreg	= macfb_setcolreg,
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_fillrect	= cfb_fillrect,
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_copyarea	= cfb_copyarea,
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_imageblit	= cfb_imageblit,
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_cursor	= soft_cursor,
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init macfb_setup(char *options)
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *this_opt;
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!options || !*options)
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while ((this_opt = strsep(&options, ",")) != NULL) {
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!*this_opt) continue;
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (! strcmp(this_opt, "inverse"))
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			inverse=1;
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* This means "turn on experimental CLUT code" */
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else if (!strcmp(this_opt, "vidtest"))
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			vidtest=1;
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init macfb_init(void)
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int video_cmap_len, video_is_nubus = 0;
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct nubus_dev* ndev = NULL;
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *option = NULL;
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (fb_get_options("macfb", &option))
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENODEV;
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_setup(option);
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!MACH_IS_MAC)
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* There can only be one internal video controller anyway so
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   we're not too worried about this */
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.yres = mac_bi_data.dimensions >> 16;
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_fix.line_length = mac_bi_data.videorow;
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Note: physical address (since 2.1.127) */
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_fix.smem_start = mac_bi_data.videoaddr;
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* This is actually redundant with the initial mappings.
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   However, there are some non-obvious aspects to the way
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   those mappings are set up, so this is in fact the safest
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   way to ensure that this driver will work on every possible
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   Mac */
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("macfb: mode is %dx%dx%d, linelength=%d\n",
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Fill in the available video resolution
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.xres_virtual   = macfb_defined.xres;
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.yres_virtual   = macfb_defined.yres;
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("macfb: scrolling: redraw\n");
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.yres_virtual = macfb_defined.yres;
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* some dummy values for timing to make fbset happy */
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (macfb_defined.bits_per_pixel) {
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 1:
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* XXX: I think this will catch any program that tries
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   to do FBIO_PUTCMAP when the visual is monochrome */
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = macfb_defined.bits_per_pixel;
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = macfb_defined.bits_per_pixel;
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 0;
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_MONO01;
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 2:
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 4:
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 8:
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = macfb_defined.bits_per_pixel;
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = macfb_defined.bits_per_pixel;
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 1 << macfb_defined.bits_per_pixel;
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 16:
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.transp.offset = 15;
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.transp.length = 1;
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.offset = 10;
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = 5;
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.offset = 5;
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = 5;
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.offset = 0;
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = 5;
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("macfb: directcolor: "
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "size=1:5:5:5, shift=15:10:5:0\n");
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 16;
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Should actually be FB_VISUAL_DIRECTCOLOR, but this
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   works too */
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 24:
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 32:
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* XXX: have to test these... can any 68k Macs
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   actually do this on internal video? */
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.offset = 16;
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = 8;
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.offset = 8;
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = 8;
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.offset = 0;
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = 8;
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("macfb: truecolor: "
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "size=0:8:8:8, shift=0:16:8:0\n");
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 16;
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 0;
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_MONO01;
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Hardware dependent stuff */
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  We take a wild guess that if the video physical address is
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  in nubus slot space, that the nubus card is driving video.
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  Penguin really ought to tell us whether we are using internal
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  video or not.
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Hopefully we only find one of them.  Otherwise our NuBus
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds           code is really broken :-) */
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		!= NULL)
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		      && (mac_bi_data.videoaddr <
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_is_nubus = 1;
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* We should probably just use the slot address... */
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_slot = ndev->board->slot;
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch(ndev->dr_hw) {
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_MDC:
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Display Card" );
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = mdc_setpalette;
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_TFB:
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Toby" );
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = toby_setpalette;
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_JET:
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Jet");
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = jet_setpalette;
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Generic NuBus" );
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* If it's not a NuBus card, it must be internal video */
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* FIXME: this function is getting way too big.  (this driver
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds           is too...) */
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!video_is_nubus)
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch( mac_bi_data.id )
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* These don't have onboard video.  Eventually, we may
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   be able to write separate framebuffer drivers for
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   them (tobyfb.c, hiresfb.c, etc, etc) */
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_II:
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIX:
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IICX:
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIFX:
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Generic NuBus" );
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Valkyrie Quadras */
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q630:
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* I'm not sure about this one */
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P588:
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Valkyrie built-in" );
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = valkyrie_setpalette;
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* DAFB Quadras */
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Note: these first four have the v7 DAFB, which is
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   known to be rather unlike the ones used in the
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   other models */
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P475:
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P475F:
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P575:
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q605:
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q800:
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q650:
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q610:
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C650:
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C610:
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q700:
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q900:
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q950:
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "DAFB built-in" );
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = dafb_setpalette;
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* LC II uses the V8 framebuffer */
8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LCII:
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "V8 built-in" );
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* IIvi, IIvx use the "Brazil" framebuffer (which is
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   very much like the V8, it seems, and probably uses
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   the same DAC) */
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIVI:
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIVX:
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P600:
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Brazil built-in" );
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* LC III (and friends) use the Sonora framebuffer */
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Incidentally this is also used in the non-AV models
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   of the x100 PowerMacs */
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* These do in fact seem to use the same DAC interface
8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   as the LC II. */
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LCIII:
8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P520:
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P550:
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P460:
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Sonora built-in" );
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* IIci and IIsi use the infamous RBV chip
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                           (the IIsi is just a rebadged and crippled
8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                           IIci in a different case, BTW) */
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IICI:
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IISI:
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = rbv_setpalette;
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "RBV built-in" );
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* AVs use the Civic framebuffer */
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q840:
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C660:
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = civic_setpalette;
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Civic built-in" );
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Write a setpalette function for your machine, then
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   you can add something similar here.  These are
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   grouped by classes of video chipsets.  Some of this
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   information is from the VideoToolbox "Bugs" web
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   page at
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Assorted weirdos */
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* We think this may be like the LC II */
8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LC:
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (vidtest) {
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_setpalette = v8_brazil_setpalette;
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_defined.activate = FB_ACTIVATE_NOW;
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				v8_brazil_cmap_regs =
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					ioremap(DAC_BASE, 0x1000);
8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "LC built-in" );
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* We think this may be like the LC II */
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_CCL:
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (vidtest) {
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_setpalette = v8_brazil_setpalette;
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_defined.activate = FB_ACTIVATE_NOW;
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				v8_brazil_cmap_regs =
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					ioremap(DAC_BASE, 0x1000);
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Color Classic built-in" );
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* And we *do* mean "weirdos" */
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_TV:
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Mac TV built-in" );
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* These don't have colour, so no need to worry */
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_SE30:
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_CLII:
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Monochrome built-in" );
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Powerbooks are particularly difficult.  Many of
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   them have separate framebuffers for external and
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   internal video, which is admittedly pretty cool,
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   but will be a bit of a headache to support here.
9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   Also, many of them are grayscale, and we don't
9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   really support that. */
9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB140:
9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB145:
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB170:
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "DDC built-in" );
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Internal is GSC, External (if present) is ViSC */
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB150:	/* no external video */
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB160:
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB165:
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB180:
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB210:
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB230:
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "GSC built-in" );
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Internal is TIM, External is ViSC */
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB165C:
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB180C:
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "TIM built-in" );
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Internal is CSC, External is Keystone+Ariel. */
9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB190:	/* external video is optional */
9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB520:
9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB250:
9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB270C:
9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB280:
9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB280C:
9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = csc_setpalette;
9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "CSC built-in" );
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.fbops		= &macfb_ops;
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.var		= macfb_defined;
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.fix		= macfb_fix;
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.pseudo_palette	= pseudo_palette;
9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.flags		= FBINFO_DEFAULT;
9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (register_framebuffer(&fb_info) < 0)
9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("fb%d: %s frame buffer device\n",
9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       fb_info.node, fb_info.fix.id);
9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(macfb_init);
9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
971