/*
* linux/drivers/video/platinumfb-hw.c -- Frame buffer device for the
* Platinum on-board video in PowerMac 7200s (and some clones based
* on the same motherboard.)
*
* Created 09 Feb 1998 by Jon Howell <jonh@cs.dartmouth.edu>
*
* Copyright (C) 1998 Jon Howell
*
* based on drivers/macintosh/platinum.c: Console support
* for PowerMac "platinum" display adaptor.
* Copyright (C) 1996 Paul Mackerras and Mark Abene.
*
* based on skeletonfb.c:
* Created 28 Dec 1997 by Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
/*
* Structure of the registers for the DACula colormap device.
*/
struct cmap_regs {
unsigned char addr;
char pad1[15 ];
unsigned char d1;
char pad2[15 ];
unsigned char d2;
char pad3[15 ];
unsigned char lut;
char pad4[15 ];
};
/*
* Structure of the registers for the "platinum" display adaptor".
*/
struct preg { /* padded register */
unsigned r; /* notice this is 32 bits. */
char pad[12 ];
};
struct platinum_regs {
struct preg reg[128 ];
};
/*
* Register initialization tables for the platinum display.
*
* It seems that there are two different types of platinum display
* out there. Older ones use the values in clocksel[1], for which
* the formula for the clock frequency seems to be
* F = 14.3MHz * c0 / (c1 & 0x1f) / (1 << (c1 >> 5))
* Newer ones use the values in clocksel[0], for which the formula
* seems to be
* F = 15MHz * c0 / ((c1 & 0x1f) + 2) / (1 << (c1 >> 5))
*/
struct platinum_regvals {
int fb_offset;
int pitch[3 ];
unsigned regs[26 ];
unsigned char offset[3 ];
unsigned char mode[3 ];
unsigned char dacula_ctrl[3 ];
unsigned char clock_params[2 ][2 ];
};
#define DIV2 0 x20
#define DIV4 0 x40
#define DIV8 0 x60
#define DIV16 0 x80
/* 1280x1024, 75Hz (20) */
static struct platinum_regvals platinum_reg_init_20 = {
0 x5c00,
{ 1312 , 2592 , 2592 },
{ 0 xffc, 4 , 0 , 0 , 0 , 0 , 0 x428, 0 ,
0 , 0 xb3, 0 xd3, 0 x12, 0 x1a5, 0 x23, 0 x28, 0 x2d,
0 x5e, 0 x19e, 0 x1a4, 0 x854, 0 x852, 4 , 9 , 0 x50,
0 x850, 0 x851 }, { 0 x58, 0 x5d, 0 x5d },
{ 0 , 0 xff, 0 xff }, { 0 x51, 0 x55, 0 x55 },
{{ 45 , 3 }, { 66 , 7 }}
};
/* 1280x960, 75Hz (19) */
static struct platinum_regvals platinum_reg_init_19 = {
0 x5c00,
{ 1312 , 2592 , 2592 },
{ 0 xffc, 4 , 0 , 0 , 0 , 0 , 0 x428, 0 ,
0 , 0 xb2, 0 xd2, 0 x12, 0 x1a3, 0 x23, 0 x28, 0 x2d,
0 x5c, 0 x19c, 0 x1a2, 0 x7d0, 0 x7ce, 4 , 9 , 0 x4c,
0 x7cc, 0 x7cd }, { 0 x56, 0 x5b, 0 x5b },
{ 0 , 0 xff, 0 xff }, { 0 x51, 0 x55, 0 x55 },
{{ 42 , 3 }, { 44 , 5 }}
};
/* 1152x870, 75Hz (18) */
static struct platinum_regvals platinum_reg_init_18 = {
0 x11b0,
{ 1184 , 2336 , 4640 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x38f, 0 ,
0 , 0 x294, 0 x16c, 0 x20, 0 x2d7, 0 x3f, 0 x49, 0 x53,
0 x82, 0 x2c2, 0 x2d6, 0 x726, 0 x724, 4 , 9 , 0 x52,
0 x71e, 0 x722 }, { 0 x74, 0 x7c, 0 x81 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 26 , 0 + DIV2 }, { 42 , 6 }}
};
/* 1024x768, 75Hz (17) */
static struct platinum_regvals platinum_reg_init_17 = {
0 x10b0,
{ 1056 , 2080 , 4128 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x254, 0 x14b, 0 x18, 0 x295, 0 x2f, 0 x32, 0 x3b,
0 x80, 0 x280, 0 x296, 0 x648, 0 x646, 4 , 9 , 0 x40,
0 x640, 0 x644 }, { 0 x72, 0 x7a, 0 x7f },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 54 , 3 + DIV2 }, { 67 , 12 }}
};
/* 1024x768, 75Hz (16) */
static struct platinum_regvals platinum_reg_init_16 = {
0 x10b0,
{ 1056 , 2080 , 4128 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x250, 0 x147, 0 x17, 0 x28f, 0 x2f, 0 x35, 0 x47,
0 x82, 0 x282, 0 x28e, 0 x640, 0 x63e, 4 , 9 , 0 x3c,
0 x63c, 0 x63d }, { 0 x74, 0 x7c, 0 x81 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 20 , 0 + DIV2 }, { 11 , 2 }}
};
/* 1024x768, 70Hz (15) */
static struct platinum_regvals platinum_reg_init_15 = {
0 x10b0,
{ 1056 , 2080 , 4128 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x254, 0 x14b, 0 x22, 0 x297, 0 x43, 0 x49, 0 x5b,
0 x86, 0 x286, 0 x296, 0 x64c, 0 x64a, 0 xa, 0 xf, 0 x44,
0 x644, 0 x646 }, { 0 x78, 0 x80, 0 x85 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 19 , 0 + DIV2 }, { 110 , 21 }}
};
/* 1024x768, 60Hz (14) */
static struct platinum_regvals platinum_reg_init_14 = {
0 x10b0,
{ 1056 , 2080 , 4128 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x25a, 0 x14f, 0 x22, 0 x29f, 0 x43, 0 x49, 0 x5b,
0 x8e, 0 x28e, 0 x29e, 0 x64c, 0 x64a, 0 xa, 0 xf, 0 x44,
0 x644, 0 x646 }, { 0 x80, 0 x88, 0 x8d },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 71 , 6 + DIV2 }, { 118 , 13 + DIV2 }}
};
/* 832x624, 75Hz (13) */
static struct platinum_regvals platinum_reg_init_13 = {
0 x70,
{ 864 , 1680 , 3344 }, /* MacOS does 1680 instead of 1696 to fit 16bpp in 1MB,
* and we use 3344 instead of 3360 to fit in 2Mb
*/
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x299, 0 ,
0 , 0 x21e, 0 x120, 0 x10, 0 x23f, 0 x1f, 0 x25, 0 x37,
0 x8a, 0 x22a, 0 x23e, 0 x536, 0 x534, 4 , 9 , 0 x52,
0 x532, 0 x533 }, { 0 x7c, 0 x84, 0 x89 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 30 , 0 + DIV4 }, { 56 , 7 + DIV2 }}
};
/* 800x600, 75Hz (12) */
static struct platinum_regvals platinum_reg_init_12 = {
0 x1010,
{ 832 , 1632 , 3232 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x1ce, 0 x108, 0 x14, 0 x20f, 0 x27, 0 x30, 0 x39,
0 x72, 0 x202, 0 x20e, 0 x4e2, 0 x4e0, 4 , 9 , 0 x2e,
0 x4de, 0 x4df }, { 0 x64, 0 x6c, 0 x71 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 122 , 7 + DIV4 }, { 62 , 9 + DIV2 }}
};
/* 800x600, 72Hz (11) */
static struct platinum_regvals platinum_reg_init_11 = {
0 x1010,
{ 832 , 1632 , 3232 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x1ca, 0 x104, 0 x1e, 0 x207, 0 x3b, 0 x44, 0 x4d,
0 x56, 0 x1e6, 0 x206, 0 x534, 0 x532, 0 xa, 0 xe, 0 x38,
0 x4e8, 0 x4ec }, { 0 x48, 0 x50, 0 x55 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 26 , 0 + DIV4 }, { 42 , 6 + DIV2 }}
};
/* 800x600, 60Hz (10) */
static struct platinum_regvals platinum_reg_init_10 = {
0 x1010,
{ 832 , 1632 , 3232 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x1ce, 0 x108, 0 x20, 0 x20f, 0 x3f, 0 x45, 0 x5d,
0 x66, 0 x1f6, 0 x20e, 0 x4e8, 0 x4e6, 6 , 0 xa, 0 x34,
0 x4e4, 0 x4e5 }, { 0 x58, 0 x60, 0 x65 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 54 , 3 + DIV4 }, { 95 , 1 + DIV8 }}
};
/* 800x600, 56Hz (9) --unsupported? copy of mode 10 for now... */
static struct platinum_regvals platinum_reg_init_9 = {
0 x1010,
{ 832 , 1632 , 3232 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x1ce, 0 x108, 0 x20, 0 x20f, 0 x3f, 0 x45, 0 x5d,
0 x66, 0 x1f6, 0 x20e, 0 x4e8, 0 x4e6, 6 , 0 xa, 0 x34,
0 x4e4, 0 x4e5 }, { 0 x58, 0 x60, 0 x65 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 54 , 3 + DIV4 }, { 88 , 1 + DIV8 }}
};
/* 768x576, 50Hz Interlaced-PAL (8) */
static struct platinum_regvals platinum_reg_init_8 = {
0 x1010,
{ 800 , 1568 , 3104 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 xc8, 0 xec, 0 x11, 0 x1d7, 0 x22, 0 x25, 0 x36,
0 x47, 0 x1c7, 0 x1d6, 0 x271, 0 x270, 4 , 9 , 0 x27,
0 x267, 0 x26b }, { 0 x39, 0 x41, 0 x46 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 31 , 0 + DIV16 }, { 74 , 9 + DIV8 }}
};
/* 640x870, 75Hz Portrait (7) */
static struct platinum_regvals platinum_reg_init_7 = {
0 xb10,
{ 672 , 1312 , 2592 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x176, 0 xd0, 0 x14, 0 x19f, 0 x27, 0 x2d, 0 x3f,
0 x4a, 0 x18a, 0 x19e, 0 x72c, 0 x72a, 4 , 9 , 0 x58,
0 x724, 0 x72a }, { 0 x3c, 0 x44, 0 x49 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 30 , 0 + DIV4 }, { 56 , 7 + DIV2 }}
};
/* 640x480, 67Hz (6) */
static struct platinum_regvals platinum_reg_init_6 = {
0 x1010,
{ 672 , 1312 , 2592 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x209, 0 ,
0 , 0 x18e, 0 xd8, 0 x10, 0 x1af, 0 x1f, 0 x25, 0 x37,
0 x4a, 0 x18a, 0 x1ae, 0 x41a, 0 x418, 4 , 9 , 0 x52,
0 x412, 0 x416 }, { 0 x3c, 0 x44, 0 x49 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 99 , 4 + DIV8 }, { 42 , 5 + DIV4 }}
};
/* 640x480, 60Hz (5) */
static struct platinum_regvals platinum_reg_init_5 = {
0 x1010,
{ 672 , 1312 , 2592 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x15e, 0 xc8, 0 x18, 0 x18f, 0 x2f, 0 x35, 0 x3e,
0 x42, 0 x182, 0 x18e, 0 x41a, 0 x418, 2 , 7 , 0 x44,
0 x404, 0 x408 }, { 0 x34, 0 x3c, 0 x41 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 26 , 0 + DIV8 }, { 14 , 2 + DIV4 }}
};
/* 640x480, 60Hz Interlaced-NTSC (4) */
static struct platinum_regvals platinum_reg_init_4 = {
0 x1010,
{ 672 , 1312 , 2592 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 xa5, 0 xc3, 0 xe, 0 x185, 0 x1c, 0 x1f, 0 x30,
0 x37, 0 x177, 0 x184, 0 x20d, 0 x20c, 5 , 0 xb, 0 x23,
0 x203, 0 x206 }, { 0 x29, 0 x31, 0 x36 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 94 , 5 + DIV16 }, { 48 , 7 + DIV8 }}
};
/* 640x480, 50Hz Interlaced-PAL (3) */
static struct platinum_regvals platinum_reg_init_3 = {
0 x1010,
{ 672 , 1312 , 2592 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 xc8, 0 xec, 0 x11, 0 x1d7, 0 x22, 0 x25, 0 x36,
0 x67, 0 x1a7, 0 x1d6, 0 x271, 0 x270, 4 , 9 , 0 x57,
0 x237, 0 x26b }, { 0 x59, 0 x61, 0 x66 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 31 , 0 + DIV16 }, { 74 , 9 + DIV8 }}
};
/* 512x384, 60Hz (2) */
static struct platinum_regvals platinum_reg_init_2 = {
0 x1010,
{ 544 , 1056 , 2080 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 x25c, 0 x140, 0 x10, 0 x27f, 0 x1f, 0 x2b, 0 x4f,
0 x68, 0 x268, 0 x27e, 0 x32e, 0 x32c, 4 , 9 , 0 x2a,
0 x32a, 0 x32b }, { 0 x5a, 0 x62, 0 x67 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 33 , 2 + DIV8 }, { 79 , 9 + DIV8 }}
};
/* 512x384, 60Hz Interlaced-NTSC (1) */
static struct platinum_regvals platinum_reg_init_1 = {
0 x1010,
{ 544 , 1056 , 2080 },
{ 0 xff0, 4 , 0 , 0 , 0 , 0 , 0 x320, 0 ,
0 , 0 xa5, 0 xc3, 0 xe, 0 x185, 0 x1c, 0 x1f, 0 x30,
0 x57, 0 x157, 0 x184, 0 x20d, 0 x20c, 5 , 0 xb, 0 x53,
0 x1d3, 0 x206 }, { 0 x49, 0 x51, 0 x56 },
{ 2 , 0 , 0 xff }, { 0 x11, 0 x15, 0 x19 },
{{ 94 , 5 + DIV16 }, { 48 , 7 + DIV8 }}
};
static struct platinum_regvals *platinum_reg_init[VMODE_MAX] = {
&platinum_reg_init_1,
&platinum_reg_init_2,
&platinum_reg_init_3,
&platinum_reg_init_4,
&platinum_reg_init_5,
&platinum_reg_init_6,
&platinum_reg_init_7,
&platinum_reg_init_8,
&platinum_reg_init_9,
&platinum_reg_init_10,
&platinum_reg_init_11,
&platinum_reg_init_12,
&platinum_reg_init_13,
&platinum_reg_init_14,
&platinum_reg_init_15,
&platinum_reg_init_16,
&platinum_reg_init_17,
&platinum_reg_init_18,
&platinum_reg_init_19,
&platinum_reg_init_20
};
struct vmode_attr {
int hres;
int vres;
int vfreq;
int interlaced;
};
struct vmode_attr vmode_attrs[VMODE_MAX] = {
{512 , 384 , 60 , 1 },
{512 , 384 , 60 },
{640 , 480 , 50 , 1 },
{640 , 480 , 60 , 1 },
{640 , 480 , 60 },
{640 , 480 , 67 },
{640 , 870 , 75 },
{768 , 576 , 50 , 1 },
{800 , 600 , 56 },
{800 , 600 , 60 },
{800 , 600 , 72 },
{800 , 600 , 75 },
{832 , 624 , 75 },
{1024 , 768 , 60 },
{1024 , 768 , 72 },
{1024 , 768 , 75 },
{1024 , 768 , 75 },
{1152 , 870 , 75 },
{1280 , 960 , 75 },
{1280 , 1024 , 75 }
};
Messung V0.5 in Prozent C=95 H=93 G=93