diff options
author | Mike Loptien <mike.loptien@se-eng.com> | 2014-06-06 15:16:29 -0600 |
---|---|---|
committer | Mike Loptien <mike.loptien@se-eng.com> | 2014-06-11 17:07:50 +0200 |
commit | c93a75a5ab067f86104028b74d92fc54cb939cd5 (patch) | |
tree | 8f91538cc2b45d7df3d049c443d66e8617c6a641 /src/southbridge/amd/cimx/sb800 | |
parent | ce740c474c3590dcb0da184d7663adf1f1d78ea8 (diff) |
AMD/CIMx: Add functions for AMD PCI IRQ routing
The PCI_INTR table is an Index/Data pair of I/O ports
0xC00 and 0xC01. This table is responsible for physically
routing IRQs to the PIC and IOAPIC. The settings given
in this table are chipset and mainboard dependent, so the
table values will reside in the mainboard.c file. This
allows for a system to uniquely set its IRQ routing.
The function to write the PCI_INTR table resides in
cimx_util.c because the indices into the table have
the same definitions for all SBx00 FCH chipsets.
The next piece is a function that will read the PCI_INTR
table and program the INT_LINE and INT_PIN registers in
PCI config space appropriately. This function will read
a devices' INT_PIN register, which is always hardcoded to
a value if it uses hardware interrupts. It then uses this
value, along with the device and function numbers to
determine an index into the PCI_INTR table. It will read
the table and program the corresponding value into the PCI
config space register 0x3C, INT_LINE. Finally, it will set
this IRQ number to LEVEL_TRIGGERED on the PIC because it is
a PCI device interrupt and the must be level triggered.
For example, the SB800 USB EHCI device 0:18.2 has an INT_PIN
value hardcoded to 2. This corresponds to PIN B. On the
Persimmon mainboard, I want the USB device to use IRQ 11. I
will program the PCI_INTR table at index 0x31 (this USB device
index) to 11. This function will then read the INT_PIN register,
read the PCI_INTR table, and then program the INT_LINE register
with the value it read. It will then set the IRQ on the PIC to
LEVEL_TRIGGERED by writing a 1 to I/O port 0x4D1 at bit position 4.
Also, the SB700 has slightly different register definitions than
the newer SB800 and SB900 so it needs its own set of #defines for
the pci_intr registers.
Only the Persimmon mainboard is adapted to this change as an
example for other mainboards.
Change-Id: I6de858289a17fa1e1abacf6328ea5099be74b1d6
Signed-off-by: Mike Loptien <mike.loptien@se-eng.com>
Reviewed-on: http://review.coreboot.org/5877
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
Diffstat (limited to 'src/southbridge/amd/cimx/sb800')
-rw-r--r-- | src/southbridge/amd/cimx/sb800/late.c | 25 | ||||
-rw-r--r-- | src/southbridge/amd/cimx/sb800/pci_devs.h | 105 |
2 files changed, 130 insertions, 0 deletions
diff --git a/src/southbridge/amd/cimx/sb800/late.c b/src/southbridge/amd/cimx/sb800/late.c index 40b422bc83..f4c5fd44e2 100644 --- a/src/southbridge/amd/cimx/sb800/late.c +++ b/src/southbridge/amd/cimx/sb800/late.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2011 Advanced Micro Devices, Inc. + * Copyright (C) 2014 Sage Electronic Engineering, LLC. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +22,7 @@ #include <device/device.h> /* device_t */ #include <device/pci.h> /* device_operations */ #include <device/pci_ids.h> +#include <bootstate.h> #include <arch/ioapic.h> #include <device/smbus.h> /* smbus_bus_operations */ #include <pc80/mc146818rtc.h> @@ -36,6 +38,7 @@ #include "sb_cimx.h" /* AMD CIMX wrapper entries */ #include "smbus.h" #include "fan.h" +#include <southbridge/amd/cimx/cimx_util.h> /*implement in mainboard.c*/ void set_pcie_reset(void); @@ -331,6 +334,28 @@ void sb_After_Pci_Restore_Init(void) AmdSbDispatcher(sb_config); } +/* + * Update the PCI devices with a valid IRQ number + * that is set in the mainboard PCI_IRQ structures. + */ +static void set_pci_irqs(void *unused) +{ + /* Write PCI_INTR regs 0xC00/0xC01 */ + write_pci_int_table(); + + /* Write IRQs for all devicetree enabled devices */ + write_pci_cfg_irqs(); +} + +/* + * Hook this function into the PCI state machine + * on entry into BS_DEV_ENABLE. + */ +BOOT_STATE_INIT_ENTRIES(pci_irq_update) = { + BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, + set_pci_irqs, NULL), +}; + /** * @brief SB Cimx entry point sbBeforePciInit wrapper */ diff --git a/src/southbridge/amd/cimx/sb800/pci_devs.h b/src/southbridge/amd/cimx/sb800/pci_devs.h new file mode 100644 index 0000000000..1ecff314b4 --- /dev/null +++ b/src/southbridge/amd/cimx/sb800/pci_devs.h @@ -0,0 +1,105 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CIMX_SB00_PCI_DEVS_H_ +#define _CIMX_SB00_PCI_DEVS_H_ + +#define BUS0 0 + +/* SATA */ +#define SATA_DEV 0x11 +#define SATA_FUNC 0 +# define SATA_IDE_DEVID 0x4390 +# define AHCI_DEVID 0x4391 +# define RAID_DEVID 0x4392 +# define RAID5_DEVID 0x4393 +# define SATA_DEVFN PCI_DEVFN(SATA_DEV,SATA_FUNC) + +/* OHCI */ +#define OHCI1_DEV 0x12 +#define OHCI1_FUNC 0 +#define OHCI2_DEV 0x13 +#define OHCI2_FUNC 0 +#define OHCI3_DEV 0x16 +#define OHCI3_FUNC 0 +#define OHCI4_DEV 0x14 +#define OHCI4_FUNC 5 +# define OHCI_DEVID 0x4397 +# define OHCI1_DEVFN PCI_DEVFN(OHCI1_DEV,OHCI1_FUNC) +# define OHCI2_DEVFN PCI_DEVFN(OHCI2_DEV,OHCI2_FUNC) +# define OHCI3_DEVFN PCI_DEVFN(OHCI3_DEV,OHCI3_FUNC) +# define OHCI4_DEVFN PCI_DEVFN(OHCI4_DEV,OHCI4_FUNC) + +/* EHCI */ +#define EHCI1_DEV 0x12 +#define EHCI1_FUNC 2 +#define EHCI2_DEV 0x13 +#define EHCI2_FUNC 2 +#define EHCI3_DEV 0x16 +#define EHCI3_FUNC 2 +# define EHCI_DEVID 0x4396 +# define EHCI1_DEVFN PCI_DEVFN(EHCI1_DEV,EHCI1_FUNC) +# define EHCI2_DEVFN PCI_DEVFN(EHCI2_DEV,EHCI2_FUNC) +# define EHCI3_DEVFN PCI_DEVFN(EHCI3_DEV,EHCI3_FUNC) + +/* IDE */ +#define IDE_DEV 0x14 +#define IDE_FUNC 1 +# define IDE_DEVID 0x439C +# define IDE_DEVFN PCI_DEVFN(IDE_DEV,IDE_FUNC) + +/* HD Audio */ +#define HDA_DEV 0x14 +#define HDA_FUNC 2 +# define HDA_DEVID 0x4383 +# define HDA_DEVFN PCI_DEVFN(HDA_DEV,HDA_FUNC) + +/* PCI Ports */ +#define SB_PCI_PORT_DEV 0x14 +#define SB_PCI_PORT_FUNC 4 +# define SB_PCI_PORT_DEVID 0x4384 +# define SB_PCI_PORT_DEVFN PCI_DEVFN(SB_PCI_PORT_DEV,SB_PCI_PORT_FUNC) + +/* PCIe Ports */ +#define SB_PCIE_DEV 0x15 +#define SB_PCIE_PORT1_FUNC 0 +#define SB_PCIE_PORT2_FUNC 1 +#define SB_PCIE_PORT3_FUNC 2 +#define SB_PCIE_PORT4_FUNC 3 +# define SB_PCIE_PORT1_DEVID 0x43A0 +# define SB_PCIE_PORT2_DEVID 0x43A1 +# define SB_PCIE_PORT3_DEVID 0x43A2 +# define SB_PCIE_PORT4_DEVID 0x43A3 +# define SB_PCIE_PORT1_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT1_FUNC) +# define SB_PCIE_PORT2_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT2_FUNC) +# define SB_PCIE_PORT3_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT3_FUNC) +# define SB_PCIE_PORT4_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT4_FUNC) + +/* Fusion Controller Hub */ +#define PCU_DEV 0x14 +#define LPC_DEV PCU_DEV +#define LPC_FUNC 3 +#define SMBUS_DEV 0x14 +#define SMBUS_FUNC 0 +# define LPC_DEVID 0x439D +# define SMBUS_DEVID 0x4385 +# define LPC_DEVFN PCI_DEVFN(LPC_DEV,LPC_FUNC) +# define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV,SMBUS_FUNC) + +#endif /* _CIMX_SB800_PCI_DEVS_H_ */ |