diff options
author | Dave Frodin <dave.frodin@se-eng.com> | 2014-12-01 16:33:33 -0700 |
---|---|---|
committer | Dave Frodin <dave.frodin@se-eng.com> | 2014-12-09 15:34:22 +0100 |
commit | c7eaf7730db0ce5bf2f9701dc79d7fed50bea963 (patch) | |
tree | 3f8c85ebfccdf74bbadbbd85de8bec80ab938485 | |
parent | d6aa7cffa3c3987749ada01a7eaedaf3a8823a33 (diff) |
gizmosphere/gizmo2: Add the gizmo2 IRQ routing
Change-Id: Ic00790eedd48a2b78620fea329464701cd294cbb
Signed-off-by: Dave Frodin <dave.frodin@se-eng.com>
Reviewed-on: http://review.coreboot.org/7723
Tested-by: build bot (Jenkins)
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
-rw-r--r-- | src/mainboard/gizmosphere/gizmo2/mainboard.c | 92 | ||||
-rw-r--r-- | src/mainboard/gizmosphere/gizmo2/mptable.c | 224 |
2 files changed, 172 insertions, 144 deletions
diff --git a/src/mainboard/gizmosphere/gizmo2/mainboard.c b/src/mainboard/gizmosphere/gizmo2/mainboard.c index cf02528916..c4a20c64d1 100644 --- a/src/mainboard/gizmosphere/gizmo2/mainboard.c +++ b/src/mainboard/gizmosphere/gizmo2/mainboard.c @@ -2,6 +2,8 @@ * This file is part of the coreboot project. * * Copyright (C) 2012 Advanced Micro Devices, Inc. + * Copyright (C) 2014 Sage Electronic Engineering, LLC + * All Rights Reserved * * 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 @@ -25,10 +27,97 @@ #include <cpu/amd/mtrr.h> #include <device/pci_def.h> #include <arch/acpi.h> +#include <southbridge/amd/agesa/hudson/pci_devs.h> +#include <southbridge/amd/agesa/hudson/amd_pci_int_defs.h> +#include <southbridge/amd/amd_pci_util.h> +#include <northbridge/amd/agesa/family16kb/pci_devs.h> #include <northbridge/amd/agesa/BiosCallOuts.h> #include <cpu/amd/agesa/s3_resume.h> #include <northbridge/amd/agesa/agesawrapper.h> +/*********************************************************** + * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. + * This table is responsible for physically routing the PIC and + * IOAPIC IRQs to the different PCI devices on the system. It + * is read and written via registers 0xC00/0xC01 as an + * Index/Data pair. These values are chipset and mainboard + * dependent and should be updated accordingly. + * + * These values are used by the PCI configuration space, + * MP Tables. TODO: Make ACPI use these values too. + */ +const u8 mainboard_picr_data[FCH_INT_TABLE_SIZE] = { + /* INTA# - INTH# */ + [0x00] = 0x0A,0x0B,0x0A,0x0B,0x0A,0x0B,0x0A,0x0B, + /* Misc-nil,0,1,2, INT from Serial irq */ + [0x08] = 0xFA,0xF1,0x00,0x00,0x1F,0x1F,0x1F,0x1F, + /* SCI, SMBUS0, ASF, HDA, FC, RSVD, PerMon, SD */ + [0x10] = 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, + /* IMC INT0 - 5 */ + [0x20] = 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, + /* USB Devs 18/19/22 INTA-C */ + [0x30] = 0x0A,0x0B,0x0A,0x0B,0x0A,0x0B, + /* SATA */ + [0x41] = 0x0F, +}; + +const u8 mainboard_intr_data[FCH_INT_TABLE_SIZE] = { + /* INTA# - INTH# */ + [0x00] = 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + /* Misc-nil,0,1,2, INT from Serial irq */ + [0x08] = 0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F, + /* SCI, SMBUS0, ASF, HDA, FC, GEC, PerMon, SD */ + [0x10] = 0x09,0x1F,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F, + /* IMC INT0 - 5 */ + [0x20] = 0x05,0x1F,0x1F,0x1F,0x1F,0x1F, + /* USB Devs 18/19/20/22 INTA-C */ + [0x30] = 0x12,0x11,0x12,0x11,0x12,0x11,0x12, + /* SATA */ + [0x41] = 0x13 +}; + +/* + * This table defines the index into the picr/intr_data + * tables for each device. Any enabled device and slot + * that uses hardware interrupts should have an entry + * in this table to define its index into the FCH + * PCI_INTR register 0xC00/0xC01. This index will define + * the interrupt that it should use. Putting PIRQ_A into + * the PIN A index for a device will tell that device to + * use PIC IRQ 10 if it uses PIN A for its hardware INT. + */ +static const struct pirq_struct mainboard_pirq_data[] = { + /* {PCI_devfn, {PIN A, PIN B, PIN C, PIN D}}, */ + {GFX_DEVFN, {PIRQ_A, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* VGA: 01.0 */ + {ACTL_DEVFN,{PIRQ_NC, PIRQ_B, PIRQ_NC, PIRQ_NC}}, /* Audio: 01.1 */ + {NB_PCIE_PORT1_DEVFN, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D}}, /* x4 PCIe: 02.1 */ + {NB_PCIE_PORT2_DEVFN, {PIRQ_B, PIRQ_C, PIRQ_D, PIRQ_A}}, /* mPCIe: 02.2 */ + {NB_PCIE_PORT3_DEVFN, {PIRQ_C, PIRQ_D, PIRQ_A, PIRQ_B}}, /* NIC: 02.3 */ + {NB_PCIE_PORT4_DEVFN, {PIRQ_D, PIRQ_A, PIRQ_B, PIRQ_C}}, /* Edge: 02.4 */ + {NB_PCIE_PORT5_DEVFN, {PIRQ_E, PIRQ_F, PIRQ_G, PIRQ_H}}, /* Edge: 02.5 */ + {XHCI_DEVFN, {PIRQ_C, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* XHCI: 10.0 */ + {SATA_DEVFN, {PIRQ_SATA, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* SATA: 11.0 */ + {OHCI1_DEVFN, {PIRQ_OHCI1, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* OHCI1: 12.0 */ + {EHCI1_DEVFN, {PIRQ_NC, PIRQ_EHCI1, PIRQ_NC, PIRQ_NC}}, /* EHCI1: 12.2 */ + {OHCI2_DEVFN, {PIRQ_OHCI2, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* OHCI2: 13.0 */ + {EHCI2_DEVFN, {PIRQ_NC, PIRQ_EHCI2, PIRQ_NC, PIRQ_NC}}, /* EHCI2: 13.2 */ + {SMBUS_DEVFN, {PIRQ_SMBUS, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* SMBUS: 14.0 */ + {HDA_DEVFN, {PIRQ_HDA, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* HDA: 14.2 */ + {SD_DEVFN, {PIRQ_SD, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* SD: 14.7 */ +}; + +const u8 *picr_data = mainboard_picr_data; +const u8 *intr_data = mainboard_intr_data; + +/* PIRQ Setup */ +static void pirq_setup(void) +{ + pirq_data_ptr = mainboard_pirq_data; + pirq_data_size = sizeof(mainboard_pirq_data) / sizeof(struct pirq_struct); + intr_data_ptr = mainboard_intr_data; + picr_data_ptr = mainboard_picr_data; +} + /********************************************** * enable the dedicated function in mainboard. **********************************************/ @@ -38,6 +127,9 @@ static void mainboard_enable(device_t dev) if (acpi_is_wakeup_s3()) agesawrapper_fchs3earlyrestore(); + + /* Initialize the PIRQ data structures for consumption */ + pirq_setup(); } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/gizmosphere/gizmo2/mptable.c b/src/mainboard/gizmosphere/gizmo2/mptable.c index db4a3ffa8e..fbf6744542 100644 --- a/src/mainboard/gizmosphere/gizmo2/mptable.c +++ b/src/mainboard/gizmosphere/gizmo2/mptable.c @@ -24,51 +24,16 @@ #include <arch/ioapic.h> #include <string.h> #include <stdint.h> -#include <cpu/amd/amdfam15.h> +#include <cpu/amd/amdfam16.h> #include <arch/cpu.h> #include <cpu/x86/lapic.h> -#include "southbridge/amd/agesa/hudson/hudson.h" /* pm_ioread() */ - -u8 picr_data[0x54] = { - 0x03,0x04,0x05,0x07,0x0B,0x0A,0x1F,0x1F,0xFA,0xF1,0x00,0x00,0x1F,0x1F,0x1F,0x1F, - 0x1F,0x1F,0x1F,0x03,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x05,0x04,0x05,0x04,0x04,0x05,0x04,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x04,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x03,0x04,0x05,0x07 -}; -u8 intr_data[0x54] = { - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F, - 0x09,0x1F,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x05,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x12,0x11,0x12,0x11,0x12,0x11,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x11,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x10,0x11,0x12,0x13 -}; - -static void smp_add_mpc_entry(struct mp_config_table *mc, unsigned length) -{ - mc->mpc_length += length; - mc->mpc_entry_count++; -} - -static void my_smp_write_bus(struct mp_config_table *mc, - unsigned char id, const char *bustype) -{ - struct mpc_config_bus *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_BUS; - mpc->mpc_busid = id; - memcpy(mpc->mpc_bustype, bustype, sizeof(mpc->mpc_bustype)); - smp_add_mpc_entry(mc, sizeof(*mpc)); -} +#include <southbridge/amd/amd_pci_util.h> +#include <drivers/generic/ioapic/chip.h> static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; - u8 byte; /* * By the time this function gets called, the IOAPIC registers @@ -78,147 +43,118 @@ static void *smp_write_config_table(void *v) u8 ioapic_id = (io_apic_read(IO_APIC_ADDR, 0x00) >> 24); u8 ioapic_ver = (io_apic_read(IO_APIC_ADDR, 0x01) & 0xFF); + /* Intialize the MP_Table */ mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); - memcpy(mc->mpc_oem, "AMD ", 8); + /* + * Type 0: Processor Entries: + * LAPIC ID, LAPIC Version, CPU Flags:EN/BP, + * CPU Signature (Stepping, Model, Family), + * Feature Flags + */ smp_write_processors(mc); - //mptable_write_buses(mc, NULL, &bus_isa); - my_smp_write_bus(mc, 0, "PCI "); - my_smp_write_bus(mc, 1, "PCI "); - bus_isa = 0x02; - my_smp_write_bus(mc, bus_isa, "ISA "); + /* + * Type 1: Bus Entries: + * Bus ID, Bus Type + */ + mptable_write_buses(mc, NULL, &bus_isa); - /* I/O APICs: APIC ID Version State Address */ + /* + * Type 2: I/O APICs: + * APIC ID, Version, APIC Flags:EN, Address + */ smp_write_ioapic(mc, ioapic_id, ioapic_ver, IO_APIC_ADDR); - smp_write_ioapic(mc, ioapic_id+1, 0x21, 0xFEC20000); - /* PIC IRQ routine */ - for (byte = 0x0; byte < sizeof(picr_data); byte ++) { - outb(byte, 0xC00); - outb(picr_data[byte], 0xC01); - } - - /* APIC IRQ routine */ - for (byte = 0x0; byte < sizeof(intr_data); byte ++) { - outb(byte | 0x80, 0xC00); - outb(intr_data[byte], 0xC01); - } -#if 0 - outb(0x0B, 0xCD6); - outb(0x02, 0xCD7); - - outb(0x50, 0xCD6); - outb(0x1F, 0xCD7); - - outb(0x48, 0xCD6); - outb(0xF2, 0xCD7); - - //outb(0xBE, 0xCD6); - //outb(0x52, 0xCD7); - - outb(0xED, 0xCD6); - outb(0x17, 0xCD7); - - *(volatile u8 *) (0xFED80D00 + 0x31) = 2; - *(volatile u8 *) (0xFED80D00 + 0x32) = 2; - *(volatile u8 *) (0xFED80D00 + 0x33) = 2; - *(volatile u8 *) (0xFED80D00 + 0x34) = 2; - - *(volatile u8 *) (0xFED80100 + 0x31) = 0xc8; - *(volatile u8 *) (0xFED80100 + 0x32) = 0xc8; - *(volatile u8 *) (0xFED80100 + 0x33) = 0xc8; - *(volatile u8 *) (0xFED80100 + 0x34) = 0xa0; - - *(volatile u8 *) (0xFED80D00 + 0x6c) = 1; - *(volatile u8 *) (0xFED80D00 + 0x6E) = 2; - *(volatile u8 *) (0xFED80D00 + 0x6f) = 2; - - *(volatile u8 *) (0xFED80100 + 0x6c) = 0xa0; - *(volatile u8 *) (0xFED80100 + 0x6E) = 0xa8; - *(volatile u8 *) (0xFED80100 + 0x6f) = 0xa0; - - *(volatile u8 *) (0xFED80D00 + 0xA6) = 2; - *(volatile u8 *) (0xFED80100 + 0xA6) = 0; - - *(volatile u8 *) (0xFED80100 + 0x40) = 0xC8; -#endif - /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ -#define IO_LOCAL_INT(type, intr, apicid, pin) \ - smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); + /* + * Type 3: I/O Interrupt Table Entries: + * Int Type, Int Polarity, Int Level, Source Bus ID, + * Source Bus IRQ, Dest APIC ID, Dest PIN# + */ mptable_add_isa_interrupts(mc, bus_isa, ioapic_id, 0); /* PCI interrupts are level triggered, and are * associated with a specific bus/device/function tuple. */ -#define PCI_INT(bus, dev, int_sign, pin) \ - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(int_sign)), ioapic_id, (pin)) +#define PCI_INT(bus, dev, fn, pin) \ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(fn)), ioapic_id, (pin)) + + /* APU Internal Graphic Device */ + PCI_INT(0x0, 0x01, 0x0, intr_data_ptr[PIRQ_C]); + PCI_INT(0x0, 0x01, 0x1, intr_data_ptr[PIRQ_D]); - /* Internal VGA */ - PCI_INT(0x0, 0x01, 0x0, intr_data[0x02]); - PCI_INT(0x0, 0x01, 0x1, intr_data[0x03]); + /* SMBUS / ACPI */ + PCI_INT(0x0, 0x14, 0x0, intr_data_ptr[PIRQ_SMBUS]); - /* SMBUS */ - PCI_INT(0x0, 0x14, 0x0, 0x10); + /* Southbridge HD Audio */ + PCI_INT(0x0, 0x14, 0x2, intr_data_ptr[PIRQ_HDA]); - /* HD Audio */ - PCI_INT(0x0, 0x14, 0x0, intr_data[0x13]); + /* LPC */ + PCI_INT(0x0, 0x14, 0x3, intr_data_ptr[PIRQ_C]); /* USB */ - PCI_INT(0x0, 0x12, 0x0, intr_data[0x30]); - PCI_INT(0x0, 0x12, 0x1, intr_data[0x31]); - PCI_INT(0x0, 0x13, 0x0, intr_data[0x32]); - PCI_INT(0x0, 0x13, 0x1, intr_data[0x33]); - PCI_INT(0x0, 0x16, 0x0, intr_data[0x34]); - PCI_INT(0x0, 0x16, 0x1, intr_data[0x35]); - PCI_INT(0x0, 0x14, 0x2, intr_data[0x36]); + PCI_INT(0x0, 0x12, 0x0, intr_data_ptr[PIRQ_OHCI1]); + PCI_INT(0x0, 0x12, 0x2, intr_data_ptr[PIRQ_EHCI1]); + PCI_INT(0x0, 0x13, 0x0, intr_data_ptr[PIRQ_OHCI2]); + PCI_INT(0x0, 0x13, 0x2, intr_data_ptr[PIRQ_EHCI2]); + PCI_INT(0x0, 0x16, 0x0, intr_data_ptr[PIRQ_OHCI3]); + PCI_INT(0x0, 0x16, 0x2, intr_data_ptr[PIRQ_EHCI3]); + PCI_INT(0x0, 0x14, 0x2, intr_data_ptr[PIRQ_OHCI4]); - /* sata */ - PCI_INT(0x0, 0x11, 0x0, intr_data[0x40]); - PCI_INT(0x0, 0x11, 0x0, intr_data[0x41]); + /* SATA */ + PCI_INT(0x0, 0x11, 0x0, intr_data_ptr[PIRQ_SATA]); - /* on board NIC & Slot PCIE. */ + /* on board NIC & Slot PCIE */ + PCI_INT(0x1, 0x0, 0x0, intr_data_ptr[PIRQ_E]); + PCI_INT(0x2, 0x0, 0x0, intr_data_ptr[PIRQ_F]); /* PCI slots */ device_t dev = dev_find_slot(0, PCI_DEVFN(0x14, 4)); if (dev && dev->enabled) { u8 bus_pci = dev->link_list->secondary; - /* PCI_SLOT 0. */ - PCI_INT(bus_pci, 0x5, 0x0, 0x14); - PCI_INT(bus_pci, 0x5, 0x1, 0x15); - PCI_INT(bus_pci, 0x5, 0x2, 0x16); - PCI_INT(bus_pci, 0x5, 0x3, 0x17); - - /* PCI_SLOT 1. */ - PCI_INT(bus_pci, 0x6, 0x0, 0x15); - PCI_INT(bus_pci, 0x6, 0x1, 0x16); - PCI_INT(bus_pci, 0x6, 0x2, 0x17); - PCI_INT(bus_pci, 0x6, 0x3, 0x14); - - /* PCI_SLOT 2. */ - PCI_INT(bus_pci, 0x7, 0x0, 0x16); - PCI_INT(bus_pci, 0x7, 0x1, 0x17); - PCI_INT(bus_pci, 0x7, 0x2, 0x14); - PCI_INT(bus_pci, 0x7, 0x3, 0x15); + /* PCI_SLOT 0 */ + PCI_INT(bus_pci, 0x5, 0x0, intr_data_ptr[PIRQ_E]); + PCI_INT(bus_pci, 0x5, 0x1, intr_data_ptr[PIRQ_F]); + PCI_INT(bus_pci, 0x5, 0x2, intr_data_ptr[PIRQ_G]); + PCI_INT(bus_pci, 0x5, 0x3, intr_data_ptr[PIRQ_H]); + + /* PCI_SLOT 1 */ + PCI_INT(bus_pci, 0x6, 0x0, intr_data_ptr[PIRQ_F]); + PCI_INT(bus_pci, 0x6, 0x1, intr_data_ptr[PIRQ_G]); + PCI_INT(bus_pci, 0x6, 0x2, intr_data_ptr[PIRQ_H]); + PCI_INT(bus_pci, 0x6, 0x3, intr_data_ptr[PIRQ_E]); + + /* PCI_SLOT 2 */ + PCI_INT(bus_pci, 0x7, 0x0, intr_data_ptr[PIRQ_G]); + PCI_INT(bus_pci, 0x7, 0x1, intr_data_ptr[PIRQ_H]); + PCI_INT(bus_pci, 0x7, 0x2, intr_data_ptr[PIRQ_E]); + PCI_INT(bus_pci, 0x7, 0x3, intr_data_ptr[PIRQ_F]); + + PCI_INT(bus_pci, 0x0, 0x0, intr_data_ptr[PIRQ_C]); + PCI_INT(bus_pci, 0x0, 0x1, intr_data_ptr[PIRQ_D]); + PCI_INT(bus_pci, 0x0, 0x2, intr_data_ptr[PIRQ_E]); } /* PCIe Lan*/ - PCI_INT(0x0, 0x06, 0x0, 0x13); + PCI_INT(0x0, 0x06, 0x0, intr_data_ptr[PIRQ_D]); /* FCH PCIe PortA */ - PCI_INT(0x0, 0x15, 0x0, 0x10); + PCI_INT(0x0, 0x15, 0x0, intr_data_ptr[PIRQ_A]); /* FCH PCIe PortB */ - PCI_INT(0x0, 0x15, 0x1, 0x11); + PCI_INT(0x0, 0x15, 0x1, intr_data_ptr[PIRQ_B]); /* FCH PCIe PortC */ - PCI_INT(0x0, 0x15, 0x2, 0x12); + PCI_INT(0x0, 0x15, 0x2, intr_data_ptr[PIRQ_C]); /* FCH PCIe PortD */ - PCI_INT(0x0, 0x15, 0x3, 0x13); + PCI_INT(0x0, 0x15, 0x3, intr_data_ptr[PIRQ_D]); + + /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ +#define IO_LOCAL_INT(type, intr, apicid, pin) \ + smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); - /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ - IO_LOCAL_INT(mp_ExtINT, 0, MP_APIC_ALL, 0x0); - IO_LOCAL_INT(mp_NMI, 0, MP_APIC_ALL, 0x1); + IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0); + IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1); /* There is no extension information... */ /* Compute the checksums */ |