Enscript Output

extractedLnx/linux-2.6.38/drivers/video/sis/sis_main.c_sisfb_post_xgi.c

static int __devinit
sisfb_post_xgi(struct pci_dev *pdev)
{
	struct sis_video_info *ivideo = pci_get_drvdata(pdev);
	unsigned char *bios = ivideo->bios_abase;
	struct pci_dev *mypdev = NULL;
	const u8 *ptr, *ptr2;
	u8 v1, v2, v3, v4, v5, reg, ramtype;
	u32 rega, regb, regd;
	int i, j, k, index;
	static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 };
	static const u8 cs76[2] = { 0xa3, 0xfb };
	static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 };
	static const u8 cs158[8] = {
		0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs160[8] = {
		0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs168[8] = {
		0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs128[3 * 8] = {
		0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs148[2 * 8] = {
		0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs31a[8 * 4] = {
		0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs33a[8 * 4] = {
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs45a[8 * 2] = {
		0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs170[7 * 8] = {
		0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs1a8[3 * 8] = {
		0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	static const u8 cs100[2 * 8] = {
		0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
		0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
	};

	/* VGA enable */
	reg = SiS_GetRegByte(SISVGAENABLE) | 0x01;
	SiS_SetRegByte(SISVGAENABLE, reg);

	/* Misc */
	reg = SiS_GetRegByte(SISMISCR) | 0x01;
	SiS_SetRegByte(SISMISCW, reg);

	/* Unlock SR */
	SiS_SetReg(SISSR, 0x05, 0x86);
	reg = SiS_GetReg(SISSR, 0x05);
	if(reg != 0xa1)
		return 0;

	/* Clear some regs */
	for(i = 0; i < 0x22; i++) {
		if(0x06 + i == 0x20) continue;
		SiS_SetReg(SISSR, 0x06 + i, 0x00);
	}
	for(i = 0; i < 0x0b; i++) {
		SiS_SetReg(SISSR, 0x31 + i, 0x00);
	}
	for(i = 0; i < 0x10; i++) {
		SiS_SetReg(SISCR, 0x30 + i, 0x00);
	}

	ptr = cs78;
	if(ivideo->haveXGIROM) {
		ptr = (const u8 *)&bios[0x78];
	}
	for(i = 0; i < 3; i++) {
		SiS_SetReg(SISSR, 0x23 + i, ptr[i]);
	}

	ptr = cs76;
	if(ivideo->haveXGIROM) {
		ptr = (const u8 *)&bios[0x76];
	}
	for(i = 0; i < 2; i++) {
		SiS_SetReg(SISSR, 0x21 + i, ptr[i]);
	}

	v1 = 0x18; v2 = 0x00;
	if(ivideo->haveXGIROM) {
		v1 = bios[0x74];
		v2 = bios[0x75];
	}
	SiS_SetReg(SISSR, 0x07, v1);
	SiS_SetReg(SISSR, 0x11, 0x0f);
	SiS_SetReg(SISSR, 0x1f, v2);
	/* PCI linear mode, RelIO enabled, A0000 decoding disabled */
	SiS_SetReg(SISSR, 0x20, 0x80 | 0x20 | 0x04);
	SiS_SetReg(SISSR, 0x27, 0x74);

	ptr = cs7b;
	if(ivideo->haveXGIROM) {
		ptr = (const u8 *)&bios[0x7b];
	}
	for(i = 0; i < 3; i++) {
		SiS_SetReg(SISSR, 0x31 + i, ptr[i]);
	}

	if(ivideo->chip == XGI_40) {
		if(ivideo->revision_id == 2) {
			SiS_SetRegANDOR(SISSR, 0x3b, 0x3f, 0xc0);
		}
		SiS_SetReg(SISCR, 0x7d, 0xfe);
		SiS_SetReg(SISCR, 0x7e, 0x0f);
	}
	if(ivideo->revision_id == 0) {	/* 40 *and* 20? */
		SiS_SetRegAND(SISCR, 0x58, 0xd7);
		reg = SiS_GetReg(SISCR, 0xcb);
		if(reg & 0x20) {
			SiS_SetRegANDOR(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */
		}
	}

	reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00;
	SiS_SetRegANDOR(SISCR, 0x38, 0x1f, reg);

	if(ivideo->chip == XGI_20) {
		SiS_SetReg(SISSR, 0x36, 0x70);
	} else {
		SiS_SetReg(SISVID, 0x00, 0x86);
		SiS_SetReg(SISVID, 0x32, 0x00);
		SiS_SetReg(SISVID, 0x30, 0x00);
		SiS_SetReg(SISVID, 0x32, 0x01);
		SiS_SetReg(SISVID, 0x30, 0x00);
		SiS_SetRegAND(SISVID, 0x2f, 0xdf);
		SiS_SetRegAND(SISCAP, 0x00, 0x3f);

		SiS_SetReg(SISPART1, 0x2f, 0x01);
		SiS_SetReg(SISPART1, 0x00, 0x00);
		SiS_SetReg(SISPART1, 0x02, bios[0x7e]);
		SiS_SetReg(SISPART1, 0x2e, 0x08);
		SiS_SetRegAND(SISPART1, 0x35, 0x7f);
		SiS_SetRegAND(SISPART1, 0x50, 0xfe);

		reg = SiS_GetReg(SISPART4, 0x00);
		if(reg == 1 || reg == 2) {
			SiS_SetReg(SISPART2, 0x00, 0x1c);
			SiS_SetReg(SISPART4, 0x0d, bios[0x7f]);
			SiS_SetReg(SISPART4, 0x0e, bios[0x80]);
			SiS_SetReg(SISPART4, 0x10, bios[0x81]);
			SiS_SetRegAND(SISPART4, 0x0f, 0x3f);

			reg = SiS_GetReg(SISPART4, 0x01);
			if((reg & 0xf0) >= 0xb0) {
				reg = SiS_GetReg(SISPART4, 0x23);
				if(reg & 0x20) reg |= 0x40;
				SiS_SetReg(SISPART4, 0x23, reg);
				reg = (reg & 0x20) ? 0x02 : 0x00;
				SiS_SetRegANDOR(SISPART1, 0x1e, 0xfd, reg);
			}
		}

		v1 = bios[0x77];

		reg = SiS_GetReg(SISSR, 0x3b);
		if(reg & 0x02) {
			reg = SiS_GetReg(SISSR, 0x3a);
			v2 = (reg & 0x30) >> 3;
			if(!(v2 & 0x04)) v2 ^= 0x02;
			reg = SiS_GetReg(SISSR, 0x39);
			if(reg & 0x80) v2 |= 0x80;
			v2 |= 0x01;

			if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
				pci_dev_put(mypdev);
				if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
					v2 &= 0xf9;
				v2 |= 0x08;
				v1 &= 0xfe;
			} else {
				mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL);
				if(!mypdev)
					mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL);
				if(!mypdev)
					mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL);
				if(mypdev) {
					pci_read_config_dword(mypdev, 0x94, &regd);
					regd &= 0xfffffeff;
					pci_write_config_dword(mypdev, 0x94, regd);
					v1 &= 0xfe;
					pci_dev_put(mypdev);
				} else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
					v1 &= 0xfe;
				} else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
					  sisfb_find_host_bridge(ivideo, pdev, 0x1022) ||
					  sisfb_find_host_bridge(ivideo, pdev, 0x700e) ||
					  sisfb_find_host_bridge(ivideo, pdev, 0x10de)) {
					if((v2 & 0x06) == 4)
						v2 ^= 0x06;
					v2 |= 0x08;
				}
			}
			SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, v2);
		}
		SiS_SetReg(SISSR, 0x22, v1);

		if(ivideo->revision_id == 2) {
			v1 = SiS_GetReg(SISSR, 0x3b);
			v2 = SiS_GetReg(SISSR, 0x3a);
			regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8);
			if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
				SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01);

			if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) {
				/* TODO: set CR5f &0xf1 | 0x01 for version 6570
				 * of nforce 2 ROM
				 */
				if(0)
					SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01);
				pci_dev_put(mypdev);
			}
		}

		v1 = 0x30;
		reg = SiS_GetReg(SISSR, 0x3b);
		v2 = SiS_GetReg(SISCR, 0x5f);
		if((!(reg & 0x02)) && (v2 & 0x0e))
			v1 |= 0x08;
		SiS_SetReg(SISSR, 0x27, v1);

		if(bios[0x64] & 0x01) {
			SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, bios[0x64]);
		}

		v1 = bios[0x4f7];
		pci_read_config_dword(pdev, 0x50, &regd);
		regd = (regd >> 20) & 0x0f;
		if(regd == 1) {
			v1 &= 0xfc;
			SiS_SetRegOR(SISCR, 0x5f, 0x08);
		}
		SiS_SetReg(SISCR, 0x48, v1);

		SiS_SetRegANDOR(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb);
		SiS_SetRegANDOR(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f);
		SiS_SetRegANDOR(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f);
		SiS_SetRegANDOR(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7);
		SiS_SetRegANDOR(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f);
		SiS_SetReg(SISCR, 0x70, bios[0x4fc]);
		SiS_SetRegANDOR(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f);
		SiS_SetReg(SISCR, 0x74, 0xd0);
		SiS_SetRegANDOR(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30);
		SiS_SetRegANDOR(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
		SiS_SetRegANDOR(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
		v1 = bios[0x501];
		if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) {
			v1 = 0xf0;
			pci_dev_put(mypdev);
		}
		SiS_SetReg(SISCR, 0x77, v1);
	}

	/* RAM type */

	regb = 0;	/* ! */

	v1 = 0xff;
	if(ivideo->haveXGIROM) {
		v1 = bios[0x140 + regb];
	}
	SiS_SetReg(SISCR, 0x6d, v1);

	ptr = cs128;
	if(ivideo->haveXGIROM) {
		ptr = (const u8 *)&bios[0x128];
	}
	for(i = 0, j = 0; i < 3; i++, j += 8) {
		SiS_SetReg(SISCR, 0x68 + i, ptr[j + regb]);
	}

	ptr  = cs31a;
	ptr2 = cs33a;
	if(ivideo->haveXGIROM) {
		index = (ivideo->chip == XGI_20) ? 0x31a : 0x3a6;
		ptr  = (const u8 *)&bios[index];
		ptr2 = (const u8 *)&bios[index + 0x20];
	}
	for(i = 0; i < 2; i++) {
		if(i == 0) {
			regd = le32_to_cpu(((u32 *)ptr)[regb]);
			rega = 0x6b;
		} else {
			regd = le32_to_cpu(((u32 *)ptr2)[regb]);
			rega = 0x6e;
		}
		reg = 0x00;
		for(j = 0; j < 16; j++) {
			reg &= 0xf3;
			if(regd & 0x01) reg |= 0x04;
			if(regd & 0x02) reg |= 0x08;
			regd >>= 2;
			SiS_SetReg(SISCR, rega, reg);
			reg = SiS_GetReg(SISCR, rega);
			reg = SiS_GetReg(SISCR, rega);
			reg += 0x10;
		}
	}

	SiS_SetRegAND(SISCR, 0x6e, 0xfc);

	ptr  = NULL;
	if(ivideo->haveXGIROM) {
		index = (ivideo->chip == XGI_20) ? 0x35a : 0x3e6;
		ptr  = (const u8 *)&bios[index];
	}
	for(i = 0; i < 4; i++) {
		SiS_SetRegANDOR(SISCR, 0x6e, 0xfc, i);
		reg = 0x00;
		for(j = 0; j < 2; j++) {
			regd = 0;
			if(ptr) {
				regd = le32_to_cpu(((u32 *)ptr)[regb * 8]);
				ptr += 4;
			}
			/* reg = 0x00; */
			for(k = 0; k < 16; k++) {
				reg &= 0xfc;
				if(regd & 0x01) reg |= 0x01;
				if(regd & 0x02) reg |= 0x02;
				regd >>= 2;
				SiS_SetReg(SISCR, 0x6f, reg);
				reg = SiS_GetReg(SISCR, 0x6f);
				reg = SiS_GetReg(SISCR, 0x6f);
				reg += 0x08;
			}
		}
	}

	ptr  = cs148;
	if(ivideo->haveXGIROM) {
		ptr  = (const u8 *)&bios[0x148];
	}
	for(i = 0, j = 0; i < 2; i++, j += 8) {
		SiS_SetReg(SISCR, 0x80 + i, ptr[j + regb]);
	}

	SiS_SetRegAND(SISCR, 0x89, 0x8f);

	ptr  = cs45a;
	if(ivideo->haveXGIROM) {
		index = (ivideo->chip == XGI_20) ? 0x45a : 0x4e6;
		ptr  = (const u8 *)&bios[index];
	}
	regd = le16_to_cpu(((const u16 *)ptr)[regb]);
	reg = 0x80;
	for(i = 0; i < 5; i++) {
		reg &= 0xfc;
		if(regd & 0x01) reg |= 0x01;
		if(regd & 0x02) reg |= 0x02;
		regd >>= 2;
		SiS_SetReg(SISCR, 0x89, reg);
		reg = SiS_GetReg(SISCR, 0x89);
		reg = SiS_GetReg(SISCR, 0x89);
		reg += 0x10;
	}

	v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13;
	if(ivideo->haveXGIROM) {
		v1 = bios[0x118 + regb];
		v2 = bios[0xf8 + regb];
		v3 = bios[0x120 + regb];
		v4 = bios[0x1ca];
	}
	SiS_SetReg(SISCR, 0x45, v1 & 0x0f);
	SiS_SetReg(SISCR, 0x99, (v1 >> 4) & 0x07);
	SiS_SetRegOR(SISCR, 0x40, v1 & 0x80);
	SiS_SetReg(SISCR, 0x41, v2);

	ptr  = cs170;
	if(ivideo->haveXGIROM) {
		ptr  = (const u8 *)&bios[0x170];
	}
	for(i = 0, j = 0; i < 7; i++, j += 8) {
		SiS_SetReg(SISCR, 0x90 + i, ptr[j + regb]);
	}

	SiS_SetReg(SISCR, 0x59, v3);

	ptr  = cs1a8;
	if(ivideo->haveXGIROM) {
		ptr  = (const u8 *)&bios[0x1a8];
	}
	for(i = 0, j = 0; i < 3; i++, j += 8) {
		SiS_SetReg(SISCR, 0xc3 + i, ptr[j + regb]);
	}

	ptr  = cs100;
	if(ivideo->haveXGIROM) {
		ptr  = (const u8 *)&bios[0x100];
	}
	for(i = 0, j = 0; i < 2; i++, j += 8) {
		SiS_SetReg(SISCR, 0x8a + i, ptr[j + regb]);
	}

	SiS_SetReg(SISCR, 0xcf, v4);

	SiS_SetReg(SISCR, 0x83, 0x09);
	SiS_SetReg(SISCR, 0x87, 0x00);

	if(ivideo->chip == XGI_40) {
		if( (ivideo->revision_id == 1) ||
		    (ivideo->revision_id == 2) ) {
			SiS_SetReg(SISCR, 0x8c, 0x87);
		}
	}

	SiS_SetReg(SISSR, 0x17, 0x00);
	SiS_SetReg(SISSR, 0x1a, 0x87);

	if(ivideo->chip == XGI_20) {
		SiS_SetReg(SISSR, 0x15, 0x00);
		SiS_SetReg(SISSR, 0x1c, 0x00);
	}

	ramtype = 0x00; v1 = 0x10;
	if(ivideo->haveXGIROM) {
		ramtype = bios[0x62];
		v1 = bios[0x1d2];
	}
	if(!(ramtype & 0x80)) {
		if(ivideo->chip == XGI_20) {
			SiS_SetReg(SISCR, 0x97, v1);
			reg = SiS_GetReg(SISCR, 0x97);
			if(reg & 0x10) {
				ramtype = (reg & 0x01) << 1;
			}
		} else {
			reg = SiS_GetReg(SISSR, 0x39);
			ramtype = reg & 0x02;
			if(!(ramtype)) {
				reg = SiS_GetReg(SISSR, 0x3a);
				ramtype = (reg >> 1) & 0x01;
			}
		}
	}
	ramtype &= 0x07;

	regb = 0;	/* ! */

	switch(ramtype) {
	case 0:
		sisfb_post_xgi_setclocks(ivideo, regb);
		if((ivideo->chip == XGI_20) ||
		   (ivideo->revision_id == 1)   ||
		   (ivideo->revision_id == 2)) {
			v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb];
			if(ivideo->haveXGIROM) {
				v1 = bios[regb + 0x158];
				v2 = bios[regb + 0x160];
				v3 = bios[regb + 0x168];
			}
			SiS_SetReg(SISCR, 0x82, v1);
			SiS_SetReg(SISCR, 0x85, v2);
			SiS_SetReg(SISCR, 0x86, v3);
		} else {
			SiS_SetReg(SISCR, 0x82, 0x88);
			SiS_SetReg(SISCR, 0x86, 0x00);
			reg = SiS_GetReg(SISCR, 0x86);
			SiS_SetReg(SISCR, 0x86, 0x88);
			reg = SiS_GetReg(SISCR, 0x86);
			SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]);
			SiS_SetReg(SISCR, 0x82, 0x77);
			SiS_SetReg(SISCR, 0x85, 0x00);
			reg = SiS_GetReg(SISCR, 0x85);
			SiS_SetReg(SISCR, 0x85, 0x88);
			reg = SiS_GetReg(SISCR, 0x85);
			SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]);
			SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]);
		}
		if(ivideo->chip == XGI_40) {
			SiS_SetReg(SISCR, 0x97, 0x00);
		}
		SiS_SetReg(SISCR, 0x98, 0x01);
		SiS_SetReg(SISCR, 0x9a, 0x02);

		SiS_SetReg(SISSR, 0x18, 0x01);
		if((ivideo->chip == XGI_20) ||
		   (ivideo->revision_id == 2)) {
			SiS_SetReg(SISSR, 0x19, 0x40);
		} else {
			SiS_SetReg(SISSR, 0x19, 0x20);
		}
		SiS_SetReg(SISSR, 0x16, 0x00);
		SiS_SetReg(SISSR, 0x16, 0x80);
		if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) {
			sisfb_post_xgi_delay(ivideo, 0x43);
			sisfb_post_xgi_delay(ivideo, 0x43);
			sisfb_post_xgi_delay(ivideo, 0x43);
			SiS_SetReg(SISSR, 0x18, 0x00);
			if((ivideo->chip == XGI_20) ||
			   (ivideo->revision_id == 2)) {
				SiS_SetReg(SISSR, 0x19, 0x40);
			} else {
				SiS_SetReg(SISSR, 0x19, 0x20);
			}
		} else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) {
			/* SiS_SetReg(SISSR, 0x16, 0x0c); */ /* ? */
		}
		SiS_SetReg(SISSR, 0x16, 0x00);
		SiS_SetReg(SISSR, 0x16, 0x80);
		sisfb_post_xgi_delay(ivideo, 4);
		v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83;
		if(ivideo->haveXGIROM) {
			v1 = bios[0xf0];
			index = (ivideo->chip == XGI_20) ? 0x4b2 : 0x53e;
			v2 = bios[index];
			v3 = bios[index + 1];
			v4 = bios[index + 2];
			v5 = bios[index + 3];
		}
		SiS_SetReg(SISSR, 0x18, v1);
		SiS_SetReg(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01));
		SiS_SetReg(SISSR, 0x16, v2);
		SiS_SetReg(SISSR, 0x16, v3);
		sisfb_post_xgi_delay(ivideo, 0x43);
		SiS_SetReg(SISSR, 0x1b, 0x03);
		sisfb_post_xgi_delay(ivideo, 0x22);
		SiS_SetReg(SISSR, 0x18, v1);
		SiS_SetReg(SISSR, 0x19, 0x00);
		SiS_SetReg(SISSR, 0x16, v4);
		SiS_SetReg(SISSR, 0x16, v5);
		SiS_SetReg(SISSR, 0x1b, 0x00);
		break;
	case 1:
		SiS_SetReg(SISCR, 0x82, 0x77);
		SiS_SetReg(SISCR, 0x86, 0x00);
		reg = SiS_GetReg(SISCR, 0x86);
		SiS_SetReg(SISCR, 0x86, 0x88);
		reg = SiS_GetReg(SISCR, 0x86);
		v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
		if(ivideo->haveXGIROM) {
			v1 = bios[regb + 0x168];
			v2 = bios[regb + 0x160];
			v3 = bios[regb + 0x158];
		}
		SiS_SetReg(SISCR, 0x86, v1);
		SiS_SetReg(SISCR, 0x82, 0x77);
		SiS_SetReg(SISCR, 0x85, 0x00);
		reg = SiS_GetReg(SISCR, 0x85);
		SiS_SetReg(SISCR, 0x85, 0x88);
		reg = SiS_GetReg(SISCR, 0x85);
		SiS_SetReg(SISCR, 0x85, v2);
		SiS_SetReg(SISCR, 0x82, v3);
		SiS_SetReg(SISCR, 0x98, 0x01);
		SiS_SetReg(SISCR, 0x9a, 0x02);

		SiS_SetReg(SISSR, 0x28, 0x64);
		SiS_SetReg(SISSR, 0x29, 0x63);
		sisfb_post_xgi_delay(ivideo, 15);
		SiS_SetReg(SISSR, 0x18, 0x00);
		SiS_SetReg(SISSR, 0x19, 0x20);
		SiS_SetReg(SISSR, 0x16, 0x00);
		SiS_SetReg(SISSR, 0x16, 0x80);
		SiS_SetReg(SISSR, 0x18, 0xc5);
		SiS_SetReg(SISSR, 0x19, 0x23);
		SiS_SetReg(SISSR, 0x16, 0x00);
		SiS_SetReg(SISSR, 0x16, 0x80);
		sisfb_post_xgi_delay(ivideo, 1);
		SiS_SetReg(SISCR, 0x97, 0x11);
		sisfb_post_xgi_setclocks(ivideo, regb);
		sisfb_post_xgi_delay(ivideo, 0x46);
		SiS_SetReg(SISSR, 0x18, 0xc5);
		SiS_SetReg(SISSR, 0x19, 0x23);
		SiS_SetReg(SISSR, 0x16, 0x00);
		SiS_SetReg(SISSR, 0x16, 0x80);
		sisfb_post_xgi_delay(ivideo, 1);
		SiS_SetReg(SISSR, 0x1b, 0x04);
		sisfb_post_xgi_delay(ivideo, 1);
		SiS_SetReg(SISSR, 0x1b, 0x00);
		sisfb_post_xgi_delay(ivideo, 1);
		v1 = 0x31;
		if(ivideo->haveXGIROM) {
			v1 = bios[0xf0];
		}
		SiS_SetReg(SISSR, 0x18, v1);
		SiS_SetReg(SISSR, 0x19, 0x06);
		SiS_SetReg(SISSR, 0x16, 0x04);
		SiS_SetReg(SISSR, 0x16, 0x84);
		sisfb_post_xgi_delay(ivideo, 1);
		break;
	default:
		sisfb_post_xgi_setclocks(ivideo, regb);
		if((ivideo->chip == XGI_40) &&
		   ((ivideo->revision_id == 1) ||
		    (ivideo->revision_id == 2))) {
			SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]);
			SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]);
			SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]);
		} else {
			SiS_SetReg(SISCR, 0x82, 0x88);
			SiS_SetReg(SISCR, 0x86, 0x00);
			reg = SiS_GetReg(SISCR, 0x86);
			SiS_SetReg(SISCR, 0x86, 0x88);
			SiS_SetReg(SISCR, 0x82, 0x77);
			SiS_SetReg(SISCR, 0x85, 0x00);
			reg = SiS_GetReg(SISCR, 0x85);
			SiS_SetReg(SISCR, 0x85, 0x88);
			reg = SiS_GetReg(SISCR, 0x85);
			v1 = cs160[regb]; v2 = cs158[regb];
			if(ivideo->haveXGIROM) {
				v1 = bios[regb + 0x160];
				v2 = bios[regb + 0x158];
			}
			SiS_SetReg(SISCR, 0x85, v1);
			SiS_SetReg(SISCR, 0x82, v2);
		}
		if(ivideo->chip == XGI_40) {
			SiS_SetReg(SISCR, 0x97, 0x11);
		}
		if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) {
			SiS_SetReg(SISCR, 0x98, 0x01);
		} else {
			SiS_SetReg(SISCR, 0x98, 0x03);
		}
		SiS_SetReg(SISCR, 0x9a, 0x02);

		if(ivideo->chip == XGI_40) {
			SiS_SetReg(SISSR, 0x18, 0x01);
		} else {
			SiS_SetReg(SISSR, 0x18, 0x00);
		}
		SiS_SetReg(SISSR, 0x19, 0x40);
		SiS_SetReg(SISSR, 0x16, 0x00);
		SiS_SetReg(SISSR, 0x16, 0x80);
		if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) {
			sisfb_post_xgi_delay(ivideo, 0x43);
			sisfb_post_xgi_delay(ivideo, 0x43);
			sisfb_post_xgi_delay(ivideo, 0x43);
			SiS_SetReg(SISSR, 0x18, 0x00);
			SiS_SetReg(SISSR, 0x19, 0x40);
			SiS_SetReg(SISSR, 0x16, 0x00);
			SiS_SetReg(SISSR, 0x16, 0x80);
		}
		sisfb_post_xgi_delay(ivideo, 4);
		v1 = 0x31;
		if(ivideo->haveXGIROM) {
			v1 = bios[0xf0];
		}
		SiS_SetReg(SISSR, 0x18, v1);
		SiS_SetReg(SISSR, 0x19, 0x01);
		if(ivideo->chip == XGI_40) {
			SiS_SetReg(SISSR, 0x16, bios[0x53e]);
			SiS_SetReg(SISSR, 0x16, bios[0x53f]);
		} else {
			SiS_SetReg(SISSR, 0x16, 0x05);
			SiS_SetReg(SISSR, 0x16, 0x85);
		}
		sisfb_post_xgi_delay(ivideo, 0x43);
		if(ivideo->chip == XGI_40) {
			SiS_SetReg(SISSR, 0x1b, 0x01);
		} else {
			SiS_SetReg(SISSR, 0x1b, 0x03);
		}
		sisfb_post_xgi_delay(ivideo, 0x22);
		SiS_SetReg(SISSR, 0x18, v1);
		SiS_SetReg(SISSR, 0x19, 0x00);
		if(ivideo->chip == XGI_40) {
			SiS_SetReg(SISSR, 0x16, bios[0x540]);
			SiS_SetReg(SISSR, 0x16, bios[0x541]);
		} else {
			SiS_SetReg(SISSR, 0x16, 0x05);
			SiS_SetReg(SISSR, 0x16, 0x85);
		}
		SiS_SetReg(SISSR, 0x1b, 0x00);
	}

	regb = 0;	/* ! */
	v1 = 0x03;
	if(ivideo->haveXGIROM) {
		v1 = bios[0x110 + regb];
	}
	SiS_SetReg(SISSR, 0x1b, v1);

	/* RAM size */
	v1 = 0x00; v2 = 0x00;
	if(ivideo->haveXGIROM) {
		v1 = bios[0x62];
		v2 = bios[0x63];
	}
	regb = 0;	/* ! */
	regd = 1 << regb;
	if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) {

		SiS_SetReg(SISSR, 0x13, bios[regb + 0xe0]);
		SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);

	} else {

		/* Set default mode, don't clear screen */
		ivideo->SiS_Pr.SiS_UseOEM = false;
		SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
		SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
		ivideo->curFSTN = ivideo->curDSTN = 0;
		ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
		SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);

		SiS_SetReg(SISSR, 0x05, 0x86);

		/* Disable read-cache */
		SiS_SetRegAND(SISSR, 0x21, 0xdf);
		sisfb_post_xgi_ramsize(ivideo);
		/* Enable read-cache */
		SiS_SetRegOR(SISSR, 0x21, 0x20);

	}

#if 0
	printk(KERN_DEBUG "-----------------\n");
	for(i = 0; i < 0xff; i++) {
		reg = SiS_GetReg(SISCR, i);
		printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg);
	}
	for(i = 0; i < 0x40; i++) {
		reg = SiS_GetReg(SISSR, i);
		printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg);
	}
	printk(KERN_DEBUG "-----------------\n");
#endif

	/* Sense CRT1 */
	if(ivideo->chip == XGI_20) {
		SiS_SetRegOR(SISCR, 0x32, 0x20);
	} else {
		reg = SiS_GetReg(SISPART4, 0x00);
		if((reg == 1) || (reg == 2)) {
			sisfb_sense_crt1(ivideo);
		} else {
			SiS_SetRegOR(SISCR, 0x32, 0x20);
		}
	}

	/* Set default mode, don't clear screen */
	ivideo->SiS_Pr.SiS_UseOEM = false;
	SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
	SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
	ivideo->curFSTN = ivideo->curDSTN = 0;
	SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);

	SiS_SetReg(SISSR, 0x05, 0x86);

	/* Display off */
	SiS_SetRegOR(SISSR, 0x01, 0x20);

	/* Save mode number in CR34 */
	SiS_SetReg(SISCR, 0x34, 0x2e);

	/* Let everyone know what the current mode is */
	ivideo->modeprechange = 0x2e;

	if(ivideo->chip == XGI_40) {
		reg = SiS_GetReg(SISCR, 0xca);
		v1 = SiS_GetReg(SISCR, 0xcc);
		if((reg & 0x10) && (!(v1 & 0x04))) {
			printk(KERN_ERR
				"sisfb: Please connect power to the card.\n");
			return 0;
		}
	}

	return 1;
}

Generated by GNU enscript 1.6.4.