コード例 #1
0
static void lpc_init(struct device *dev)
{
	printk(BIOS_DEBUG, "i82801ix: lpc_init\n");

	/* Set the value for PCI command register. */
	pci_write_config16(dev, PCI_COMMAND, 0x000f);

	/* IO APIC initialization. */
	i82801ix_enable_apic(dev);

	i82801ix_enable_serial_irqs(dev);

	/* Setup the PIRQ. */
	i82801ix_pirq_init(dev);

	/* Setup power options. */
	i82801ix_power_options(dev);

	/* Configure Cx state registers */
	if (LPC_IS_MOBILE(dev))
		i82801ix_configure_cstates(dev);

	/* Initialize the real time clock. */
	i82801ix_rtc_init(dev);

	/* Initialize ISA DMA. */
	isa_dma_init();

	/* Initialize the High Precision Event Timers, if present. */
	enable_hpet();

	/* Initialize Clock Gating */
	enable_clock_gating();

	setup_i8259();

	/* The OS should do this? */
	/* Interrupt 9 should be level triggered (SCI) */
	i8259_configure_irq_trigger(9, 1);

#if CONFIG_HAVE_SMI_HANDLER
	i82801ix_lock_smm(dev);
#endif
}
コード例 #2
0
ファイル: i82801ix.c プロジェクト: andy737/firebrickRemote
static void i82801ix_pcie_init(const config_t *const info)
{
	device_t pciePort[6];
	int i, slot_number = 1; /* Reserve slot number 0 for nb's PEG. */
	u32 reg32;

	/* PCIe - BIOS must program... */
	for (i = 0; i < 6; ++i) {
		pciePort[i] = dev_find_slot(0, PCI_DEVFN(0x1c, i));
		if (!pciePort[i]) {
			printk(BIOS_EMERG, "PCIe port 00:1c.%x", i);
			die(" is not listed in devicetree.\n");
		}
#if CONFIG_MMCONF_SUPPORT
		reg32 = pci_mmio_read_config32(pciePort[i], 0x300);
		pci_mmio_write_config32(pciePort[i], 0x300, reg32 | (1 << 21));
		pci_mmio_write_config8(pciePort[i], 0x324, 0x40);
#else
#error "MMIO needed for ICH9 PCIe"
#endif
	}

	if (LPC_IS_MOBILE(dev_find_slot(0, PCI_DEVFN(0x1f, 0)))) {
		for (i = 0; i < 6; ++i) {
			if (pciePort[i]->enabled) {
				reg32 = pci_read_config32(pciePort[i], 0xe8);
				reg32 |= 1;
				pci_write_config32(pciePort[i], 0xe8, reg32);
			}
		}
	}

	for (i = 5; (i >= 0) && !pciePort[i]->enabled; --i) {
		/* Only for the top disabled ports. */
#if CONFIG_MMCONF_SUPPORT
		reg32 = pci_mmio_read_config32(pciePort[i], 0x300);
		reg32 |= 0x3 << 16;
		pci_mmio_write_config32(pciePort[i], 0x300, reg32);
#else
#error "MMIO needed for ICH9 PCIe"
#endif
	}

	/* Set slot implemented, slot number and slot power limits. */
	for (i = 0; i < 6; ++i) {
		const device_t dev = pciePort[i];
		u32 xcap = pci_read_config32(dev, D28Fx_XCAP);
		if (info->pcie_slot_implemented & (1 << i))
			xcap |=  PCI_EXP_FLAGS_SLOT;
		else
			xcap &= ~PCI_EXP_FLAGS_SLOT;
		pci_write_config32(dev, D28Fx_XCAP, xcap);

		if (info->pcie_slot_implemented & (1 << i)) {
			u32 slcap = pci_read_config32(dev, D28Fx_SLCAP);
			slcap &= ~(0x1fff << 19);
			slcap |=  (slot_number++ << 19);
			slcap &= ~(0x0003 << 16);
			slcap |=  (info->pcie_power_limits[i].scale << 16);
			slcap &= ~(0x00ff <<  7);
			slcap |=  (info->pcie_power_limits[i].value <<  7);
			pci_write_config32(dev, D28Fx_SLCAP, slcap);
		}
	}

	/* Lock R/WO ASPM support bits. */
	for (i = 0; i < 6; ++i) {
		reg32 = pci_read_config32(pciePort[i], 0x4c);
		pci_write_config32(pciePort[i], 0x4c, reg32);
	}
}
コード例 #3
0
ファイル: pcie.c プロジェクト: RafaelRMachado/Coreboot
static void setup_aspm(const stepping_t stepping, const int peg_enabled)
{
	u32 tmp32;
	const device_t pciex = PCI_DEV(0, 1, 0);

	/* Prerequisites for ASPM: */
	if (peg_enabled) {
		tmp32 = pci_read_config32(pciex, 0x200) | (3 << 13);
		pci_write_config32(pciex, 0x200, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0f0);
		tmp32 &= ~((1 << 27) | (1 << 26));
		pci_write_config32(pciex, 0x0f0, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0f0) | (3 << 24);
		pci_write_config32(pciex, 0x0f0, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0f4) & ~(1 << 4);
		pci_write_config32(pciex, 0x0f4, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0fc) | (1 << 0);
		pci_write_config32(pciex, 0x0fc, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0fc) | (1 << 1);
		pci_write_config32(pciex, 0x0fc, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0fc) | (1 << 4);
		pci_write_config32(pciex, 0x0fc, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0fc) & ~(7 << 5);
		pci_write_config32(pciex, 0x0fc, tmp32);

		/* Set L0s, L1 supported in LCTL? */
		tmp32 = pci_read_config32(pciex, 0x0b0) | (3 << 0);
		pci_write_config32(pciex, 0x0b0, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0f0) | (3 << 24);
		pci_write_config32(pciex, 0x0f0, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0f0);
		if ((stepping >= STEPPING_B0) && (stepping <= STEPPING_B1))
			tmp32 |= (1 << 31);
		else if (stepping >= STEPPING_B2)
			tmp32 &= ~(1 << 31);
		pci_write_config32(pciex, 0x0f0, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0fc);
		if ((stepping >= STEPPING_B0) && (stepping <= STEPPING_B1))
			tmp32 |= (1 << 10);
		else if (stepping >= STEPPING_B2)
			tmp32 &= ~(1 << 10);
		pci_write_config32(pciex, 0x0fc, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0fc);
		if (stepping >= STEPPING_B2)
			tmp32 |= (1 << 14);
		pci_write_config32(pciex, 0x0fc, tmp32);

		tmp32 = pci_read_config32(pciex, 0x0fc);
		if (stepping >= STEPPING_B1)
			tmp32 &= ~(1 << 13);
		pci_write_config32(pciex, 0x0fc, tmp32);
	}
	DMIBAR8 (0x0e1c) |= (1 <<  0);
	DMIBAR16(0x0f00) |= (3 <<  8);
	DMIBAR16(0x0f00) |= (7 <<  3);
	DMIBAR32(0x0f14) &= ~(1 << 17);
	DMIBAR16(0x0e1c) &= ~(1 <<  8);
	if (stepping >= STEPPING_B0) {
		DMIBAR32(0x0e28 + 4) = (DMIBAR32(0x0e28 + 4) &
						~(0xf << (52 - 32))) |
					(0xd << (52 - 32));
		DMIBAR32(0x0e2c) = 0x88d07333;
	}
	if (peg_enabled) {
		tmp32 = pci_read_config32(pciex, 0xa08) & ~(1 << 15);
		pci_write_config32(pciex, 0xa08, tmp32);

		tmp32 = pci_read_config32(pciex, 0xa84) | (1 << 8);
		pci_write_config32(pciex, 0xa84, tmp32);

		tmp32 = pci_read_config32(pciex, 0xb14) & ~(1 << 17);
		pci_write_config32(pciex, 0xb14, tmp32);

		tmp32 = pci_read_config32(pciex, 0xb00) | (3 << 8);
		pci_write_config32(pciex, 0xb00, tmp32);

		tmp32 = pci_read_config32(pciex, 0xb00) | (7 << 3);
		pci_write_config32(pciex, 0xb00, tmp32);

		tmp32 = pci_read_config32(pciex, 0xa84) & ~(1 << 8);
		pci_write_config32(pciex, 0xa84, tmp32);

		tmp32 = pci_read_config32(pciex, 0xa84) | (1 << 8);
		pci_write_config32(pciex, 0xa84, tmp32);

		tmp32 = pci_read_config32(pciex, 0xb04);
		tmp32 = (tmp32 & ~(0x1f << 23)) | (0xe << 23);
		pci_write_config32(pciex, 0xb04, tmp32);

		tmp32 = pci_read_config32(pciex, 0xb04);
		tmp32 |= (1 << 31);
		pci_write_config32(pciex, 0xb04, tmp32);

		tmp32 = pci_read_config32(pciex, 0xb04);
		tmp32 = (tmp32 & ~(0x03 << 29)) | (0x1 << 29);
		pci_write_config32(pciex, 0xb04, tmp32);
	}


	/*\ Setup ASPM on DMI \*/

	/* Exit latencies should be checked to be supported by
	   the endpoint (ICH), but ICH doesn't give any limits. */

	if (LPC_IS_MOBILE(PCI_DEV(0, 0x1f, 0)))
		DMIBAR8(0x88) |= (3 << 0); // enable ASPM L0s, L1 (write-once)
	else
		DMIBAR8(0x88) |= (1 << 0); // enable ASPM L0s (write-once)
	/* timing */
	DMIBAR32(0x84) = (DMIBAR32(0x84) & ~(63 << 12)) | (2 << 12) | (2 << 15);
	DMIBAR8(0x208 + 3) = 0;
	DMIBAR32(0x208) &= ~(3 << 20);


	/*\ Setup ASPM on PEG \*/
	/*
	 * Maybe we just have to advertise ASPM through LCAP[11:10]
	 * (LCAP[17:15] == 010b is the default, will be locked, as it's R/WO),
	 * set 0x208[31:24,23:22] to zero, 0x224[24:21] = 1 and let the
	 * generic ASPM code do the rest? – Nico
	 */
	/* TODO: Prepare PEG for ASPM. */
}