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