summaryrefslogtreecommitdiff
path: root/src/southbridge/amd/cimx/sb800/late.c
diff options
context:
space:
mode:
authorMike Loptien <mike.loptien@se-eng.com>2014-06-06 15:16:29 -0600
committerMike Loptien <mike.loptien@se-eng.com>2014-06-11 17:07:50 +0200
commitc93a75a5ab067f86104028b74d92fc54cb939cd5 (patch)
tree8f91538cc2b45d7df3d049c443d66e8617c6a641 /src/southbridge/amd/cimx/sb800/late.c
parentce740c474c3590dcb0da184d7663adf1f1d78ea8 (diff)
downloadcoreboot-c93a75a5ab067f86104028b74d92fc54cb939cd5.tar.xz
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/late.c')
-rw-r--r--src/southbridge/amd/cimx/sb800/late.c25
1 files changed, 25 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
*/