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, ®d);
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, ®d);
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.