patch-2.1.97 linux/drivers/macintosh/imstt.c

Next file: linux/drivers/macintosh/imstt.h
Previous file: linux/drivers/macintosh/control.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.96/linux/drivers/macintosh/imstt.c linux/drivers/macintosh/imstt.c
@@ -2,28 +2,41 @@
  * imstt.c: Console support for PowerMac "imstt" display adaptor.
  *
  * Copyright (C) 1997 Sigurdur Asgeirsson
+ * Modified by Danilo Beuche 1997
  *	
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+#include <linux/module.h>
+
+#include <linux/config.h>
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/vc_ioctl.h>
 #include <linux/pci.h>
-#include <linux/bios32.h>
 #include <linux/nvram.h>
 #include <asm/prom.h>
 #include <asm/io.h>
+#include <asm/pgtable.h>
 #include <asm/pci-bridge.h>
 #include <linux/selection.h>
 #include <linux/vt_kern.h>
 #include "pmac-cons.h"
 #include "imstt.h"
 
+
+enum { 
+  IBMRAMDAC = 0x00,
+  TVPRAMDAC  = 0x01
+};
+
+
+// IMS TWIN TURBO 
 enum
 {
   S1SA		=  0, /* 0x00 */
@@ -79,6 +92,8 @@
 #endif
 };
 
+
+// IBM RAMDAC
 enum
 {
  PADDRW		= 0x00,
@@ -97,12 +112,256 @@
  PC0		= 0x23
 };
 
+// TI TVP 3030 RAMDAC Direct Registers
+enum 
+{
+	TVPADDRW = 0x00, // 0  Palette/Cursor RAM Write Adress/Index
+	TVPPDATA = 0x04, // 1  Palette Data RAM Data
+	TVPPMASK = 0x08, // 2  Pixel Read-Mask
+	TVPPADRR = 0x0c, // 3  Palette/Cursor RAM Read Adress
+	TVPCADRW = 0x10, // 4  Cursor/Overscan Color Write Address
+	TVPCDATA = 0x14, // 5  Cursor/Overscan Color Data
+			 // 6  reserved
+	TVPCADRR = 0x1c, // 7  Cursor/Overscan Color Read Address
+			 // 8  reserved
+	TVPDCCTL = 0x24, // 9  Direct Cursor Control
+	TVPIDATA = 0x28, // 10 Index Data
+	TVPCRDAT = 0x2c, // 11 Cursor RAM Data
+	TVPCXPOL = 0x30, // 12 Cursor-Position X LSB
+	TVPCXPOH = 0x34, // 13 Cursor-Position X MSB
+	TVPCYPOL = 0x38, // 14 Cursor-Position Y LSB
+	TVPCYPOH = 0x3c, // 15 Cursor-Position Y MSB
+};
+
+// TI TVP 3030 RAMDAC Indirect Registers
+enum
+{
+	TVPIRREV = 0x01, // Silicon Revision [RO] 
+	TVPIRICC = 0x06, // Indirect Cursor Control 	(0x00) 
+	TVPIRBRC = 0x07, // Byte Router Control 	(0xe4)
+	TVPIRLAC = 0x0f, // Latch Control 		(0x06)
+	TVPIRTCC = 0x18, // True Color Control  	(0x80)
+	TVPIRMXC = 0x19, // Multiplex Control		(0x98)
+	TVPIRCLS = 0x1a, // Clock Selection		(0x07)
+	TVPIRPPG = 0x1c, // Palette Page		(0x00)
+	TVPIRGEC = 0x1d, // General Control 		(0x00)
+	TVPIRMIC = 0x1e, // Miscellaneous Control	(0x00)
+	TVPIRPLA = 0x2c, // PLL Address			
+	TVPIRPPD = 0x2d, // Pixel Clock PLL Data
+	TVPIRMPD = 0x2e, // Memory Clock PLL Data
+	TVPIRLPD = 0x2f, // Loop Clock PLL Data
+	TVPIRCKL = 0x30, // Color-Key Overlay Low
+	TVPIRCKH = 0x31, // Color-Key Overlay High 
+	TVPIRCRL = 0x32, // Color-Key Red Low
+	TVPIRCRH = 0x33, // Color-Key Red High 
+	TVPIRCGL = 0x34, // Color-Key Green Low
+	TVPIRCGH = 0x35, // Color-Key Green High 
+	TVPIRCBL = 0x36, // Color-Key Blue Low
+	TVPIRCBH = 0x37, // Color-Key Blue High 
+	TVPIRCKC = 0x38, // Color-Key Control 		(0x00)
+	TVPIRMLC = 0x39, // MCLK/Loop Clock Control	(0x18)
+	TVPIRSEN = 0x3a, // Sense Test			(0x00)
+	TVPIRTMD = 0x3b, // Test Mode Data
+	TVPIRRML = 0x3c, // CRC Remainder LSB [RO]
+	TVPIRRMM = 0x3d, // CRC Remainder MSB [RO]
+	TVPIRRMS = 0x3e, // CRC  Bit Select [WO] 
+	TVPIRDID = 0x3f, // Device ID [RO] 		(0x30)
+	TVPIRRES = 0xff, // Software Reset [WO]
+
+};
+
 struct initvalues
 {
   unsigned char	addr, value;
 };
 
-static struct initvalues initregs[] = 
+
+
+// Values which only depend on resolution not on color mode
+struct tt_single_rmodevals
+{
+	unsigned short hes;	
+	unsigned short heb;	
+	unsigned short hsb;	
+	unsigned short ht;	
+	unsigned short ves;	
+	unsigned short veb;	
+	unsigned short vsb;	
+	unsigned short vt;	
+};
+
+struct tvp_single_rmodevals
+{
+	unsigned char pclk_n;
+	unsigned char pclk_m;
+	unsigned char pclk_p;
+};
+
+struct ibm_single_rmodevals
+{
+	unsigned char pclk_m;
+	unsigned char pclk_n;
+	unsigned char pclk_p;
+	unsigned char pclk_c;
+};
+
+// Values which only depend on color mode not on resolution
+struct tvp_single_cmodevals
+{
+	unsigned char tcc; // True Color control
+	unsigned char mxc; // Multiplexer control
+	unsigned char lckl_n;	// N value of LCKL PLL
+};
+
+struct ibm_single_cmodevals
+{
+	unsigned char pformat; // pixel format
+};
+	
+// Values of the tvp which change depending on colormode x resolution
+struct tvp_single_crmodevals
+{
+	unsigned char mlc;	// Memory Loop Config 0x39
+	unsigned char lckl_p;	// P value of LCKL PLL
+};
+
+struct ibm_single_crmodevals
+{
+    // oh nothing changes
+};
+
+// complete configuration for a resolution in all depths 
+// 0 = 8 Bit, 15/16 bit = 1 , 32 Bit = 2 
+struct ims_crmodevals
+{
+	int pitch;
+	struct tt_single_rmodevals tt[2];  // for each ramdac  seperate tt config
+
+	struct tvp_single_rmodevals tvp_clock;  // for each ramdac  seperate clock config
+	struct tvp_single_crmodevals tvp[3]; 	   // for each colormode 
+
+	struct ibm_single_rmodevals ibm_clock;  // for each ramdac  seperate clock config
+//	struct ibm_single_crmodevals ibm[3];	   // for each color mode 
+};
+
+struct ims_modevals
+{
+	int dac;			  // which dac do we have
+	int total_vram;			  // how much vram is on board
+	int sense;			  // what monitor
+	unsigned char*	fb;		  // frame buffer address
+	unsigned char*	fb_phys;	  // frame buffer address
+	unsigned char*  cmap;		  // dac address
+	unsigned char*  cmap_phys;	  // dac address
+	unsigned int*	dc;		  // tt address
+	unsigned int*	dc_phys;	  // tt address
+
+	struct initvalues*     init[2];	  // initial register settings for each ramdac
+
+	struct ims_crmodevals* mode[20];  // for each possible mode
+	
+	struct  tvp_single_cmodevals tvp[3]; // for each color mode
+	
+	struct  ibm_single_cmodevals ibm[3]; // for each color mode
+};
+
+
+struct ims_crmodevals imsmode_6 =
+{
+	640,
+	{
+  		{ 0x08, 0x12, 0x62, 0x6C, 0x0003, 0x002A, 0x020A, 0x020C },
+		{ 0x04, 0x0009, 0x0031, 0x0036, 0x0003, 0x002a, 0x020a, 0x020d },
+	},
+	{	0xef, 0x2e, 0xb2 },
+	{
+		{ 0x39, 0xf3 },
+		{ 0x39, 0xf3 },
+		{ 0x38, 0xf3 }
+	},
+	// IBM CLOCK
+	{       0x78, 0x13, 0x02, 0x02 },
+};
+
+struct ims_crmodevals imsmode_13 =
+{
+	832,
+	{
+  		{ 0x05, 0x20, 0x88, 0x90, 0x0003, 0x0028, 0x0298, 0x029B },
+		{ 0x04, 0x0011, 0x0045, 0x0048, 0x0003, 0x002a, 0x029a, 0x029b},
+	},
+	{	0xfe, 0x3e, 0xf1 },
+	{
+		{ 0x39, 0xf3 },
+		{ 0x38, 0xf3 },
+		{ 0x38, 0xf2 }
+	},
+	{ 0x3E, 0x0A, 0x01, 0x02 }
+};
+struct ims_crmodevals imsmode_17 =
+{
+	1024,
+	{
+  		{ 0x0A, 0x1C, 0x9C, 0xA6, 0x0003, 0x0020, 0x0320, 0x0323 } ,
+		{ 0x06, 0x0210, 0x0250, 0x0053, 0x1003, 0x0021, 0x0321, 0x0324 },
+	},
+	{	0xfc, 0x3a, 0xf1 },
+	{
+		{ 0x39, 0xf3 },
+		{ 0x38, 0xf3 },
+		{ 0x38, 0xf2 }
+	},
+	{ 0x07, 0x00, 0x01, 0x02 }
+};
+struct ims_crmodevals imsmode_18 =
+{
+	1152,
+	{
+		{ 0, 0, 0, 0, 0, 0, 0, 0 },
+  		{ 0x09, 0x0011, 0x059, 0x5b, 0x0003, 0x0031, 0x0397, 0x039a }, 
+	},
+	{	0xfd, 0x3a, 0xf1 },
+	{
+		{ 0x39, 0xf3 },
+		{ 0x38, 0xf3 },
+		{ 0x38, 0xf2 }
+	},
+	{ 0, 0, 0, 0 }
+};
+struct ims_crmodevals imsmode_19 =
+{
+	1280,
+	{
+		{ 0, 0, 0, 0, 0, 0, 0, 0 },
+		{ 0x09, 0x0016, 0x0066, 0x0069, 0x0003, 0x0027, 0x03e7, 0x03e8 },
+	},
+	{	0xf7, 0x36, 0xf0 },
+	{
+		{ 0x38, 0xf3 },
+		{ 0x38, 0xf2 },
+		{ 0x38, 0xf1 }
+	},
+	{ 0, 0, 0, 0 }
+};
+struct ims_crmodevals imsmode_20 =
+{
+	1280,
+	{
+		{ 0, 0, 0, 0, 0, 0, 0, 0 },
+		{ 0x09, 0x0018, 0x0068, 0x006a, 0x0003, 0x0029, 0x0429, 0x042a },
+	},
+	{	0xf0, 0x2d, 0xf0 },
+	{
+		{ 0x38, 0xf3 },
+		{ 0x38, 0xf2 },
+		{ 0x38, 0xf1 }
+	},
+      	{ 0, 0, 0, 0 }
+};
+
+// IBM RAMDAC initial register values
+
+static struct initvalues ibm_initregs[] = 
 {
  { 0x02, 0x21 },	/* (0x01) Miscellaneous Clock Control */
  { 0x03, 0x00 },	/* (0x00) Sync Control */
@@ -129,64 +388,114 @@
  { 0x71, 0x45 },	/* (0x00) Miscellaneous Control 2 */
  { 0x72, 0x00 },	/* (0x00) Miscellaneous Control 3 */
  { 0x78, 0x00 },	/* (0x00) Key Control/DB Operation */
+ { 0x00, 0x00 } 
+};
+
+
+static struct initvalues tvp_initregs[] = 
+{
+{ 0x6, 0x00},
+{ 0x7, 0xe4},
+{ 0xf, 0x06},
+{ 0x18, 0x80},
+{ 0x19, 0x4d},
+{ 0x1a, 0x05},
+{ 0x1c, 0x00},
+{ 0x1d, 0x00},
+{ 0x1e, 0x08},
+{ 0x30, 0xff},
+{ 0x31, 0xff},
+{ 0x32, 0xff},
+{ 0x33, 0xff},
+{ 0x34, 0xff},
+{ 0x35, 0xff},
+{ 0x36, 0xff},
+{ 0x37, 0xff},
+{ 0x38, 0x00},
+{ TVPIRPLA, 0x00 },
+{ TVPIRPPD, 0xc0 },
+{ TVPIRPPD, 0xd5 },
+{ TVPIRPPD, 0xea },
+{ TVPIRPLA, 0x00 },
+{ TVPIRMPD, 0xb9 },
+{ TVPIRMPD, 0x3a },
+{ TVPIRMPD, 0xb1 },
+{ TVPIRPLA, 0x00 },
+{ TVPIRLPD, 0xc1 },
+{ TVPIRLPD, 0x3d },
+{ TVPIRLPD, 0xf3 },
+{ 0x00, 0x00 } 
 };
 
-static void set_imstt_clock(unsigned char *params);
+
+static struct ims_modevals ims_info =
+{
+	-1,	// DAC
+	-1,	// VRAM
+	-1, 	// Monitor;
+	0,	// Framebuffer
+	0,	// Framebuffer_phys
+	0,	// colormap
+	0,	// colormap_phys
+	0,	// dc
+	0,	// dc_phys
+	{ ibm_initregs, tvp_initregs},
+	{
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		&imsmode_6,
+		&imsmode_6,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		&imsmode_13,
+		NULL,
+		NULL,
+		NULL,
+		&imsmode_17,
+		&imsmode_18,
+		&imsmode_19,
+		&imsmode_20
+	},
+	{
+		{ 0x80, 0x4d, 0xc1 },
+		{ 0x44, 0x55, 0xe1 },
+		{ 0x46, 0x5d, 0xf1 }
+	},
+	{
+		{ 0x03 },
+		{ 0x04 },
+		{ 0x06 }
+	}	
+};	
+		
+	
+
+
+// static void set_imstt_clock(unsigned char *params);
+static void map_imstt_display(struct device_node *, int);
 static int read_imstt_sense(void);
 static int imstt_vram_reqd(int vmode, int cmode);
 
-static int total_vram = 2 * 1024 * 1024;		/* total amount of video memory, bytes */
-static unsigned char *frame_buffer;
-static unsigned char *cmap_regs;
-static unsigned *dc_regs;
 
+#if 0
+static int get_tvp_ireg(int iaddr)
+{
+	ims_info.cmap[0] = iaddr & 0xff; eieio();
+	return ims_info.cmap[40];
+}
+#endif
 
-/*
- * Register initialization tables for the imstt display.
- *
- * Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1)
- * where m = clk[0], n = clk[1], p = clk[2]
- * clk[3] is c, charge pump bias which depends on the VCO frequency  
- */
-struct imstt_regvals {
-	unsigned short		cfg[8];
-	unsigned char		clk[4];
-	unsigned long		pitch[3];
-} imsttmode;
-
-/* Register values for 1024x768, 75Hz mode (17) */
-static struct imstt_regvals imstt_reg_init_17 = {
-  { 0x0A, 0x1C, 0x9C, 0xA6, 0x0003, 0x0020, 0x0320, 0x0323 }, 
-  { 0x07, 0x00, 0x01, 0x02 },
-  { 0x0400, 0x0800, 0x1000 }
-};
-
-/* Register values for 832x624, 75Hz mode (13) */
-static struct imstt_regvals imstt_reg_init_13 = {
-  { 0x05, 0x20, 0x88, 0x90, 0x0003, 0x0028, 0x0298, 0x029B },
-  { 0x3E, 0x0A, 0x01, 0x02 },
-  { 832, 832 * 2, 832 * 4 }
-};
-
-/* Register values for 640x480, 67Hz mode (6) */
-static struct imstt_regvals imstt_reg_init_6 = {
-  { 0x08, 0x12, 0x62, 0x6C, 0x0003, 0x002A, 0x020A, 0x020C },
-  { 0x78, 0x13, 0x02, 0x02 },
-  { 640, 640 * 2, 640 * 4 }
-};
-
-static struct imstt_regvals *imstt_reg_init[20] = {
-	NULL, NULL, NULL, NULL,
-	&imstt_reg_init_6, // fake'm out
-	&imstt_reg_init_6,
-	NULL, NULL, NULL,
-	NULL, NULL, NULL,
-	&imstt_reg_init_13,
-	NULL, NULL, NULL,
-	&imstt_reg_init_17,
-	NULL, NULL, NULL
-};
-
+static void set_tvp_ireg(int iaddr,unsigned char value)
+{
+	ims_info.cmap[0] = iaddr & 0xff; eieio();
+	ims_info.cmap[40] = value; eieio();
+}
 /*
  * Get the monitor sense value.
  * Note that this can be called before calibrate_delay,
@@ -199,28 +508,28 @@
 	int sense;
 	unsigned gio, gioe;
 
-	gio = ld_le32(dc_regs + GIO) & ~0x0038;
+	gio = ld_le32(ims_info.dc + GIO) & ~0x0038;
 	gioe = ld_le32(dc_
 	
-	out_le32(dc_regs + GIOE, reg);	/* drive all lines high */
+	out_le32(ims_info.dc + GIOE, reg);	/* drive all lines high */
 	__delay(200);
-	out_le32(dc_regs + GIOE, 077);	/* turn off drivers */
+	out_le32(ims_info.dc + GIOE, 077);	/* turn off drivers */
 	__delay(2000);
-	sense = (in_le32(dc_regs + GIOE) & 0x1c0) << 2;
+	sense = (in_le32(ims_info.dc + GIOE) & 0x1c0) << 2;
 
 	/* drive each sense line low in turn and collect the other 2 */
-	out_le32(dc_regs + GIOE, 033);	/* drive A low */
+	out_le32(ims_info.dc + GIOE, 033);	/* drive A low */
 	__delay(2000);
-	sense |= (in_le32(dc_regs + GIOE) & 0xc0) >> 2;
-	out_le32(dc_regs + GIOE, 055);	/* drive B low */
+	sense |= (in_le32(ims_info.dc + GIOE) & 0xc0) >> 2;
+	out_le32(ims_info.dc + GIOE, 055);	/* drive B low */
 	__delay(2000);
-	sense |= ((in_le32(dc_regs + GIOE) & 0x100) >> 5)
-		| ((in_le32(dc_regs + GIOE) & 0x40) >> 4);
-	out_le32(dc_regs + GIOE, 066);	/* drive C low */
+	sense |= ((in_le32(ims_info.dc + GIOE) & 0x100) >> 5)
+		| ((in_le32(ims_info.dc + GIOE) & 0x40) >> 4);
+	out_le32(ims_info.dc + GIOE, 066);	/* drive C low */
 	__delay(2000);
-	sense |= (in_le32(dc_regs + GIOE) & 0x180) >> 7;
+	sense |= (in_le32(ims_info.dc + GIOE) & 0x180) >> 7;
 
-	out_le32(dc_regs + GIOE, 077);	/* turn off drivers */
+	out_le32(ims_info.dc + GIOE, 077);	/* turn off drivers */
 	return sense;
 #else
 	return 0;
@@ -229,12 +538,24 @@
 
 static inline int imstt_vram_reqd(int vmode, int cmode)
 {
-	return vmode_attrs[vmode-1].vres
-		* imstt_reg_init[vmode-1]->pitch[cmode];
+	return vmode_attrs[vmode-1].vres *
+		(ims_info.mode[vmode-1])->pitch * ( 1 << cmode);
+}
+
+void
+map_imstt_display_tvp(struct device_node *dp)
+{
+    map_imstt_display(dp,1);
 }
 
 void
-map_imstt_display(struct device_node *dp)
+map_imstt_display_ibm(struct device_node *dp)
+{
+    map_imstt_display(dp,0);
+}
+
+static void
+map_imstt_display(struct device_node *dp, int which)
 {
 	int i, sense;
 	unsigned long addr, size, tmp;
@@ -244,7 +565,7 @@
 	if (dp->next != 0)
 		printk("Warning: only using first imstt display device\n");
 
-#if 1
+#if 0
 	printk("pmac_display_init: node = %p, addrs =", dp->node);
 	for (i = 0; i < dp->n_addrs; ++i)
 		printk(" %x(%x)", dp->addrs[i].address, dp->addrs[i].size);
@@ -259,12 +580,14 @@
 		addr = dp->addrs[i].address;
 		size = dp->addrs[i].size;
 		if (size >= 0x02000000) {
-			frame_buffer = ioremap(addr, size);
-			dc_regs = (unsigned*)(frame_buffer + 0x00800000);
-			cmap_regs = (unsigned char*)(frame_buffer + 0x00840000);
-
-			printk("mapped frame_buffer=%x(%x)", (unsigned)frame_buffer, (unsigned)size);
-			printk(" dc_regs=%x, cmap_regs=%x\n", (unsigned)dc_regs, (unsigned)cmap_regs);
+			ims_info.fb = __ioremap(addr, size, _PAGE_NO_CACHE);
+			ims_info.fb_phys = (unsigned char*)addr;
+			ims_info.dc = (unsigned*)(ims_info.fb + 0x00800000);
+			ims_info.dc_phys = (unsigned*)(ims_info.fb_phys + 0x00800000);
+			ims_info.cmap = (unsigned char*)(ims_info.fb + 0x00840000);
+			ims_info.cmap_phys = (unsigned char*)(ims_info.fb_phys + 0x00840000);
+			printk("mapped ims_info.fb=%x(%x)", (unsigned)ims_info.fb, (unsigned)size);
+			printk(" ims_info.dc=%x, ims_info.cmap=%x\n", (unsigned)ims_info.dc, (unsigned)ims_info.cmap);
 		}
 	}
 
@@ -282,12 +605,28 @@
 	else
 	  printk("unable to find pci device\n");
 
-	tmp = in_le32(dc_regs + SSTATUS);
+	tmp = in_le32(ims_info.dc + SSTATUS);
 	printk("chip version %ld, ", (tmp & 0x0F00) >> 8);
 
-	tmp = in_le32(dc_regs + PRC);
-	total_vram = (tmp & 0x0004) ? 0x000400000L : 0x000200000L;
-	printk("VRAM size %ldM\n", total_vram / 0x000100000L);
+	tmp = in_le32(ims_info.dc + PRC);
+	
+	if (0 == which )
+	    ims_info.total_vram = (tmp & 0x0004) ? 0x000400000L : 0x000200000L;
+	else
+	    ims_info.total_vram = 0x000800000L;
+	
+	printk("VRAM size %ldM\n", ims_info.total_vram / 0x000100000L);
+	
+	if (ims_info.total_vram == 0x000800000L)
+	{
+		ims_info.dac = TVPRAMDAC;
+		printk("Selecting TVP 3030 RAMDAC\n");
+	}
+	else
+	{
+		ims_info.dac = IBMRAMDAC;
+		printk("Selecting  IBM RAMDAC\n");
+	}
 
 	sense = read_imstt_sense();
 	printk("Monitor sense value = 0x%x, ", sense);
@@ -311,147 +650,232 @@
 	if (color_mode < CMODE_8 || color_mode > CMODE_32)
 		color_mode = CMODE_8;
 	while (color_mode > CMODE_8
-	       && imstt_vram_reqd(video_mode, color_mode) > total_vram)
+	       && imstt_vram_reqd(video_mode, color_mode) > ims_info.total_vram)
 		--color_mode;
 
 #endif
-
+	// Hack Hack Hack !!!
 	video_mode = VMODE_640_480_67;
 	color_mode = CMODE_8;
 }
 
+/*
+ * We dont need it ( all is done in ims_init )
 static void
-set_imstt_clock(unsigned char *params)
+set_imstt_clock_tvp(char* tvprv)
 {
-  cmap_regs[PIDXHI] = 0; eieio();
-  cmap_regs[PIDXLO] = PM0; eieio();
-  cmap_regs[PIDXDATA] = params[0]; eieio();
+  int j;
+  for (j=0;j<3;j++)
+	{
+  		set_tvp_ireg(TVPIRPLA,(j << 4) | (j << 2) | j); // Select same value for all plls
+		set_tvp_ireg(TVPIRPPD,tvprv[j]);
+		set_tvp_ireg(TVPIRMPD,tvprv[3+j]);
+		set_tvp_ireg(TVPIRLPD,tvprv[6+j]);
+	}
+}
 
-  cmap_regs[PIDXLO] = PN0; eieio();
-  cmap_regs[PIDXDATA] = params[1]; eieio();
+static void
+set_imstt_clock_ibm(unsigned char *params)
+{
+  ims_info.cmap[PIDXHI] = 0; eieio();
+  ims_info.cmap[PIDXLO] = PM0; eieio();
+  ims_info.cmap[PIDXDATA] = params[0]; eieio();
+
+  ims_info.cmap[PIDXLO] = PN0; eieio();
+  ims_info.cmap[PIDXDATA] = params[1]; eieio();
 
-  cmap_regs[PIDXLO] = PP0; eieio();
-  cmap_regs[PIDXDATA] = params[2]; eieio();
+  ims_info.cmap[PIDXLO] = PP0; eieio();
+  ims_info.cmap[PIDXDATA] = params[2]; eieio();
 	
-  cmap_regs[PIDXLO] = PC0; eieio();
-  cmap_regs[PIDXDATA] = params[3]; eieio();
+  ims_info.cmap[PIDXLO] = PC0; eieio();
+  ims_info.cmap[PIDXDATA] = params[3]; eieio();
 }
+*/
 
 void
 imstt_init()
 {
   int	                 i, yoff, hres;
-  unsigned long	         ctl, pitch, tmp;
-  unsigned char	         pformat;
-  unsigned               *p;
-  struct imstt_regvals   *init;
-
-  if (video_mode <= 0 || video_mode > VMODE_MAX
-      || (init = imstt_reg_init[video_mode-1]) == 0)
-    panic("imstt: display mode %d not supported", video_mode);
+  unsigned long	         ctl, pitch, tmp, scrCmode;
+  struct ims_crmodevals   *init;
+
+  if (video_mode <= 0 || video_mode > VMODE_MAX ) panic("imstt: display mode %d not supported(not in valid range)", video_mode);
+  if ((init = ims_info.mode[video_mode-1]) == 0) panic("imstt: display mode %d not supported(no mode definition)", video_mode);
+  if (init->tt[ims_info.dac].vt == 0) panic("imstt: display mode %d not supported (no timing definition)", video_mode);
+	
 
   n_scanlines = vmode_attrs[video_mode-1].vres;
   hres = vmode_attrs[video_mode-1].hres;
   pixel_size = 1 << color_mode;
-  line_pitch = init->pitch[color_mode];
+  line_pitch = init->pitch * pixel_size;
   row_pitch = line_pitch * 16;
 
   /* initialize the card */
-  tmp = in_le32(dc_regs + STGCTL);
-  out_le32(dc_regs + STGCTL, tmp & ~0x1);
+  tmp = in_le32(ims_info.dc + STGCTL);
+  out_le32(ims_info.dc + STGCTL, tmp & ~0x1);
 #if 0
-  out_le32(dc_regs + SCR, 0);
+  out_le32(ims_info.dc + SCR, 0);
 #endif
 
-  cmap_regs[PPMASK] = 0xFF;
-  /* set default values for DAC registers */ 
-  cmap_regs[PIDXHI] = 0; eieio();
-  for(i = 0; i < sizeof(initregs) / sizeof(*initregs); i++) {
-    cmap_regs[PIDXLO] = initregs[i].addr; eieio();
-    cmap_regs[PIDXDATA] = initregs[i].value; eieio();
+  switch(ims_info.dac)
+  {
+  case IBMRAMDAC:
+      ims_info.cmap[PPMASK] = 0xFF; eieio();
+      ims_info.cmap[PIDXHI] = 0x00; eieio();
+      for (i = 0; ims_info.init[IBMRAMDAC][i].addr != 0 && ims_info.init[IBMRAMDAC][i].value != 0 ;i++)
+	  {
+	      ims_info.cmap[PIDXLO] = ims_info.init[IBMRAMDAC][i].addr; eieio();
+	      ims_info.cmap[PIDXDATA] = ims_info.init[IBMRAMDAC][i].value; eieio();
+	  }
+
+      ims_info.cmap[PIDXHI] = 0; eieio();
+      ims_info.cmap[PIDXLO] = PM0; eieio();
+      ims_info.cmap[PIDXDATA] = init->ibm_clock.pclk_m; eieio();
+
+      ims_info.cmap[PIDXLO] = PN0; eieio();
+      ims_info.cmap[PIDXDATA] = init->ibm_clock.pclk_n; eieio();
+
+      ims_info.cmap[PIDXLO] = PP0; eieio();
+      ims_info.cmap[PIDXDATA] = init->ibm_clock.pclk_p; eieio();
+	
+      ims_info.cmap[PIDXLO] = PC0; eieio();
+      ims_info.cmap[PIDXDATA] = init->ibm_clock.pclk_c; eieio();
+      
+      ims_info.cmap[PIDXLO] = PPIXREP; eieio();
+      ims_info.cmap[PIDXDATA] = ims_info.ibm[color_mode].pformat; eieio();
+
+      break;
+  case TVPRAMDAC:
+	for (i = 0; ims_info.init[TVPRAMDAC][i].addr != 0 && ims_info.init[TVPRAMDAC][i].value != 0 ;i++)
+	{
+		set_tvp_ireg(ims_info.init[TVPRAMDAC][i].addr,ims_info.init[TVPRAMDAC][i].value);	
+	}
+    	set_tvp_ireg(TVPIRPLA,0x00);
+    	set_tvp_ireg(TVPIRPPD,init->tvp_clock.pclk_n);
+    	set_tvp_ireg(TVPIRPPD,init->tvp_clock.pclk_m);
+    	set_tvp_ireg(TVPIRPPD,init->tvp_clock.pclk_p);
+
+    	set_tvp_ireg(TVPIRTCC,ims_info.tvp[color_mode].tcc);
+    	set_tvp_ireg(TVPIRMXC,ims_info.tvp[color_mode].mxc);
+
+    	set_tvp_ireg(TVPIRPLA,0x00);
+    	set_tvp_ireg(TVPIRLPD,ims_info.tvp[color_mode].lckl_n);
+
+    	set_tvp_ireg(TVPIRPLA,0x15);
+    	set_tvp_ireg(TVPIRMLC,(init->tvp[color_mode]).mlc);
+
+    	set_tvp_ireg(TVPIRPLA,0x2a);
+    	set_tvp_ireg(TVPIRLPD,init->tvp[color_mode].lckl_p);
+	break;
   }
-  set_imstt_clock(init->clk);
+
 
   switch(color_mode) {
   case CMODE_32:
-    ctl = 0x17b5;
-    pitch = init->pitch[2] / 4;
-    pformat = 0x06;
+    ctl = 0x1785;
+    pitch = init->pitch;
+    scrCmode = 0x300;
     break;
   case CMODE_16:
-    ctl = 0x17b3;
-    pitch = init->pitch[1] / 4;
-    pformat = 0x04;
+    ctl = 0x1783;
+    pitch = init->pitch / 2;
+    scrCmode = 0x100;
     break;
   case CMODE_8:
   default:
-    ctl = 0x17b1;
-    pitch = init->pitch[0] / 4;
-    pformat = 0x03;
+    ctl = 0x1781;
+    pitch = init->pitch / 4;
+    scrCmode = 0x000;
     break;
   }
 
-  out_le32(&dc_regs[HES], init->cfg[0]);
-  out_le32(&dc_regs[HEB], init->cfg[1]);
-  out_le32(&dc_regs[HSB], init->cfg[2]);
-  out_le32(&dc_regs[HT], init->cfg[3]);
-  out_le32(&dc_regs[VES], init->cfg[4]);
-  out_le32(&dc_regs[VEB], init->cfg[5]);
-  out_le32(&dc_regs[VSB], init->cfg[6]);
-  out_le32(&dc_regs[VT], init->cfg[7]);
-  out_le32(&dc_regs[HCIV], 1);
-  out_le32(&dc_regs[VCIV], 1);
-  out_le32(&dc_regs[TCDR], 4);
-  out_le32(&dc_regs[VIL], 0);
-	
-  out_le32(&dc_regs[SSR], 0);
-  out_le32(&dc_regs[HRIR], 0x0200);
-  out_le32(&dc_regs[CMR], 0x01FF);
-  out_le32(&dc_regs[SRGCTL], 0x0003);
-  if(total_vram == 0x000200000)
-     out_le32(&dc_regs[SCR], 0x0059D);
-  else {
-    pitch /= 2;
-    out_le32(&dc_regs[SCR], 0x00D0DC);
+  out_le32(&ims_info.dc[HES], init->tt[ims_info.dac].hes);
+  out_le32(&ims_info.dc[HEB], init->tt[ims_info.dac].heb);
+  out_le32(&ims_info.dc[HSB], init->tt[ims_info.dac].hsb);
+  out_le32(&ims_info.dc[HT], init->tt[ims_info.dac].ht);
+  out_le32(&ims_info.dc[VES], init->tt[ims_info.dac].ves);
+  out_le32(&ims_info.dc[VEB], init->tt[ims_info.dac].veb);
+  out_le32(&ims_info.dc[VSB], init->tt[ims_info.dac].vsb);
+  out_le32(&ims_info.dc[VT], init->tt[ims_info.dac].vt);
+  out_le32(&ims_info.dc[HCIV], 1);
+  out_le32(&ims_info.dc[VCIV], 1);
+  out_le32(&ims_info.dc[TCDR], 4);
+  out_le32(&ims_info.dc[VIL], 0);
+	
+  out_le32(&ims_info.dc[SSR], 0);
+  out_le32(&ims_info.dc[HRIR], 0x0200);
+  out_le32(&ims_info.dc[CMR], 0x01FF);
+  out_le32(&ims_info.dc[SRGCTL], 0x0003);
+  switch(ims_info.total_vram)
+  {
+	case 0x000200000:
+     		out_le32(&ims_info.dc[SCR], 0x0059D| scrCmode);
+		break;
+	case 0x000400000:
+    		pitch /= 2;
+    		out_le32(&ims_info.dc[SCR], 0x00D0DC | scrCmode);
+		break;
+	case 0x000800000:
+    		pitch /= 2;
+    		out_le32(&ims_info.dc[SCR], 0x0150DD | scrCmode);
+		break;
   }
 
-  out_le32(&dc_regs[SPR], pitch);
-
-  cmap_regs[PIDXLO] = PPIXREP; eieio();
-  cmap_regs[PIDXDATA] = pformat; eieio();
+  out_le32(&ims_info.dc[SPR], pitch);
 
+  if (ims_info.dac == IBMRAMDAC)
+  {
+	  
 
+  }
+  
   pmac_init_palette();	/* Initialize colormap */
 
-  out_le32(&dc_regs[STGCTL], ctl);
+  out_le32(&ims_info.dc[STGCTL], ctl);
 
   yoff = (n_scanlines % 16) / 2;
-  fb_start = frame_buffer + yoff * line_pitch;
+  fb_start = ims_info.fb + yoff * line_pitch;
 
   /* Clear screen */
-  p = (unsigned *)frame_buffer;
-  for (i = n_scanlines * line_pitch / sizeof(unsigned); i != 0; --i)
-    *p++ = 0;
+  {
+	unsigned long *p;
+  	p = (unsigned long*)ims_info.fb;
+  	for (i = n_scanlines * line_pitch / sizeof(unsigned); i != 0; --i)
+    		*p++ = 0;
+  }
 
   display_info.height = n_scanlines;
   display_info.width = hres;
   display_info.depth = pixel_size * 8;
   display_info.pitch = line_pitch;
   display_info.mode = video_mode;
-  strncpy(display_info.name, "IMS,tt128mb", sizeof(display_info.name));
-  display_info.fb_address = (unsigned long) frame_buffer;
-  display_info.cmap_adr_address = (unsigned long) &cmap_regs[PADDRW];
-  display_info.cmap_data_address = (unsigned long) &cmap_regs[PDATA];
+
+  if (ims_info.dac == IBMRAMDAC )
+      strncpy(display_info.name, "IMS,tt128mb2/4", sizeof(display_info.name));
+  else
+      strncpy(display_info.name, "IMS,tt128mb8/8A", sizeof(display_info.name));
+  
+  display_info.fb_address = (unsigned long) ims_info.fb_phys;
+  display_info.cmap_adr_address = (unsigned long) &ims_info.cmap_phys[PADDRW];
+  display_info.cmap_data_address = (unsigned long) &ims_info.cmap_phys[PDATA];
   display_info.disp_reg_address = (unsigned long) NULL;
 }
 
 int
 imstt_setmode(struct vc_mode *mode, int doit)
 {
-	int cmode;
+  int cmode;
+  struct ims_crmodevals   *init;
+
+  if (video_mode <= 0 || video_mode > VMODE_MAX )
+		return -EINVAL;
+  if ((init = ims_info.mode[video_mode-1]) == 0)
+		return -EINVAL;
+  if (init->tt[ims_info.dac].vt == 0)
+		return -EINVAL;
 
 	if (mode->mode <= 0 || mode->mode > VMODE_MAX
-	    || imstt_reg_init[mode->mode-1] == 0)
+	    || (ims_info.mode[mode->mode-1] == 0))
 		return -EINVAL;
 	switch (mode->depth) {
 	case 24:
@@ -468,7 +892,7 @@
 	default:
 		return -EINVAL;
 	}
-	if (imstt_vram_reqd(mode->mode, cmode) > total_vram)
+	if (imstt_vram_reqd(mode->mode, cmode) > ims_info.total_vram)
 		return -EINVAL;
 	if (doit) {
 		video_mode = mode->mode;
@@ -478,17 +902,32 @@
 	return 0;
 }
 
+// set palette for TI TVP3030 ramdac (used on 8MB version)
 void
-imstt_set_palette(unsigned char red[], unsigned char green[],
+imstt_set_palette_tvp(unsigned char red[], unsigned char green[],
+		    unsigned char blue[], int index, int ncolors)
+{
+	int i;
+	for (i = 0; i < ncolors; ++i) {
+		ims_info.cmap[TVPADDRW] = index + i;	eieio();
+		ims_info.cmap[TVPPDATA] = red[i];	eieio();
+		ims_info.cmap[TVPPDATA] = green[i];	eieio();
+		ims_info.cmap[TVPPDATA] = blue[i];	eieio();
+	}
+}
+
+// set palette for IBM ramdac (used on 2MB/4MB version)
+void
+imstt_set_palette_ibm(unsigned char red[], unsigned char green[],
 		    unsigned char blue[], int index, int ncolors)
 {
 	int i;
 
 	for (i = 0; i < ncolors; ++i) {
-		cmap_regs[PADDRW] = index + i;	eieio();
-		cmap_regs[PDATA] = red[i];	eieio();
-		cmap_regs[PDATA] = green[i];	eieio();
-		cmap_regs[PDATA] = blue[i];	eieio();
+		ims_info.cmap[PADDRW] = index + i;	eieio();
+		ims_info.cmap[PDATA] = red[i];	eieio();
+		ims_info.cmap[PDATA] = green[i];	eieio();
+		ims_info.cmap[PDATA] = blue[i];	eieio();
 	}
 }
 
@@ -497,10 +936,12 @@
 {
 	long ctrl;
 
-	ctrl = ld_le32(dc_regs + STGCTL) | 0x0030;
+	ctrl = ld_le32(ims_info.dc + STGCTL) | 0x0030;
 	if (blank_mode & VESA_VSYNC_SUSPEND)
 		ctrl &= ~0x0020;
 	if (blank_mode & VESA_HSYNC_SUSPEND)
 		ctrl &= ~0x0010;
-	out_le32(dc_regs + STGCTL, ctrl);
+	out_le32(ims_info.dc + STGCTL, ctrl);
 }
+
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov