Example #1
0
/* The PEG settings have to be set before ASPM is setup on DMI. */
static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
{
	const device_t mch_dev	= PCI_DEV(0, 0, 0);
	const device_t peg_dev	= PCI_DEV(0, 1, 0);
	const device_t igd_dev	= PCI_DEV(0, 2, 0);

	u16 reg16;
	u32 reg32;

	printk(BIOS_DEBUG, "Enabling IGD.\n");

	/* HSync/VSync */
	MCHBAR8(0xbd0 + 3) = 0x5a;
	MCHBAR8(0xbd0 + 4) = 0x5a;

	static const u16 display_clock_from_f0_and_vco[][4] = {
		  /* VCO 2666    VCO 3200    VCO 4000    VCO 5333 */
		{         222,        228,        222,        222,  },
		{         333,        320,        333,        333,  },
	};
	const int f0_12 = (pci_read_config16(igd_dev, 0xf0) >> 12) & 1;
	const int vco = raminit_read_vco_index();
	reg16 = pci_read_config16(igd_dev, 0xcc);
	reg16 &= 0xfc00;
	reg16 |= display_clock_from_f0_and_vco[f0_12][vco];
	pci_write_config16(igd_dev, 0xcc, reg16);

	/* Graphics Stolen Memory: 2MB GTT (0x0300) when VT-d disabled,
	                           2MB GTT + 2MB shadow GTT (0x0b00) else. */
	/* Graphics Mode Select: 32MB framebuffer (0x0050) */
	/* TODO: We could switch to 64MB (0x0070), config flag? */
	const u32 capid = pci_read_config32(mch_dev, D0F0_CAPID0 + 4);
	reg16 = pci_read_config16(mch_dev, D0F0_GGC);
	reg16 &= 0xf00f;
	reg16 |= 0x0350;
	if (capid & (1 << (48 - 32)))
		reg16 |= 0x0800;
	pci_write_config16(mch_dev, D0F0_GGC, reg16);

	if ((sysinfo->gfx_type != GMCH_GL40) &&
			(sysinfo->gfx_type != GMCH_GS40) &&
			(sysinfo->gfx_type != GMCH_GL43)) {
		const u32 deven = pci_read_config32(mch_dev, D0F0_DEVEN);
		if (!(deven & 2))
			/* Enable PEG temporarily to access D1:F0. */
			pci_write_config32(mch_dev, D0F0_DEVEN, deven | 2);

		/* Some IGD related settings on D1:F0. */
		reg16 = pci_read_config16(peg_dev, 0xa08);
		reg16 &= ~(1 << 15);
		pci_write_config16(peg_dev, 0xa08, reg16);

		reg16 = pci_read_config16(peg_dev, 0xa84);
		reg16 |= (1 << 8);
		pci_write_config16(peg_dev, 0xa84, reg16);

		reg16 = pci_read_config16(peg_dev, 0xb00);
		reg16 |= (3 << 8) | (7 << 3);
		pci_write_config16(peg_dev, 0xb00, reg16);

		reg32 = pci_read_config32(peg_dev, 0xb14);
		reg32 &= ~(1 << 17);
		pci_write_config32(peg_dev, 0xb14, reg32);

		if (!(deven & 2) || no_peg) {
			/* Disable PEG finally. */
			printk(BIOS_DEBUG, "Finally disabling "
					   "PEG in favor of IGD.\n");
			MCHBAR8(0xc14) |= (1 << 5) | (1 << 0);

			reg32 = pci_read_config32(peg_dev, 0x200);
			reg32 |= (1 << 18);
			pci_write_config32(peg_dev, 0x200, reg32);
			reg16 = pci_read_config16(peg_dev, 0x224);
			reg16 |= (1 << 8);
			pci_write_config16(peg_dev, 0x224, reg16);
			reg32 = pci_read_config32(peg_dev, 0x200);
			reg32 &= ~(1 << 18);
			pci_write_config32(peg_dev, 0x200, reg32);
			while (pci_read_config32(peg_dev, 0x214) & 0x000f0000);

			pci_write_config32(mch_dev, D0F0_DEVEN, deven & ~2);
			MCHBAR8(0xc14) &= ~((1 << 5) | (1 << 0));
		}
	}
}
Example #2
0
static void init_freq_scaling(const gmch_gfx_t sku, const int low_power_mode)
{
	int i;

	MCHBAR32(0x11cc) = (MCHBAR32(0x11cc) & ~(0x1f)) | 0x17;
	switch (sku) {
	case GMCH_GM45:
	case GMCH_GE45:
	case GMCH_GS45:
	case GMCH_GM47:
	case GMCH_GM49:
		break;
	default:
		/* No more to be done for the others. */
		return;
	}

	static const u32 voltage_mask =
		(0x1f << 24) | (0x1f << 16) | (0x1f << 8) | 0x1f;
	MCHBAR32(0x1120) = (MCHBAR32(0x1120) & ~voltage_mask) | 0x10111213;
	MCHBAR32(0x1124) = (MCHBAR32(0x1124) & ~voltage_mask) | 0x14151617;
	MCHBAR32(0x1128) = (MCHBAR32(0x1128) & ~voltage_mask) | 0x18191a1b;
	MCHBAR32(0x112c) = (MCHBAR32(0x112c) & ~voltage_mask) | 0x1c1d1e1f;
	MCHBAR32(0x1130) = (MCHBAR32(0x1130) & ~voltage_mask) | 0x00010203;
	MCHBAR32(0x1134) = (MCHBAR32(0x1134) & ~voltage_mask) | 0x04050607;
	MCHBAR32(0x1138) = (MCHBAR32(0x1138) & ~voltage_mask) | 0x08090a0b;
	MCHBAR32(0x113c) = (MCHBAR32(0x113c) & ~voltage_mask) | 0x0c0d0e0f;

	/* Program frequencies. */
	static const u32 frequencies_from_sku_vco[][4][8] = {
	/* GM45/GE45/GS45_perf */ {
	    /* VCO 2666 */ { 0xcd, 0xbc, 0x9b, 0x8a, 0x79, 0x78, 0x67, 0x56 },
	    /* VCO 3200 */ { 0xcd, 0xac, 0x9b, 0x8a, 0x89, 0x78, 0x67, 0x56 },
	    /* VCO 4000 */ { 0xac, 0x9b, 0x9a, 0x89, 0x89, 0x68, 0x56, 0x45 },
	    /* VCO 5333 */ { 0xab, 0x9a, 0x79, 0x68, 0x57, 0x56, 0x45, 0x34 },
	},
	/* GS45_low_power */ {
	    /* VCO 2666 */ { 0xcd, 0x8a },
	    /* VCO 3200 */ { 0xcd, 0x89 },
	    /* VCO 4000 */ { 0xac, 0x89 },
	    /* VCO 5333 */ { 0xab, 0x68 },
	},
	/* GM47 */ {
	    /* VCO 2666 */ { 0xcd, 0xcd, 0xbc, 0x9b, 0x79, 0x78, 0x67, 0x56 },
	    /* VCO 3200 */ { 0xde, 0xcd, 0xac, 0x9b, 0x89, 0x78, 0x67, 0x56 },
	    /* VCO 4000 */ { 0xcd, 0xac, 0x9b, 0x9a, 0x89, 0x68, 0x56, 0x45 },
	    /* VCO 5333 */ { 0xac, 0xab, 0x9a, 0x79, 0x68, 0x56, 0x45, 0x34 },
	},
	/* GM49 */ {
	    /* VCO 2666 */ { },
	    /* VCO 3200 */ { 0xef, 0xde, 0xcd, 0xac, 0x89, 0x78, 0x67, 0x56 },
	    /* VCO 4000 */ { 0xef, 0xde, 0xac, 0x9b, 0x89, 0x68, 0x56, 0x45 },
	    /* VCO 5333 */ { 0xce, 0xbd, 0xab, 0x9a, 0x68, 0x57, 0x45, 0x34 },
	}};
	const int sku_index = sku_freq_index(sku, low_power_mode);
	const int vco_index = raminit_read_vco_index();
	const int reg_limit = low_power_mode ? 1 : 4;
	if (sku == GMCH_GM49)
		MCHBAR8(0x1110+3) = 0x1b;
	else
		MCHBAR8(0x1110+3) = 0x17;
	MCHBAR8(0x1110+1) = 0x17;
	if (!low_power_mode) {
		MCHBAR8(0x1114+3) = 0x17;
		MCHBAR8(0x1114+1) = 0x17;
		MCHBAR8(0x1118+3) = 0x17;
		MCHBAR8(0x1118+1) = 0x17;
		MCHBAR8(0x111c+3) = 0x17;
		MCHBAR8(0x111c+1) = 0x17;
	}
	for (i = 0; i < reg_limit; ++i) {
		const int mchbar = 0x1110 + (i * 4);
		MCHBAR8(mchbar + 2) = frequencies_from_sku_vco
					[sku_index][vco_index][i * 2 + 0];
		MCHBAR8(mchbar + 0) = frequencies_from_sku_vco
					[sku_index][vco_index][i * 2 + 1];
	}

	if (low_power_mode) {
		MCHBAR16(0x1190) =
			(MCHBAR16(0x1190) & ~((7 << 8) | (7 << 4) | 7)) |
			(1 << 8) | (1 << 4) | 1;
	} else {
		MCHBAR16(0x1190) =
			(MCHBAR16(0x1190) & ~((7 << 8) | (7 << 4))) | 7;
		if (sku == GMCH_GS45) /* performance mode */
			MCHBAR32(0x0ffc) &= ~(1 << 31);
	}

	MCHBAR16(0x0fc0) |= (1 << 11);
	MCHBAR16(0x11b8) = 0x333c;
	MCHBAR16(0x11c0 + 2) = 0x0303;
	MCHBAR32(0x11c4) = 0x0a030a03;
	MCHBAR16(0x1100) = (MCHBAR16(0x1100) & ~(0x1f << 8)) | (3 << 8);
	MCHBAR16(0x11b8 + 2) = 0x4000;
}
Example #3
0
/* The PEG settings have to be set before ASPM is setup on DMI. */
static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
{
	const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
	const pci_devfn_t peg_dev = PCI_DEV(0, 1, 0);
	const pci_devfn_t igd_dev = PCI_DEV(0, 2, 0);

	u16 reg16;
	u32 reg32;

	printk(BIOS_DEBUG, "Enabling IGD.\n");

	/* HSync/VSync */
	MCHBAR8(0xbd0 + 3) = 0x5a;
	MCHBAR8(0xbd0 + 4) = 0x5a;

	static const u16 display_clock_from_f0_and_vco[][4] = {
		  /* VCO 2666    VCO 3200    VCO 4000    VCO 5333 */
		{         222,        228,        222,        222,  },
		{         333,        320,        333,        333,  },
	};
	const int f0_12 = (pci_read_config16(igd_dev, 0xf0) >> 12) & 1;
	const int vco = raminit_read_vco_index();
	reg16 = pci_read_config16(igd_dev, 0xcc);
	reg16 &= 0xfc00;
	reg16 |= display_clock_from_f0_and_vco[f0_12][vco];
	pci_write_config16(igd_dev, 0xcc, reg16);

	reg16 = pci_read_config16(mch_dev, D0F0_GGC);
	reg16 &= 0xf00f;
	reg16 |= sysinfo->ggc;
	pci_write_config16(mch_dev, D0F0_GGC, reg16);

	if ((sysinfo->gfx_type != GMCH_GL40) &&
			(sysinfo->gfx_type != GMCH_GS40) &&
			(sysinfo->gfx_type != GMCH_GL43)) {
		const u32 deven = pci_read_config32(mch_dev, D0F0_DEVEN);
		if (!(deven & 2))
			/* Enable PEG temporarily to access D1:F0. */
			pci_write_config32(mch_dev, D0F0_DEVEN, deven | 2);

		/* Some IGD related settings on D1:F0. */
		reg16 = pci_read_config16(peg_dev, 0xa08);
		reg16 &= ~(1 << 15);
		pci_write_config16(peg_dev, 0xa08, reg16);

		reg16 = pci_read_config16(peg_dev, 0xa84);
		reg16 |= (1 << 8);
		pci_write_config16(peg_dev, 0xa84, reg16);

		reg16 = pci_read_config16(peg_dev, 0xb00);
		reg16 |= (3 << 8) | (7 << 3);
		pci_write_config16(peg_dev, 0xb00, reg16);

		reg32 = pci_read_config32(peg_dev, 0xb14);
		reg32 &= ~(1 << 17);
		pci_write_config32(peg_dev, 0xb14, reg32);

		if (!(deven & 2) || no_peg) {
			/* Disable PEG finally. */
			printk(BIOS_DEBUG, "Finally disabling "
					   "PEG in favor of IGD.\n");
			MCHBAR8(0xc14) |= (1 << 5) | (1 << 0);

			reg32 = pci_read_config32(peg_dev, 0x200);
			reg32 |= (1 << 18);
			pci_write_config32(peg_dev, 0x200, reg32);
			reg16 = pci_read_config16(peg_dev, 0x224);
			reg16 |= (1 << 8);
			pci_write_config16(peg_dev, 0x224, reg16);
			reg32 = pci_read_config32(peg_dev, 0x200);
			reg32 &= ~(1 << 18);
			pci_write_config32(peg_dev, 0x200, reg32);
			while (pci_read_config32(peg_dev, 0x214) & 0x000f0000);

			pci_write_config32(mch_dev, D0F0_DEVEN, deven & ~2);
			MCHBAR8(0xc14) &= ~((1 << 5) | (1 << 0));
		}
	}
}