macfb.c revision 34c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13
134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/*
234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * don't know how to set.
434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain *
534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * (c) 1999 David Huggins-Daines <dhd@debian.org>
634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain *
734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Primarily based on vesafb.c, by Gerd Knorr
834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain *
1034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Also uses information and code from:
1134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain *
1234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
1334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Mellinger, Mikael Forselius, Michael Schmitz, and others.
1434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain *
1534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
1634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
1734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain *
1834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * The VideoToolbox "Bugs" web page at
1934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * http://rajsky.psych.nyu.edu/Tips/VideoBugs.html
2034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain *
2134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * This code is free software.  You may copy, modify, and distribute
2234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * it subject to the terms and conditions of the GNU General Public
2334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * License, version 2, or any later version, at your convenience.
2434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain */
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/nubus.h>
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fb.h>
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/setup.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bootinfo.h>
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/macintosh.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DAC_BASE 0x50f24000
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Some addresses for the DAFB */
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DAFB_BASE 0xf9800200
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Address for the built-in Civic framebuffer in Quadra AVs */
4834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain#define CIVIC_BASE 0x50f30800
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* GSC (Gray Scale Controller) base address */
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define GSC_BASE 0x50F20000
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* CSC (Color Screen Controller) base address */
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSC_BASE 0x50F20000
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int (*macfb_setpalette)(unsigned int regno, unsigned int red,
5734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			       unsigned int green, unsigned int blue,
5834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			       struct fb_info *info);
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
603839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
633839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *v8_brazil_cmap_regs;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
653839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[3]; /* word aligned */
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[3]; /* word aligned */
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char cntl; /* a guess as to purpose */
713839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *rbv_cmap_regs;
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
733839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long reset;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long pad1[3];
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad2[3];
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
783839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *dafb_cmap_regs;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
803839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;	/* OFFSET: 0x00 */
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad1[15];
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;	/* OFFSET: 0x10 */
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad2[15];
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char status;	/* OFFSET: 0x20 */
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad3[7];
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long vbl_addr;	/* OFFSET: 0x28 */
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int  status2;	/* OFFSET: 0x2C */
893839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *civic_cmap_regs;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
913839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
9234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	char pad1[0x40];
9334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	unsigned char clut_waddr;	/* 0x40 */
9434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	char pad2;
9534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	unsigned char clut_data;	/* 0x42 */
9634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	char pad3[0x3];
9734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	unsigned char clut_raddr;	/* 0x46 */
983839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *csc_cmap_regs;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/* The registers in these structs are in NuBus slot space */
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mdc_cmap_regs {
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0x200200];
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[6];
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct toby_cmap_regs {
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0x90018];
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[3];
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct jet_cmap_regs {
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0xe0e000];
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain#define PIXEL_TO_MM(a)	(((a)*10)/28)	/* width in mm at 72 dpi */
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int  video_slot = 0;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_var_screeninfo macfb_defined = {
12634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	.bits_per_pixel	= 8,
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.activate	= FB_ACTIVATE_NOW,
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.width		= -1,
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.height		= -1,
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.right_margin	= 32,
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.upper_margin	= 16,
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.lower_margin	= 4,
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.vsync_len	= 4,
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.vmode		= FB_VMODE_NONINTERLACED,
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_fix_screeninfo macfb_fix = {
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.type	= FB_TYPE_PACKED_PIXELS,
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.accel	= FB_ACCEL_NONE,
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_info fb_info;
14324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplasstatic u32 pseudo_palette[16];
14434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int inverse;
14534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int vidtest;
14634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
14734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/*
14834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Unlike the Valkyrie, the DAFB cannot set individual colormap
14934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * registers.  Therefore, we do what the MacOS driver does (no
15034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * kidding!) and simply set them one by one until we hit the one we
15134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * want.
15234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain */
15334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int dafb_setpalette(unsigned int regno, unsigned int red,
15434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			   unsigned int green, unsigned int blue,
15534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			   struct fb_info *info)
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static int lastreg = -1;
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	red >>= 8;
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	green >>= 8;
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	blue >>= 8;
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
16534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
16634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/*
16734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * fbdev will set an entire colourmap, but X won't.  Hopefully
16834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * this should accommodate both of them
16934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 */
17034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (regno != lastreg + 1) {
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int i;
17234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Stab in the dark trying to reset the CLUT pointer */
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writel(0, &dafb_cmap_regs->reset);
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nop();
17634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Loop until we get to the register we want */
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < regno; i++) {
17934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(info->cmap.red[i] >> 8,
18034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     &dafb_cmap_regs->lut);
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
18234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(info->cmap.green[i] >> 8,
18334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     &dafb_cmap_regs->lut);
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
18534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(info->cmap.blue[i] >> 8,
18634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     &dafb_cmap_regs->lut);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
19034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(red, &dafb_cmap_regs->lut);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(green, &dafb_cmap_regs->lut);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(blue, &dafb_cmap_regs->lut);
19634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lastreg = regno;
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
20334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int v8_brazil_setpalette(unsigned int regno, unsigned int red,
20434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				unsigned int green, unsigned int blue,
20534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				struct fb_info *info)
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int bpp = info->var.bits_per_pixel;
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =red>>8;
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=green>>8;
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =blue>>8;
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno;
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (bpp > 8)
21534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		return 1; /* failsafe */
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* On these chips, the CLUT register numbers are spread out
22034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * across the register space.  Thus:
22134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * In 8bpp, all regnos are valid.
22234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
22334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff
22434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 */
22534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	_regno = (regno << (8 - bpp)) | (0xFF >> bpp);
22634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_regno, &v8_brazil_cmap_regs->addr);
22734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* send one color channel at a time */
23034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_red, &v8_brazil_cmap_regs->lut);
23134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
23234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_green, &v8_brazil_cmap_regs->lut);
23334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	local_irq_restore(flags);
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/* RAM-Based Video */
24134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int rbv_setpalette(unsigned int regno, unsigned int red,
24234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  unsigned int green, unsigned int blue,
24334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  struct fb_info *info)
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =red>>8;
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=green>>8;
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =blue>>8;
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno;
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (info->var.bits_per_pixel > 8)
25334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		return 1; /* failsafe */
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
25634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* From the VideoToolbox driver.  Seems to be saying that
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * regno #254 and #255 are the important ones for 1-bit color,
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * regno #252-255 are the important ones for 2-bit color, etc.
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	_regno = regno + (256-(1 << info->var.bits_per_pixel));
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* reset clut? (VideoToolbox sez "not necessary") */
26434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(0xFF, &rbv_cmap_regs->cntl);
26534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
26634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* tell clut which address to use. */
26834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_regno, &rbv_cmap_regs->addr);
26934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
27034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* send one color channel at a time. */
27234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_red, &rbv_cmap_regs->lut);
27334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
27434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_green, &rbv_cmap_regs->lut);
27534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
27634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_blue, &rbv_cmap_regs->lut);
27734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
27834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	local_irq_restore(flags);
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
28234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/* Macintosh Display Card (8*24) */
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mdc_setpalette(unsigned int regno, unsigned int red,
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  unsigned int green, unsigned int blue,
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  struct fb_info *info)
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile struct mdc_cmap_regs *cmap_regs =
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_slot_addr(video_slot);
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =red>>8;
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=green>>8;
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =blue>>8;
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno=regno;
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
29734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* the nop's are there to order writes. */
29934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_regno, &cmap_regs->addr);
30034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
30134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_red, &cmap_regs->lut);
30234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
30334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_green, &cmap_regs->lut);
30434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &cmap_regs->lut);
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Toby frame buffer */
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int toby_setpalette(unsigned int regno, unsigned int red,
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
31434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			   struct fb_info *info)
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile struct toby_cmap_regs *cmap_regs =
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_slot_addr(video_slot);
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int bpp = info->var.bits_per_pixel;
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red  =~(red>>8);
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green=~(green>>8);
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue =~(blue>>8);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
32734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
32834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_regno, &cmap_regs->addr);
32934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
33034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_red, &cmap_regs->lut);
33134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
33234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_green, &cmap_regs->lut);
33334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &cmap_regs->lut);
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Jet frame buffer */
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int jet_setpalette(unsigned int regno, unsigned int red,
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  unsigned int green, unsigned int blue,
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  struct fb_info *info)
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile struct jet_cmap_regs *cmap_regs =
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_slot_addr(video_slot);
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use MSBs */
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _red   = (red>>8);
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _green = (green>>8);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char _blue  = (blue>>8);
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
35434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
35534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(regno, &cmap_regs->addr);
35634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
35734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_red, &cmap_regs->lut);
35834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
35934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(_green, &cmap_regs->lut);
36034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(_blue, &cmap_regs->lut);
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Civic framebuffer -- Quadra AV built-in video.  A chip
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * called Sebastian holds the actual color palettes, and
37034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * apparently, there are two different banks of 512K RAM
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * which can act as separate framebuffers for doing video
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * input and viewing the screen at the same time!  The 840AV
37334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Can add another 1MB RAM to give the two framebuffers
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1MB RAM apiece.
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
37634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int civic_setpalette(unsigned int regno, unsigned int red,
37734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			    unsigned int green, unsigned int blue,
37834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			    struct fb_info *info)
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int clut_status;
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
38334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (info->var.bits_per_pixel > 8)
38434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		return 1; /* failsafe */
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	red   >>= 8;
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	green >>= 8;
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	blue  >>= 8;
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
39234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/* Set the register address */
39334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(regno, &civic_cmap_regs->addr);
39434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Grab a status word and do some checking;
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Then finally write the clut!
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	clut_status =  nubus_readb(&civic_cmap_regs->status2);
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((clut_status & 0x0008) == 0)
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((clut_status & 0x000D) != 0)
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
40734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
40834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
40934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
41034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(red, &civic_cmap_regs->lut);
41534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
41634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(green, &civic_cmap_regs->lut);
41734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
41834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(blue, &civic_cmap_regs->lut);
41934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
42034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(0x00, &civic_cmap_regs->lut);
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned char junk;
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
42734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
42834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
42934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
43034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
43134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
43234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
43334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((clut_status & 0x000D) != 0)
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
43734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
43834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
43934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
44034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
44334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(red, &civic_cmap_regs->lut);
44434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
44534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(green, &civic_cmap_regs->lut);
44634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
44734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(blue, &civic_cmap_regs->lut);
44834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
44934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(junk, &civic_cmap_regs->lut);
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The CSC is the framebuffer on the PowerBook 190 series
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (and the 5300 too, but that's a PowerMac). This function
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * brought to you in part by the ECSC driver for MkLinux.
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
46134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int csc_setpalette(unsigned int regno, unsigned int red,
46234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  unsigned int green, unsigned int blue,
46334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  struct fb_info *info)
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mdelay(1);
4663839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain	nubus_writeb(regno, &csc_cmap_regs->clut_waddr);
4673839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain	nubus_writeb(red,   &csc_cmap_regs->clut_data);
4683839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain	nubus_writeb(green, &csc_cmap_regs->clut_data);
4693839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain	nubus_writeb(blue,  &csc_cmap_regs->clut_data);
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned blue, unsigned transp,
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *fb_info)
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
47834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Set a single color register. The values supplied are
47934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * already rounded down to the hardware's capabilities
48034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * (according to the entries in the `var' structure).
48134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Return non-zero for invalid regno.
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (regno >= fb_info->cmap.len)
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
48724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	if (fb_info->var.bits_per_pixel <= 8) {
48824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		switch (fb_info->var.bits_per_pixel) {
48924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 1:
49024fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			/* We shouldn't get here */
49124fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
49224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 2:
49324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 4:
49424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 8:
49524fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			if (macfb_setpalette)
49624fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				macfb_setpalette(regno, red, green, blue,
49724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas						 fb_info);
49824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			else
49924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				return 1;
50024fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
50124fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		}
50224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	} else if (regno < 16) {
50324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		switch (fb_info->var.bits_per_pixel) {
50424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 16:
50524fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			if (fb_info->var.red.offset == 10) {
50624fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				/* 1:5:5:5 */
50724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				((u32*) (fb_info->pseudo_palette))[regno] =
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((red   & 0xf800) >>  1) |
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((green & 0xf800) >>  6) |
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((blue  & 0xf800) >> 11) |
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((transp != 0) << 15);
51224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			} else {
51324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				/* 0:5:6:5 */
51424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				((u32*) (fb_info->pseudo_palette))[regno] =
51534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain					((red   & 0xf800) >>  0) |
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((green & 0xfc00) >>  5) |
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((blue  & 0xf800) >> 11);
51824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			}
51924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
52034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
52134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * 24-bit colour almost doesn't exist on 68k Macs --
52234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * http://support.apple.com/kb/TA28634 (Old Article: 10992)
52334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
52424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 24:
52524fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 32:
52624fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			red   >>= 8;
52724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			green >>= 8;
52824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			blue  >>= 8;
52924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			((u32 *)(fb_info->pseudo_palette))[regno] =
53034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				(red   << fb_info->var.red.offset) |
53124fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				(green << fb_info->var.green.offset) |
53224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				(blue  << fb_info->var.blue.offset);
53324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
53524fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	}
53624fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas
53724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	return 0;
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_ops macfb_ops = {
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.owner		= THIS_MODULE,
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_setcolreg	= macfb_setcolreg,
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_fillrect	= cfb_fillrect,
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_copyarea	= cfb_copyarea,
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_imageblit	= cfb_imageblit,
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
548511e7483abe1ab433d8ab7a7998f799042b52941Adrian Bunkstatic void __init macfb_setup(char *options)
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *this_opt;
55134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!options || !*options)
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
55434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while ((this_opt = strsep(&options, ",")) != NULL) {
55634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		if (!*this_opt)
55734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			continue;
55834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
55934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		if (!strcmp(this_opt, "inverse"))
56034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			inverse = 1;
56134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		else
56234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			if (!strcmp(this_opt, "vidtest"))
56334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				vidtest = 1; /* enable experimental CLUT code */
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
567164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Ladstatic void __init iounmap_macfb(void)
568164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad{
569164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (dafb_cmap_regs)
570164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(dafb_cmap_regs);
571164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (v8_brazil_cmap_regs)
572164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(v8_brazil_cmap_regs);
573164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (rbv_cmap_regs)
574164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(rbv_cmap_regs);
575164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (civic_cmap_regs)
576164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(civic_cmap_regs);
577164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (csc_cmap_regs)
578164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(csc_cmap_regs);
579164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad}
580164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad
581ed1705afb93409a3e345d653be9d263984aa5c1bAl Virostatic int __init macfb_init(void)
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int video_cmap_len, video_is_nubus = 0;
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct nubus_dev* ndev = NULL;
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *option = NULL;
586ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro	int err;
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (fb_get_options("macfb", &option))
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENODEV;
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_setup(option);
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!MACH_IS_MAC)
593ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro		return -ENODEV;
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
59511e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain	if (mac_bi_data.id == MAC_MODEL_Q630 ||
59611e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain	    mac_bi_data.id == MAC_MODEL_P588)
59711e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain		return -ENODEV; /* See valkyriefb.c */
59811e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.yres = mac_bi_data.dimensions >> 16;
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
60234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_fix.line_length = mac_bi_data.videorow;
60434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_fix.smem_len    = macfb_fix.line_length * macfb_defined.yres;
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Note: physical address (since 2.1.127) */
60634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_fix.smem_start  = mac_bi_data.videoaddr;
60734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
60834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/*
60934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * This is actually redundant with the initial mappings.
61034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * However, there are some non-obvious aspects to the way
61134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * those mappings are set up, so this is in fact the safest
61234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * way to ensure that this driver will work on every possible Mac
61334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 */
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
61734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	       macfb_fix.smem_start, fb_info.screen_base,
61834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	       macfb_fix.smem_len / 1024);
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("macfb: mode is %dx%dx%d, linelength=%d\n",
62034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	       macfb_defined.xres, macfb_defined.yres,
62134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	       macfb_defined.bits_per_pixel, macfb_fix.line_length);
62234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
62434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Fill in the available video resolution
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
62634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.xres_virtual = macfb_defined.xres;
62734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.yres_virtual = macfb_defined.yres;
62834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.height       = PIXEL_TO_MM(macfb_defined.yres);
62934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.width        = PIXEL_TO_MM(macfb_defined.xres);
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("macfb: scrolling: redraw\n");
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* some dummy values for timing to make fbset happy */
63434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.pixclock     = 10000000 / macfb_defined.xres *
63534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     1000 / macfb_defined.yres;
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (macfb_defined.bits_per_pixel) {
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 1:
64134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
64234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * XXX: I think this will catch any program that tries
64334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * to do FBIO_PUTCMAP when the visual is monochrome.
64434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = macfb_defined.bits_per_pixel;
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = macfb_defined.bits_per_pixel;
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 0;
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_MONO01;
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 2:
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 4:
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 8:
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = macfb_defined.bits_per_pixel;
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = macfb_defined.bits_per_pixel;
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 1 << macfb_defined.bits_per_pixel;
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 16:
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.transp.offset = 15;
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.transp.length = 1;
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.offset = 10;
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = 5;
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.offset = 5;
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = 5;
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.offset = 0;
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = 5;
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("macfb: directcolor: "
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "size=1:5:5:5, shift=15:10:5:0\n");
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 16;
67234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
67334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Should actually be FB_VISUAL_DIRECTCOLOR, but this
67434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * works too
67534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 24:
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 32:
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.offset = 16;
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = 8;
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.offset = 8;
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = 8;
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.offset = 0;
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = 8;
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("macfb: truecolor: "
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "size=0:8:8:8, shift=0:16:8:0\n");
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 16;
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 0;
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_MONO01;
69334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		printk("macfb: unknown or unsupported bit depth: %d\n",
69434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		       macfb_defined.bits_per_pixel);
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
69834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/*
69934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * We take a wild guess that if the video physical address is
70034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * in nubus slot space, that the nubus card is driving video.
70134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Penguin really ought to tell us whether we are using internal
70234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * video or not.
70334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Hopefully we only find one of them.  Otherwise our NuBus
70434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * code is really broken :-)
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		!= NULL)
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		      && (mac_bi_data.videoaddr <
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_is_nubus = 1;
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* We should probably just use the slot address... */
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_slot = ndev->board->slot;
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch(ndev->dr_hw) {
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_MDC:
72089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Mac Disp. Card");
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = mdc_setpalette;
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_TFB:
72589c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Toby");
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = toby_setpalette;
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_JET:
73089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Jet");
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = jet_setpalette;
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
73334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			break;
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
73589c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Generic NuBus");
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* If it's not a NuBus card, it must be internal video */
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!video_is_nubus)
74234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		switch (mac_bi_data.id) {
74334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
74434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * DAFB Quadras
74534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Note: these first four have the v7 DAFB, which is
74634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * known to be rather unlike the ones used in the
74734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * other models
74834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P475:
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P475F:
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P575:
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q605:
75334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q800:
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q650:
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q610:
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C650:
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C610:
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q700:
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q900:
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q950:
76289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "DAFB");
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = dafb_setpalette;
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
76834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
76934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * LC II uses the V8 framebuffer
77034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LCII:
77289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "V8");
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
77734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
77834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
77934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * IIvi, IIvx use the "Brazil" framebuffer (which is
78034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * very much like the V8, it seems, and probably uses
78134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * the same DAC)
78234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIVI:
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIVX:
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P600:
78689c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Brazil");
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
79134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
79234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
79334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * LC III (and friends) use the Sonora framebuffer
79434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Incidentally this is also used in the non-AV models
79534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * of the x100 PowerMacs
79634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * These do in fact seem to use the same DAC interface
79734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * as the LC II.
79834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LCIII:
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P520:
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P550:
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P460:
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
80589c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Sonora");
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
80934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
81034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * IIci and IIsi use the infamous RBV chip
81134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * (the IIsi is just a rebadged and crippled
81234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * IIci in a different case, BTW)
81334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IICI:
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IISI:
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = rbv_setpalette;
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
81889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "RBV");
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
82234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
82334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * AVs use the Civic framebuffer
82434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q840:
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C660:
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = civic_setpalette;
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
82989c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Civic");
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
83434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
83534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Assorted weirdos
83634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * We think this may be like the LC II
83734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LC:
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (vidtest) {
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_setpalette = v8_brazil_setpalette;
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_defined.activate = FB_ACTIVATE_NOW;
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				v8_brazil_cmap_regs =
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					ioremap(DAC_BASE, 0x1000);
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
84589c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "LC");
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
84734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
84834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
84934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * We think this may be like the LC II
85034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_CCL:
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (vidtest) {
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_setpalette = v8_brazil_setpalette;
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_defined.activate = FB_ACTIVATE_NOW;
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				v8_brazil_cmap_regs =
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					ioremap(DAC_BASE, 0x1000);
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
85889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Color Classic");
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
86134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
86234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * And we *do* mean "weirdos"
86334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_TV:
86589c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Mac TV");
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
86834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
86934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * These don't have colour, so no need to worry
87034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_SE30:
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_CLII:
87389c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Monochrome");
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
87634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
87734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Powerbooks are particularly difficult.  Many of
87834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * them have separate framebuffers for external and
87934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * internal video, which is admittedly pretty cool,
88034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * but will be a bit of a headache to support here.
88134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Also, many of them are grayscale, and we don't
88234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * really support that.
88334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB140:
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB145:
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB170:
88889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "DDC");
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
89134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
89234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Internal is GSC, External (if present) is ViSC
89334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB150:	/* no external video */
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB160:
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB165:
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB180:
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB210:
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB230:
90089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "GSC");
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
90334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
90434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Internal is TIM, External is ViSC
90534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB165C:
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB180C:
90889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "TIM");
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
91134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
91234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Internal is CSC, External is Keystone+Ariel.
91334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB190:	/* external video is optional */
9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB520:
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB250:
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB270C:
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB280:
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB280C:
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = csc_setpalette;
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
92289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "CSC");
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
92534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
92789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Unknown");
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.fbops		= &macfb_ops;
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.var		= macfb_defined;
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.fix		= macfb_fix;
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.pseudo_palette	= pseudo_palette;
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.flags		= FBINFO_DEFAULT;
9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
93789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
93889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	if (err)
93989c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain		goto fail_unmap;
94034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
941ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro	err = register_framebuffer(&fb_info);
94289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	if (err)
94389c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain		goto fail_dealloc;
94489c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain
94589c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	printk("fb%d: %s frame buffer device\n",
94689c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	       fb_info.node, fb_info.fix.id);
94789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	return 0;
94889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain
94989c223a616cddd9eab792b860f61f99cec53c4e8Finn Thainfail_dealloc:
95089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	fb_dealloc_cmap(&fb_info.cmap);
95189c223a616cddd9eab792b860f61f99cec53c4e8Finn Thainfail_unmap:
95289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	iounmap(fb_info.screen_base);
95389c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	iounmap_macfb();
954ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro	return err;
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(macfb_init);
9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
959