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/macintosh.h>
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DAC_BASE 0x50f24000
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Some addresses for the DAFB */
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DAFB_BASE 0xf9800200
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Address for the built-in Civic framebuffer in Quadra AVs */
4734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain#define CIVIC_BASE 0x50f30800
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* GSC (Gray Scale Controller) base address */
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define GSC_BASE 0x50F20000
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* CSC (Color Screen Controller) base address */
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSC_BASE 0x50F20000
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int (*macfb_setpalette)(unsigned int regno, unsigned int red,
5634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			       unsigned int green, unsigned int blue,
5734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			       struct fb_info *info);
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
593839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
623839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *v8_brazil_cmap_regs;
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
643839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[3]; /* word aligned */
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[3]; /* word aligned */
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char cntl; /* a guess as to purpose */
703839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *rbv_cmap_regs;
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
723839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long reset;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long pad1[3];
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad2[3];
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
773839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *dafb_cmap_regs;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
793839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;	/* OFFSET: 0x00 */
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad1[15];
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;	/* OFFSET: 0x10 */
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad2[15];
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char status;	/* OFFSET: 0x20 */
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char pad3[7];
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long vbl_addr;	/* OFFSET: 0x28 */
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int  status2;	/* OFFSET: 0x2C */
883839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *civic_cmap_regs;
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
903839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thainstatic struct {
9134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	char pad1[0x40];
9234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	unsigned char clut_waddr;	/* 0x40 */
9334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	char pad2;
9434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	unsigned char clut_data;	/* 0x42 */
9534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	char pad3[0x3];
9634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	unsigned char clut_raddr;	/* 0x46 */
973839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain} __iomem *csc_cmap_regs;
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/* The registers in these structs are in NuBus slot space */
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mdc_cmap_regs {
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0x200200];
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[6];
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct toby_cmap_regs {
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0x90018];
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad2[3];
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct jet_cmap_regs {
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char pad1[0xe0e000];
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char addr;
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char lut;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain#define PIXEL_TO_MM(a)	(((a)*10)/28)	/* width in mm at 72 dpi */
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_var_screeninfo macfb_defined = {
12334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	.bits_per_pixel	= 8,
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.activate	= FB_ACTIVATE_NOW,
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.width		= -1,
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.height		= -1,
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.right_margin	= 32,
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.upper_margin	= 16,
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.lower_margin	= 4,
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.vsync_len	= 4,
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.vmode		= FB_VMODE_NONINTERLACED,
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_fix_screeninfo macfb_fix = {
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.type	= FB_TYPE_PACKED_PIXELS,
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.accel	= FB_ACCEL_NONE,
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13999e11ab20b26b3236490ae687ab309c2601d180bFinn Thainstatic void *slot_addr;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_info fb_info;
14124fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplasstatic u32 pseudo_palette[16];
14234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int inverse;
14334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int vidtest;
14434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
14534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/*
14634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Unlike the Valkyrie, the DAFB cannot set individual colormap
14734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * registers.  Therefore, we do what the MacOS driver does (no
14834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * kidding!) and simply set them one by one until we hit the one we
14934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * want.
15034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain */
15134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int dafb_setpalette(unsigned int regno, unsigned int red,
15234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			   unsigned int green, unsigned int blue,
15334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			   struct fb_info *info)
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static int lastreg = -1;
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
15934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
16034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/*
16134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * fbdev will set an entire colourmap, but X won't.  Hopefully
16234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * this should accommodate both of them
16334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 */
16434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (regno != lastreg + 1) {
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int i;
16634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Stab in the dark trying to reset the CLUT pointer */
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nubus_writel(0, &dafb_cmap_regs->reset);
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nop();
17034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Loop until we get to the register we want */
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < regno; i++) {
17334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(info->cmap.red[i] >> 8,
17434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     &dafb_cmap_regs->lut);
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
17634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(info->cmap.green[i] >> 8,
17734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     &dafb_cmap_regs->lut);
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
17934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(info->cmap.blue[i] >> 8,
18034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     &dafb_cmap_regs->lut);
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nop();
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(red, &dafb_cmap_regs->lut);
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(green, &dafb_cmap_regs->lut);
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nop();
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nubus_writeb(blue, &dafb_cmap_regs->lut);
19034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lastreg = regno;
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
19734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int v8_brazil_setpalette(unsigned int regno, unsigned int red,
19834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				unsigned int green, unsigned int blue,
19934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				struct fb_info *info)
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int bpp = info->var.bits_per_pixel;
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (bpp > 8)
20534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		return 1; /* failsafe */
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* On these chips, the CLUT register numbers are spread out
21034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * across the register space.  Thus:
21134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * In 8bpp, all regnos are valid.
21234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
21334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff
21434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 */
21599e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	regno = (regno << (8 - bpp)) | (0xFF >> bpp);
21699e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(regno, &v8_brazil_cmap_regs->addr);
21734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* send one color channel at a time */
22099e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(red, &v8_brazil_cmap_regs->lut);
22134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
22299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(green, &v8_brazil_cmap_regs->lut);
22334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
22499e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(blue, &v8_brazil_cmap_regs->lut);
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	local_irq_restore(flags);
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/* RAM-Based Video */
23134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int rbv_setpalette(unsigned int regno, unsigned int red,
23234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  unsigned int green, unsigned int blue,
23334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  struct fb_info *info)
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (info->var.bits_per_pixel > 8)
23834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		return 1; /* failsafe */
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
24134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* From the VideoToolbox driver.  Seems to be saying that
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * regno #254 and #255 are the important ones for 1-bit color,
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * regno #252-255 are the important ones for 2-bit color, etc.
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
24699e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	regno += 256 - (1 << info->var.bits_per_pixel);
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* reset clut? (VideoToolbox sez "not necessary") */
24934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(0xFF, &rbv_cmap_regs->cntl);
25034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
25134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* tell clut which address to use. */
25399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(regno, &rbv_cmap_regs->addr);
25434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
25534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* send one color channel at a time. */
25799e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(red, &rbv_cmap_regs->lut);
25834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
25999e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(green, &rbv_cmap_regs->lut);
26034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
26199e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(blue, &rbv_cmap_regs->lut);
26234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
26334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	local_irq_restore(flags);
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain/* Macintosh Display Card (8*24) */
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mdc_setpalette(unsigned int regno, unsigned int red,
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  unsigned int green, unsigned int blue,
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  struct fb_info *info)
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
27299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	struct mdc_cmap_regs *cmap_regs = slot_addr;
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
27634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* the nop's are there to order writes. */
27899e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(regno, &cmap_regs->addr);
27934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
28099e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(red, &cmap_regs->lut);
28134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
28299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(green, &cmap_regs->lut);
28334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
28499e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(blue, &cmap_regs->lut);
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Toby frame buffer */
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int toby_setpalette(unsigned int regno, unsigned int red,
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned int green, unsigned int blue,
29334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			   struct fb_info *info)
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
29599e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	struct toby_cmap_regs *cmap_regs = slot_addr;
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int bpp = info->var.bits_per_pixel;
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
29999e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	red = ~red;
30099e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	green = ~green;
30199e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	blue = ~blue;
30299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	regno = (regno << (8 - bpp)) | (0xFF >> bpp);
30399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
30534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
30699e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(regno, &cmap_regs->addr);
30734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
30899e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(red, &cmap_regs->lut);
30934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
31099e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(green, &cmap_regs->lut);
31134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
31299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(blue, &cmap_regs->lut);
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Jet frame buffer */
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int jet_setpalette(unsigned int regno, unsigned int red,
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  unsigned int green, unsigned int blue,
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  struct fb_info *info)
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
32399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	struct jet_cmap_regs *cmap_regs = slot_addr;
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();
33099e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(red, &cmap_regs->lut);
33134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
33299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(green, &cmap_regs->lut);
33334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
33499e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(blue, &cmap_regs->lut);
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Civic framebuffer -- Quadra AV built-in video.  A chip
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * called Sebastian holds the actual color palettes, and
34334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * apparently, there are two different banks of 512K RAM
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * which can act as separate framebuffers for doing video
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * input and viewing the screen at the same time!  The 840AV
34634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain * Can add another 1MB RAM to give the two framebuffers
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1MB RAM apiece.
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
34934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int civic_setpalette(unsigned int regno, unsigned int red,
35034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			    unsigned int green, unsigned int blue,
35134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			    struct fb_info *info)
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int clut_status;
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	if (info->var.bits_per_pixel > 8)
35734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		return 1; /* failsafe */
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
36134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/* Set the register address */
36234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nubus_writeb(regno, &civic_cmap_regs->addr);
36334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	nop();
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Grab a status word and do some checking;
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Then finally write the clut!
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	clut_status =  nubus_readb(&civic_cmap_regs->status2);
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((clut_status & 0x0008) == 0)
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((clut_status & 0x000D) != 0)
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
37634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
37734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
37834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
37934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
38334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(red, &civic_cmap_regs->lut);
38434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
38534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(green, &civic_cmap_regs->lut);
38634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
38734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(blue, &civic_cmap_regs->lut);
38834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
38934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(0x00, &civic_cmap_regs->lut);
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned char junk;
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
39534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
39634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
39734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
39834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
39934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
40034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
40134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		junk = nubus_readb(&civic_cmap_regs->lut);
40234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((clut_status & 0x000D) != 0)
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{
40634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
40734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
40834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nubus_writeb(0x00, &civic_cmap_regs->lut);
40934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			nop();
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(red, &civic_cmap_regs->lut);
41334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
41434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(green, &civic_cmap_regs->lut);
41534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
41634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(blue, &civic_cmap_regs->lut);
41734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nop();
41834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		nubus_writeb(junk, &civic_cmap_regs->lut);
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The CSC is the framebuffer on the PowerBook 190 series
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (and the 5300 too, but that's a PowerMac). This function
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * brought to you in part by the ECSC driver for MkLinux.
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
43034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thainstatic int csc_setpalette(unsigned int regno, unsigned int red,
43134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  unsigned int green, unsigned int blue,
43234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			  struct fb_info *info)
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
43499e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	unsigned long flags;
43599e11ab20b26b3236490ae687ab309c2601d180bFinn Thain
43699e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	local_irq_save(flags);
43799e11ab20b26b3236490ae687ab309c2601d180bFinn Thain
43899e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	udelay(1); /* mklinux on PB 5300 waits for 260 ns */
4393839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain	nubus_writeb(regno, &csc_cmap_regs->clut_waddr);
44099e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(red, &csc_cmap_regs->clut_data);
4413839d01d61195d76d53943ac36b603d7e7ca4b6eFinn Thain	nubus_writeb(green, &csc_cmap_regs->clut_data);
44299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	nubus_writeb(blue, &csc_cmap_regs->clut_data);
44399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain
44499e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	local_irq_restore(flags);
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   unsigned blue, unsigned transp,
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct fb_info *fb_info)
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
45334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Set a single color register. The values supplied are
45434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * already rounded down to the hardware's capabilities
45534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * (according to the entries in the `var' structure).
45634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Return non-zero for invalid regno.
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (regno >= fb_info->cmap.len)
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
46224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	if (fb_info->var.bits_per_pixel <= 8) {
46324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		switch (fb_info->var.bits_per_pixel) {
46424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 1:
46524fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			/* We shouldn't get here */
46624fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
46724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 2:
46824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 4:
46924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 8:
47024fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			if (macfb_setpalette)
47199e11ab20b26b3236490ae687ab309c2601d180bFinn Thain				macfb_setpalette(regno, red >> 8, green >> 8,
47299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain						 blue >> 8, fb_info);
47324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			else
47424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				return 1;
47524fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
47624fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		}
47724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	} else if (regno < 16) {
47824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		switch (fb_info->var.bits_per_pixel) {
47924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 16:
48024fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			if (fb_info->var.red.offset == 10) {
48124fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				/* 1:5:5:5 */
48224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				((u32*) (fb_info->pseudo_palette))[regno] =
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((red   & 0xf800) >>  1) |
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((green & 0xf800) >>  6) |
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((blue  & 0xf800) >> 11) |
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((transp != 0) << 15);
48724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			} else {
48824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				/* 0:5:6:5 */
48924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				((u32*) (fb_info->pseudo_palette))[regno] =
49034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain					((red   & 0xf800) >>  0) |
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((green & 0xfc00) >>  5) |
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					((blue  & 0xf800) >> 11);
49324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			}
49424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
49534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
49634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * 24-bit colour almost doesn't exist on 68k Macs --
49734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * http://support.apple.com/kb/TA28634 (Old Article: 10992)
49834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
49924fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 24:
50024fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas		case 32:
50124fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			red   >>= 8;
50224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			green >>= 8;
50324fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			blue  >>= 8;
50424fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			((u32 *)(fb_info->pseudo_palette))[regno] =
50534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				(red   << fb_info->var.red.offset) |
50624fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				(green << fb_info->var.green.offset) |
50724fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas				(blue  << fb_info->var.blue.offset);
50824fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas			break;
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
51024fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	}
51124fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas
51224fc72239ab5a2d26ebdd4f6950539e6120d1a54Antonino A. Daplas	return 0;
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_ops macfb_ops = {
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.owner		= THIS_MODULE,
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_setcolreg	= macfb_setcolreg,
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_fillrect	= cfb_fillrect,
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_copyarea	= cfb_copyarea,
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.fb_imageblit	= cfb_imageblit,
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
523511e7483abe1ab433d8ab7a7998f799042b52941Adrian Bunkstatic void __init macfb_setup(char *options)
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *this_opt;
52634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!options || !*options)
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
52934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while ((this_opt = strsep(&options, ",")) != NULL) {
53134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		if (!*this_opt)
53234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			continue;
53334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
53434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		if (!strcmp(this_opt, "inverse"))
53534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			inverse = 1;
53634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		else
53734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			if (!strcmp(this_opt, "vidtest"))
53834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				vidtest = 1; /* enable experimental CLUT code */
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
542164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Ladstatic void __init iounmap_macfb(void)
543164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad{
544164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (dafb_cmap_regs)
545164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(dafb_cmap_regs);
546164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (v8_brazil_cmap_regs)
547164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(v8_brazil_cmap_regs);
548164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (rbv_cmap_regs)
549164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(rbv_cmap_regs);
550164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (civic_cmap_regs)
551164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(civic_cmap_regs);
552164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad	if (csc_cmap_regs)
553164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad		iounmap(csc_cmap_regs);
554164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad}
555164a765b9895f4f80f91cb7f1aab7539b3f8d335Amol Lad
556ed1705afb93409a3e345d653be9d263984aa5c1bAl Virostatic int __init macfb_init(void)
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int video_cmap_len, video_is_nubus = 0;
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct nubus_dev* ndev = NULL;
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *option = NULL;
561ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro	int err;
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (fb_get_options("macfb", &option))
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENODEV;
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_setup(option);
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!MACH_IS_MAC)
568ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro		return -ENODEV;
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
57011e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain	if (mac_bi_data.id == MAC_MODEL_Q630 ||
57111e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain	    mac_bi_data.id == MAC_MODEL_P588)
57211e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain		return -ENODEV; /* See valkyriefb.c */
57311e8faca2e501c25d2f98c1b9534776a9a9704c5Finn Thain
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.yres = mac_bi_data.dimensions >> 16;
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
57734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_fix.line_length = mac_bi_data.videorow;
57934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_fix.smem_len    = macfb_fix.line_length * macfb_defined.yres;
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Note: physical address (since 2.1.127) */
58134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_fix.smem_start  = mac_bi_data.videoaddr;
58234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
58334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/*
58434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * This is actually redundant with the initial mappings.
58534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * However, there are some non-obvious aspects to the way
58634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * those mappings are set up, so this is in fact the safest
58734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * way to ensure that this driver will work on every possible Mac
58834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 */
58999e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	fb_info.screen_base = ioremap(mac_bi_data.videoaddr,
59099e11ab20b26b3236490ae687ab309c2601d180bFinn Thain				      macfb_fix.smem_len);
59199e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	if (!fb_info.screen_base)
59299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		return -ENODEV;
59399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain
594d9070fc4997e255532f0519709c9326d043501b2Finn Thain	pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
595d9070fc4997e255532f0519709c9326d043501b2Finn Thain	        macfb_fix.smem_start, fb_info.screen_base,
596d9070fc4997e255532f0519709c9326d043501b2Finn Thain	        macfb_fix.smem_len / 1024);
597d9070fc4997e255532f0519709c9326d043501b2Finn Thain	pr_info("macfb: mode is %dx%dx%d, linelength=%d\n",
598d9070fc4997e255532f0519709c9326d043501b2Finn Thain	        macfb_defined.xres, macfb_defined.yres,
599d9070fc4997e255532f0519709c9326d043501b2Finn Thain	        macfb_defined.bits_per_pixel, macfb_fix.line_length);
60034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
60199e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	/* Fill in the available video resolution */
60234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.xres_virtual = macfb_defined.xres;
60334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.yres_virtual = macfb_defined.yres;
60434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.height       = PIXEL_TO_MM(macfb_defined.yres);
60534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.width        = PIXEL_TO_MM(macfb_defined.xres);
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
60799e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	/* Some dummy values for timing to make fbset happy */
60834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	macfb_defined.pixclock     = 10000000 / macfb_defined.xres *
60934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain				     1000 / macfb_defined.yres;
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (macfb_defined.bits_per_pixel) {
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 1:
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = macfb_defined.bits_per_pixel;
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = macfb_defined.bits_per_pixel;
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
618d9070fc4997e255532f0519709c9326d043501b2Finn Thain		video_cmap_len = 2;
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_MONO01;
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 2:
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 4:
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 8:
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = macfb_defined.bits_per_pixel;
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = macfb_defined.bits_per_pixel;
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 1 << macfb_defined.bits_per_pixel;
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 16:
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.transp.offset = 15;
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.transp.length = 1;
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.offset = 10;
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = 5;
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.offset = 5;
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = 5;
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.offset = 0;
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = 5;
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 16;
64034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
64134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Should actually be FB_VISUAL_DIRECTCOLOR, but this
64234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * works too
64334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 24:
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 32:
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.offset = 16;
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.red.length = 8;
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.offset = 8;
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.green.length = 8;
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.offset = 0;
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_defined.blue.length = 8;
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_cmap_len = 16;
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
65699e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		break;
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
658d9070fc4997e255532f0519709c9326d043501b2Finn Thain		pr_err("macfb: unknown or unsupported bit depth: %d\n",
65934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		       macfb_defined.bits_per_pixel);
660d9070fc4997e255532f0519709c9326d043501b2Finn Thain		err = -EINVAL;
661d9070fc4997e255532f0519709c9326d043501b2Finn Thain		goto fail_unmap;
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
66434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	/*
66534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * We take a wild guess that if the video physical address is
66634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * in nubus slot space, that the nubus card is driving video.
66734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Penguin really ought to tell us whether we are using internal
66834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * video or not.
66934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * Hopefully we only find one of them.  Otherwise our NuBus
67034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain	 * code is really broken :-)
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
67399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain	while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY,
67499e11ab20b26b3236490ae687ab309c2601d180bFinn Thain				       NUBUS_TYPE_VIDEO, ndev)))
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
67699e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		unsigned long base = ndev->board->slot_addr;
67799e11ab20b26b3236490ae687ab309c2601d180bFinn Thain
67899e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		if (mac_bi_data.videoaddr < base ||
67999e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		    mac_bi_data.videoaddr - base > 0xFFFFFF)
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
68199e11ab20b26b3236490ae687ab309c2601d180bFinn Thain
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		video_is_nubus = 1;
68399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		slot_addr = (unsigned char *)base;
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch(ndev->dr_hw) {
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_MDC:
68789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Mac Disp. Card");
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = mdc_setpalette;
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_TFB:
69289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Toby");
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = toby_setpalette;
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case NUBUS_DRHW_APPLE_JET:
69789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Jet");
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = jet_setpalette;
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_defined.activate = FB_ACTIVATE_NOW;
70034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain			break;
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
70289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Generic NuBus");
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* If it's not a NuBus card, it must be internal video */
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!video_is_nubus)
70934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		switch (mac_bi_data.id) {
71034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
71134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * DAFB Quadras
71234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Note: these first four have the v7 DAFB, which is
71334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * known to be rather unlike the ones used in the
71434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * other models
71534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P475:
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P475F:
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P575:
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q605:
72034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q800:
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q650:
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q610:
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C650:
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C610:
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q700:
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q900:
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q950:
72989c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "DAFB");
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = dafb_setpalette;
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
732d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_defined.activate = FB_ACTIVATE_NOW;
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
73534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
73634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * LC II uses the V8 framebuffer
73734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LCII:
73989c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "V8");
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
742d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_defined.activate = FB_ACTIVATE_NOW;
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
74434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
74534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
74634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * IIvi, IIvx use the "Brazil" framebuffer (which is
74734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * very much like the V8, it seems, and probably uses
74834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * the same DAC)
74934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIVI:
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IIVX:
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P600:
75389c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Brazil");
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			macfb_setpalette = v8_brazil_setpalette;
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
756d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_defined.activate = FB_ACTIVATE_NOW;
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
75834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
75934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
76034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * LC III (and friends) use the Sonora framebuffer
76134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Incidentally this is also used in the non-AV models
76234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * of the x100 PowerMacs
76334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * These do in fact seem to use the same DAC interface
76434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * as the LC II.
76534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LCIII:
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P520:
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P550:
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_P460:
77089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Sonora");
771d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_setpalette = v8_brazil_setpalette;
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
773d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_defined.activate = FB_ACTIVATE_NOW;
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
77634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
77734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * IIci and IIsi use the infamous RBV chip
77834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * (the IIsi is just a rebadged and crippled
77934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * IIci in a different case, BTW)
78034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IICI:
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_IISI:
78389c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "RBV");
784d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_setpalette = rbv_setpalette;
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
786d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_defined.activate = FB_ACTIVATE_NOW;
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
78934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
79034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * AVs use the Civic framebuffer
79134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_Q840:
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_C660:
79489c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Civic");
795d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_setpalette = civic_setpalette;
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
797d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_defined.activate = FB_ACTIVATE_NOW;
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
80134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
80234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Assorted weirdos
80334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * We think this may be like the LC II
80434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_LC:
806d9070fc4997e255532f0519709c9326d043501b2Finn Thain			strcpy(macfb_fix.id, "LC");
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (vidtest) {
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_setpalette = v8_brazil_setpalette;
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				v8_brazil_cmap_regs =
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					ioremap(DAC_BASE, 0x1000);
811d9070fc4997e255532f0519709c9326d043501b2Finn Thain				macfb_defined.activate = FB_ACTIVATE_NOW;
8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
81434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
81534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
81634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * We think this may be like the LC II
81734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_CCL:
819d9070fc4997e255532f0519709c9326d043501b2Finn Thain			strcpy(macfb_fix.id, "Color Classic");
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (vidtest) {
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				macfb_setpalette = v8_brazil_setpalette;
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				v8_brazil_cmap_regs =
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					ioremap(DAC_BASE, 0x1000);
824d9070fc4997e255532f0519709c9326d043501b2Finn Thain				macfb_defined.activate = FB_ACTIVATE_NOW;
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
82834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
82934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * And we *do* mean "weirdos"
83034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_TV:
83289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Mac TV");
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
83534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
83634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * These don't have colour, so no need to worry
83734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_SE30:
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_CLII:
84089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Monochrome");
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
84334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
84434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Powerbooks are particularly difficult.  Many of
84534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * them have separate framebuffers for external and
84634c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * internal video, which is admittedly pretty cool,
84734c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * but will be a bit of a headache to support here.
84834c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Also, many of them are grayscale, and we don't
84934c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * really support that.
85034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
85299e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		/*
85399e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		 * Slot 0 ROM says TIM. No external video. B&W.
85499e11ab20b26b3236490ae687ab309c2601d180bFinn Thain		 */
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB140:
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB145:
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB170:
85889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "DDC");
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
86134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
86234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Internal is GSC, External (if present) is ViSC
86334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB150:	/* no external video */
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB160:
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB165:
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB180:
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB210:
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB230:
87089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "GSC");
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
87334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
87434c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Internal is TIM, External is ViSC
87534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB165C:
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB180C:
87889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "TIM");
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
88134c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		/*
88234c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 * Internal is CSC, External is Keystone+Ariel.
88334c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain		 */
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB190:	/* external video is optional */
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB520:
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB250:
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB270C:
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB280:
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case MAC_MODEL_PB280C:
89089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "CSC");
891d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_setpalette = csc_setpalette;
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
893d9070fc4997e255532f0519709c9326d043501b2Finn Thain			macfb_defined.activate = FB_ACTIVATE_NOW;
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
89534c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
89789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain			strcpy(macfb_fix.id, "Unknown");
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.fbops		= &macfb_ops;
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.var		= macfb_defined;
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.fix		= macfb_fix;
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.pseudo_palette	= pseudo_palette;
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fb_info.flags		= FBINFO_DEFAULT;
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
90789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
90889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	if (err)
90989c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain		goto fail_unmap;
91034c41d0ab8c2a96bb3db89a209c1dd7e8c44fe13Finn Thain
911ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro	err = register_framebuffer(&fb_info);
91289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	if (err)
91389c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain		goto fail_dealloc;
91489c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain
91531b6780c15a4e3a90fe260e977f5186772ce7afbJoe Perches	fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);
916d9070fc4997e255532f0519709c9326d043501b2Finn Thain
91789c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	return 0;
91889c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain
91989c223a616cddd9eab792b860f61f99cec53c4e8Finn Thainfail_dealloc:
92089c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	fb_dealloc_cmap(&fb_info.cmap);
92189c223a616cddd9eab792b860f61f99cec53c4e8Finn Thainfail_unmap:
92289c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	iounmap(fb_info.screen_base);
92389c223a616cddd9eab792b860f61f99cec53c4e8Finn Thain	iounmap_macfb();
924ed1705afb93409a3e345d653be9d263984aa5c1bAl Viro	return err;
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(macfb_init);
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
929