|
|
60a3a4 |
From 64181e8938e1ebb31375bfb5372190a2f3f1ad60 Mon Sep 17 00:00:00 2001
|
|
|
60a3a4 |
From: Marcel Apfelbaum <marcel@redhat.com>
|
|
|
60a3a4 |
Date: Thu, 31 Mar 2016 16:19:03 +0200
|
|
|
60a3a4 |
Subject: [PATCH] fw/pci: add Q35 S3 support
|
|
|
60a3a4 |
|
|
|
60a3a4 |
RH-Author: Marcel Apfelbaum <marcel@redhat.com>
|
|
|
60a3a4 |
Message-id: <1459441143-24378-1-git-send-email-marcel@redhat.com>
|
|
|
60a3a4 |
Patchwork-id: 69965
|
|
|
60a3a4 |
O-Subject: [RHEL-7.3 seabios PATCH] fw/pci: add Q35 S3 support
|
|
|
60a3a4 |
Bugzilla: 1185721
|
|
|
60a3a4 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
60a3a4 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
60a3a4 |
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
60a3a4 |
|
|
|
60a3a4 |
Following the i440fx example, save the LPC, SMBUS and PCIEXBAR bdfs
|
|
|
60a3a4 |
between OS sleeps and use them to re-configure the
|
|
|
60a3a4 |
corresponding registers.
|
|
|
60a3a4 |
|
|
|
60a3a4 |
Tested-by: Gal Hammer <ghammer@redhat.com>
|
|
|
60a3a4 |
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
60a3a4 |
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
|
|
|
60a3a4 |
(cherry picked from commit dce99e01b6bfc51175bdf32612fd4f2738e5c3c8)
|
|
|
60a3a4 |
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
|
|
|
60a3a4 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
60a3a4 |
---
|
|
|
60a3a4 |
src/fw/pciinit.c | 73 +++++++++++++++++++++++++++++++++++++++++++-------------
|
|
|
60a3a4 |
1 file changed, 56 insertions(+), 17 deletions(-)
|
|
|
60a3a4 |
|
|
|
60a3a4 |
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
|
|
|
60a3a4 |
index c31c2fa..7896600 100644
|
|
|
60a3a4 |
--- a/src/fw/pciinit.c
|
|
|
60a3a4 |
+++ b/src/fw/pciinit.c
|
|
|
60a3a4 |
@@ -149,6 +149,22 @@ static void piix_isa_bridge_setup(struct pci_device *pci, void *arg)
|
|
|
60a3a4 |
dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
|
|
|
60a3a4 |
}
|
|
|
60a3a4 |
|
|
|
60a3a4 |
+static void mch_isa_lpc_setup(u16 bdf)
|
|
|
60a3a4 |
+{
|
|
|
60a3a4 |
+ /* pm io base */
|
|
|
60a3a4 |
+ pci_config_writel(bdf, ICH9_LPC_PMBASE,
|
|
|
60a3a4 |
+ acpi_pm_base | ICH9_LPC_PMBASE_RTE);
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+ /* acpi enable, SCI: IRQ9 000b = irq9*/
|
|
|
60a3a4 |
+ pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+ /* set root complex register block BAR */
|
|
|
60a3a4 |
+ pci_config_writel(bdf, ICH9_LPC_RCBA,
|
|
|
60a3a4 |
+ ICH9_LPC_RCBA_ADDR | ICH9_LPC_RCBA_EN);
|
|
|
60a3a4 |
+}
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+static int ICH9LpcBDF = -1;
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
/* ICH9 LPC PCI to ISA bridge */
|
|
|
60a3a4 |
/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
|
|
|
60a3a4 |
static void mch_isa_bridge_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
@@ -176,16 +192,10 @@ static void mch_isa_bridge_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
outb(elcr[1], ICH9_LPC_PORT_ELCR2);
|
|
|
60a3a4 |
dprintf(1, "Q35 LPC init: elcr=%02x %02x\n", elcr[0], elcr[1]);
|
|
|
60a3a4 |
|
|
|
60a3a4 |
- /* pm io base */
|
|
|
60a3a4 |
- pci_config_writel(bdf, ICH9_LPC_PMBASE,
|
|
|
60a3a4 |
- acpi_pm_base | ICH9_LPC_PMBASE_RTE);
|
|
|
60a3a4 |
+ ICH9LpcBDF = bdf;
|
|
|
60a3a4 |
|
|
|
60a3a4 |
- /* acpi enable, SCI: IRQ9 000b = irq9*/
|
|
|
60a3a4 |
- pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
|
|
|
60a3a4 |
+ mch_isa_lpc_setup(bdf);
|
|
|
60a3a4 |
|
|
|
60a3a4 |
- /* set root complex register block BAR */
|
|
|
60a3a4 |
- pci_config_writel(bdf, ICH9_LPC_RCBA,
|
|
|
60a3a4 |
- ICH9_LPC_RCBA_ADDR | ICH9_LPC_RCBA_EN);
|
|
|
60a3a4 |
e820_add(ICH9_LPC_RCBA_ADDR, 16*1024, E820_RESERVED);
|
|
|
60a3a4 |
|
|
|
60a3a4 |
acpi_pm1a_cnt = acpi_pm_base + 0x04;
|
|
|
60a3a4 |
@@ -244,11 +254,8 @@ static void piix4_pm_setup(struct pci_device *pci, void *arg)
|
|
|
60a3a4 |
pmtimer_setup(acpi_pm_base + 0x08);
|
|
|
60a3a4 |
}
|
|
|
60a3a4 |
|
|
|
60a3a4 |
-/* ICH9 SMBUS */
|
|
|
60a3a4 |
-/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
|
|
|
60a3a4 |
-static void ich9_smbus_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
+static void ich9_smbus_enable(u16 bdf)
|
|
|
60a3a4 |
{
|
|
|
60a3a4 |
- u16 bdf = dev->bdf;
|
|
|
60a3a4 |
/* map smbus into io space */
|
|
|
60a3a4 |
pci_config_writel(bdf, ICH9_SMB_SMB_BASE,
|
|
|
60a3a4 |
(acpi_pm_base + 0x100) | PCI_BASE_ADDRESS_SPACE_IO);
|
|
|
60a3a4 |
@@ -257,6 +264,17 @@ static void ich9_smbus_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
pci_config_writeb(bdf, ICH9_SMB_HOSTC, ICH9_SMB_HOSTC_HST_EN);
|
|
|
60a3a4 |
}
|
|
|
60a3a4 |
|
|
|
60a3a4 |
+static int ICH9SmbusBDF = -1;
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+/* ICH9 SMBUS */
|
|
|
60a3a4 |
+/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
|
|
|
60a3a4 |
+static void ich9_smbus_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
+{
|
|
|
60a3a4 |
+ ICH9SmbusBDF = dev->bdf;
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+ ich9_smbus_enable(dev->bdf);
|
|
|
60a3a4 |
+}
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
static const struct pci_device_id pci_device_tbl[] = {
|
|
|
60a3a4 |
/* PIIX3/PIIX4 PCI to ISA bridge */
|
|
|
60a3a4 |
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0,
|
|
|
60a3a4 |
@@ -293,6 +311,9 @@ static const struct pci_device_id pci_device_tbl[] = {
|
|
|
60a3a4 |
PCI_DEVICE_END,
|
|
|
60a3a4 |
};
|
|
|
60a3a4 |
|
|
|
60a3a4 |
+static int MCHMmcfgBDF = -1;
|
|
|
60a3a4 |
+static void mch_mmconfig_setup(u16 bdf);
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
void pci_resume(void)
|
|
|
60a3a4 |
{
|
|
|
60a3a4 |
if (!CONFIG_QEMU) {
|
|
|
60a3a4 |
@@ -302,6 +323,18 @@ void pci_resume(void)
|
|
|
60a3a4 |
if (PiixPmBDF >= 0) {
|
|
|
60a3a4 |
piix4_pm_config_setup(PiixPmBDF);
|
|
|
60a3a4 |
}
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+ if (ICH9LpcBDF >= 0) {
|
|
|
60a3a4 |
+ mch_isa_lpc_setup(ICH9LpcBDF);
|
|
|
60a3a4 |
+ }
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+ if (ICH9SmbusBDF >= 0) {
|
|
|
60a3a4 |
+ ich9_smbus_enable(ICH9SmbusBDF);
|
|
|
60a3a4 |
+ }
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+ if(MCHMmcfgBDF >= 0) {
|
|
|
60a3a4 |
+ mch_mmconfig_setup(MCHMmcfgBDF);
|
|
|
60a3a4 |
+ }
|
|
|
60a3a4 |
}
|
|
|
60a3a4 |
|
|
|
60a3a4 |
static void pci_bios_init_device(struct pci_device *pci)
|
|
|
60a3a4 |
@@ -388,18 +421,24 @@ static void i440fx_mem_addr_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
pci_slot_get_irq = piix_pci_slot_get_irq;
|
|
|
60a3a4 |
}
|
|
|
60a3a4 |
|
|
|
60a3a4 |
-static void mch_mem_addr_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
+static void mch_mmconfig_setup(u16 bdf)
|
|
|
60a3a4 |
{
|
|
|
60a3a4 |
u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
|
|
|
60a3a4 |
- u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
|
|
|
60a3a4 |
-
|
|
|
60a3a4 |
- /* setup mmconfig */
|
|
|
60a3a4 |
- u16 bdf = dev->bdf;
|
|
|
60a3a4 |
u32 upper = addr >> 32;
|
|
|
60a3a4 |
u32 lower = (addr & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN;
|
|
|
60a3a4 |
pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0);
|
|
|
60a3a4 |
pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
|
|
|
60a3a4 |
pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower);
|
|
|
60a3a4 |
+}
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+static void mch_mem_addr_setup(struct pci_device *dev, void *arg)
|
|
|
60a3a4 |
+{
|
|
|
60a3a4 |
+ u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
|
|
|
60a3a4 |
+ u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
|
|
|
60a3a4 |
+
|
|
|
60a3a4 |
+ /* setup mmconfig */
|
|
|
60a3a4 |
+ MCHMmcfgBDF = dev->bdf;
|
|
|
60a3a4 |
+ mch_mmconfig_setup(dev->bdf);
|
|
|
60a3a4 |
e820_add(addr, size, E820_RESERVED);
|
|
|
60a3a4 |
|
|
|
60a3a4 |
/* setup pci i/o window (above mmconfig) */
|
|
|
60a3a4 |
--
|
|
|
60a3a4 |
1.8.3.1
|
|
|
60a3a4 |
|