Пример #1
0
static void
VirgeWaitIdleEmpty()
{
	// Wait until GP is idle and queue is empty.

	if(gInfo.sharedInfo->chipType == S3_TRIO_3D)
		while ((IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) != 0x20002000);
	else
		while ((IN_SUBSYS_STAT() & 0x3f00) != 0x3000);
}
Пример #2
0
static void
Virge_NopAllCmdSets()
{
	// This function should be called only for the Trio 3D chip.

	for (int i = 0; i < 1000; i++) {
		if ( (IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) == 0x20002000) {
			break;
		}
	}

	gInfo.WaitQueue(7);
	WriteReg32(CMD_SET, CMD_NOP);
}
Пример #3
0
static void
Virge_GEReset(const DisplayModeEx& mode)
{
	SharedInfo& si = *gInfo.sharedInfo;

	if (si.chipType == S3_TRIO_3D)
		Virge_NopAllCmdSets();

	gInfo.WaitIdleEmpty();

	if (si.chipType == S3_TRIO_3D) {
		bool ge_was_on = false;
		snooze(10000);

		for (int r = 1; r < 10; r++) {
			uint8  resetidx = 0x66;

			VerticalRetraceWait();
			uint8 tmp = ReadCrtcReg(resetidx);

			VerticalRetraceWait();
			IN_SUBSYS_STAT();

			// turn off the GE

			if (tmp & 0x01) {
				WriteCrtcReg(resetidx, tmp);
				ge_was_on = true;
				snooze(10000);
			}

			IN_SUBSYS_STAT();
			WriteCrtcReg(resetidx, tmp | 0x02);
			snooze(10000);

			VerticalRetraceWait();
			WriteCrtcReg(resetidx, tmp & ~0x02);
			snooze(10000);

			if (ge_was_on) {
				tmp |= 0x01;
				WriteCrtcReg(resetidx, tmp);
				snooze(10000);
			}

			VerticalRetraceWait();

			Virge_NopAllCmdSets();
			gInfo.WaitIdleEmpty();

			WriteReg32(DEST_SRC_STR, mode.bytesPerRow << 16 | mode.bytesPerRow);
			snooze(10000);

			if ((IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) != 0x20002000) {
				TRACE("Restarting S3 graphics engine reset %2d ...%lx\n",
					   r, IN_SUBSYS_STAT() );
			} else
				break;
		}
	} else {
		uint8 regIndex = (si.chipType == S3_VIRGE_VX ? 0x63 : 0x66);
		uint8 tmp = ReadCrtcReg(regIndex);
		snooze(10000);

		// try multiple times to avoid lockup of VIRGE/MX

		for (int r = 1; r < 10; r++) {
			WriteCrtcReg(regIndex, tmp | 0x02);
			snooze(10000);
			WriteCrtcReg(regIndex, tmp & ~0x02);
			snooze(10000);
			gInfo.WaitIdleEmpty();

			WriteReg32(DEST_SRC_STR, mode.bytesPerRow << 16 | mode.bytesPerRow);
			snooze(10000);

			if (((IN_SUBSYS_STAT() & 0x3f00) != 0x3000)) {
				TRACE("Restarting S3 graphics engine reset %2d ...\n", r);
			} else
				break;
		}
	}

	gInfo.WaitQueue(2);
	WriteReg32(SRC_BASE, 0);
	WriteReg32(DEST_BASE, 0);

	gInfo.WaitQueue(4);
	WriteReg32(CLIP_L_R, ((0) << 16) | mode.timing.h_display);
	WriteReg32(CLIP_T_B, ((0) << 16) | mode.timing.v_display);
	WriteReg32(MONO_PAT_0, ~0);
	WriteReg32(MONO_PAT_1, ~0);

	if (si.chipType == S3_TRIO_3D)
		Virge_NopAllCmdSets();
}
Пример #4
0
static inline void WaitForSync()
{
	while ((IN_SUBSYS_STAT() & 0x2000) == 0) ;
}