static void sisfb_post_sis300()

in fbdev/sis/sis_main.c [4347:4553]


static void sisfb_post_sis300(struct pci_dev *pdev)
{
	struct sis_video_info *ivideo = pci_get_drvdata(pdev);
	unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase;
	u8  reg, v1, v2, v3, v4, v5, v6, v7, v8;
	u16 index, rindex, memtype = 0;
	unsigned int mapsize;

	if(!ivideo->SiS_Pr.UseROM)
		bios = NULL;

	SiS_SetReg(SISSR, 0x05, 0x86);

	if(bios) {
		if(bios[0x52] & 0x80) {
			memtype = bios[0x52];
		} else {
			memtype = SiS_GetReg(SISSR, 0x3a);
		}
		memtype &= 0x07;
	}

	v3 = 0x80; v6 = 0x80;
	if(ivideo->revision_id <= 0x13) {
		v1 = 0x44; v2 = 0x42;
		v4 = 0x44; v5 = 0x42;
	} else {
		v1 = 0x68; v2 = 0x43; /* Assume 125Mhz MCLK */
		v4 = 0x68; v5 = 0x43; /* Assume 125Mhz ECLK */
		if(bios) {
			index = memtype * 5;
			rindex = index + 0x54;
			v1 = bios[rindex++];
			v2 = bios[rindex++];
			v3 = bios[rindex++];
			rindex = index + 0x7c;
			v4 = bios[rindex++];
			v5 = bios[rindex++];
			v6 = bios[rindex++];
		}
	}
	SiS_SetReg(SISSR, 0x28, v1);
	SiS_SetReg(SISSR, 0x29, v2);
	SiS_SetReg(SISSR, 0x2a, v3);
	SiS_SetReg(SISSR, 0x2e, v4);
	SiS_SetReg(SISSR, 0x2f, v5);
	SiS_SetReg(SISSR, 0x30, v6);

	v1 = 0x10;
	if(bios)
		v1 = bios[0xa4];
	SiS_SetReg(SISSR, 0x07, v1);       /* DAC speed */

	SiS_SetReg(SISSR, 0x11, 0x0f);     /* DDC, power save */

	v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
	v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
	if(bios) {
		memtype += 0xa5;
		v1 = bios[memtype];
		v2 = bios[memtype + 8];
		v3 = bios[memtype + 16];
		v4 = bios[memtype + 24];
		v5 = bios[memtype + 32];
		v6 = bios[memtype + 40];
		v7 = bios[memtype + 48];
		v8 = bios[memtype + 56];
	}
	if(ivideo->revision_id >= 0x80)
		v3 &= 0xfd;
	SiS_SetReg(SISSR, 0x15, v1);       /* Ram type (assuming 0, BIOS 0xa5 step 8) */
	SiS_SetReg(SISSR, 0x16, v2);
	SiS_SetReg(SISSR, 0x17, v3);
	SiS_SetReg(SISSR, 0x18, v4);
	SiS_SetReg(SISSR, 0x19, v5);
	SiS_SetReg(SISSR, 0x1a, v6);
	SiS_SetReg(SISSR, 0x1b, v7);
	SiS_SetReg(SISSR, 0x1c, v8);	   /* ---- */
	SiS_SetRegAND(SISSR, 0x15, 0xfb);
	SiS_SetRegOR(SISSR, 0x15, 0x04);
	if(bios) {
		if(bios[0x53] & 0x02) {
			SiS_SetRegOR(SISSR, 0x19, 0x20);
		}
	}
	v1 = 0x04;			   /* DAC pedestal (BIOS 0xe5) */
	if(ivideo->revision_id >= 0x80)
		v1 |= 0x01;
	SiS_SetReg(SISSR, 0x1f, v1);
	SiS_SetReg(SISSR, 0x20, 0xa4);     /* linear & relocated io & disable a0000 */
	v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
	if(bios) {
		v1 = bios[0xe8];
		v2 = bios[0xe9];
		v3 = bios[0xea];
	}
	SiS_SetReg(SISSR, 0x23, v1);
	SiS_SetReg(SISSR, 0x24, v2);
	SiS_SetReg(SISSR, 0x25, v3);
	SiS_SetReg(SISSR, 0x21, 0x84);
	SiS_SetReg(SISSR, 0x22, 0x00);
	SiS_SetReg(SISCR, 0x37, 0x00);
	SiS_SetRegOR(SISPART1, 0x24, 0x01);   /* unlock crt2 */
	SiS_SetReg(SISPART1, 0x00, 0x00);
	v1 = 0x40; v2 = 0x11;
	if(bios) {
		v1 = bios[0xec];
		v2 = bios[0xeb];
	}
	SiS_SetReg(SISPART1, 0x02, v1);

	if(ivideo->revision_id >= 0x80)
		v2 &= ~0x01;

	reg = SiS_GetReg(SISPART4, 0x00);
	if((reg == 1) || (reg == 2)) {
		SiS_SetReg(SISCR, 0x37, 0x02);
		SiS_SetReg(SISPART2, 0x00, 0x1c);
		v4 = 0x00; v5 = 0x00; v6 = 0x10;
		if(ivideo->SiS_Pr.UseROM) {
			v4 = bios[0xf5];
			v5 = bios[0xf6];
			v6 = bios[0xf7];
		}
		SiS_SetReg(SISPART4, 0x0d, v4);
		SiS_SetReg(SISPART4, 0x0e, v5);
		SiS_SetReg(SISPART4, 0x10, v6);
		SiS_SetReg(SISPART4, 0x0f, 0x3f);
		reg = SiS_GetReg(SISPART4, 0x01);
		if(reg >= 0xb0) {
			reg = SiS_GetReg(SISPART4, 0x23);
			reg &= 0x20;
			reg <<= 1;
			SiS_SetReg(SISPART4, 0x23, reg);
		}
	} else {
		v2 &= ~0x10;
	}
	SiS_SetReg(SISSR, 0x32, v2);

	SiS_SetRegAND(SISPART1, 0x24, 0xfe);  /* Lock CRT2 */

	reg = SiS_GetReg(SISSR, 0x16);
	reg &= 0xc3;
	SiS_SetReg(SISCR, 0x35, reg);
	SiS_SetReg(SISCR, 0x83, 0x00);
#if !defined(__i386__) && !defined(__x86_64__)
	if(sisfb_videoram) {
		SiS_SetReg(SISSR, 0x13, 0x28);  /* ? */
		reg = ((sisfb_videoram >> 10) - 1) | 0x40;
		SiS_SetReg(SISSR, 0x14, reg);
	} else {
#endif
		/* Need to map max FB size for finding out about RAM size */
		mapsize = ivideo->video_size;
		sisfb_post_map_vram(ivideo, &mapsize, 4);

		if(ivideo->video_vbase) {
			sisfb_post_300_ramsize(pdev, mapsize);
			iounmap(ivideo->video_vbase);
		} else {
			printk(KERN_DEBUG
				"sisfb: Failed to map memory for size detection, assuming 8MB\n");
			SiS_SetReg(SISSR, 0x13, 0x28);  /* ? */
			SiS_SetReg(SISSR, 0x14, 0x47);  /* 8MB, 64bit default */
		}
#if !defined(__i386__) && !defined(__x86_64__)
	}
#endif
	if(bios) {
		v1 = bios[0xe6];
		v2 = bios[0xe7];
	} else {
		reg = SiS_GetReg(SISSR, 0x3a);
		if((reg & 0x30) == 0x30) {
			v1 = 0x04; /* PCI */
			v2 = 0x92;
		} else {
			v1 = 0x14; /* AGP */
			v2 = 0xb2;
		}
	}
	SiS_SetReg(SISSR, 0x21, v1);
	SiS_SetReg(SISSR, 0x22, v2);

	/* Sense CRT1 */
	sisfb_sense_crt1(ivideo);

	/* 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);

	/* 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;
}