diff options
Diffstat (limited to 'src/northbridge/via/vx900/traf_ctrl.c')
-rw-r--r-- | src/northbridge/via/vx900/traf_ctrl.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/northbridge/via/vx900/traf_ctrl.c b/src/northbridge/via/vx900/traf_ctrl.c new file mode 100644 index 0000000000..2e73ea439e --- /dev/null +++ b/src/northbridge/via/vx900/traf_ctrl.c @@ -0,0 +1,145 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com> + * + * 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, either version 2 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <device/pci.h> +#include <device/pci_ids.h> +#include <console/console.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <drivers/generic/ioapic/chip.h> + +#include "vx900.h" +#include "chip.h" + +/** + * @file traf_ctrl.c + * + * STATUS: + * The same issues with the IOAPIC pointe in lpc.c also apply here. + * + * We need to check if the current PCIE lane configuration mechanism is sane. + */ + +/** + * \brief VX900: Set up the north module IOAPIC (for PCIE and VGA) + * + * Enable the IOAPIC in the south module, and properly set it up. + * \n + * This is the hardware specific initialization for the IOAPIC, and complements + * the setup done by the generic IOAPIC driver. In order for the IOAPIC to work + * properly, it _must_ be declared in devicetree.cb . + * \n + * We are assuming this is called before the drivers/generic/ioapic code, + * which should be the case if devicetree.cb is set up properly. + */ +static void vx900_north_ioapic_setup(device_t dev) +{ + u8 base_val; + device_t ioapic; + ioapic_config_t *config; + /* Find the IOAPIC, and make sure it's set up correctly in devicetree.cb + * If it's not, then the generic ioapic driver will not set it up + * correctly, and the MP table will not be correctly generated */ + for (ioapic = dev->next; ioapic; ioapic = ioapic->next) { + if (ioapic->path.type == DEVICE_PATH_IOAPIC) + break; + } + /* You did put an IOAPIC in devicetree.cb, didn't you? */ + if (ioapic == 0) { + /* We don't have enough info to set up the IOAPIC */ + printk(BIOS_ERR, "ERROR: North module IOAPIC not found. " + "Check your devicetree.cb\n"); + return; + } + /* Found our IOAPIC, and it should not carry ISA interrupts */ + config = (ioapic_config_t *) ioapic->chip_info; + if (config->have_isa_interrupts) { + /* Umh, is this the right IOAPIC ? */ + printk(BIOS_ERR, "ERROR: North module IOAPIC should not carry " + "ISA interrupts.\n" "Check your devicetree.cb\n"); + printk(BIOS_ERR, "Will not initialize this IOAPIC.\n"); + return; + } + /* The base address of this IOAPIC _must_ + * be between 0xfec00000 and 0xfecfff00 + * be 256-byte aligned + */ + if ((config->base < 0xfec0000 || config->base > 0xfecfff00) + || ((config->base & 0xff) != 0)) { + printk(BIOS_ERR, "ERROR: North module IOAPIC base should be " + "between 0xfec00000 and 0xfecfff00\n" + "and must be aligned to a 256-byte boundary, " + "but we found it at 0x%.8x\n", config->base); + return; + } + + printk(BIOS_DEBUG, "VX900 TRAF_CTR: Setting up the north module IOAPIC " + "at 0%.8x\n", config->base); + + /* First register of the IOAPIC base */ + base_val = (config->base >> 8) & 0xff; + pci_write_config8(dev, 0x41, base_val); + /* Second register of the base. + * Bit[7] also enables the IOAPIC and bit[5] enables MSI cycles */ + base_val = (config->base >> 16) & 0xf; + pci_mod_config8(dev, 0x40, 0, base_val | (1 << 7) | (1 << 5)); +} + +/* + * Configures the PCI-express ports + * + * FIXME: triple-quadruple-check this + */ +static void vx900_pex_link_setup(device_t dev) +{ + u8 reg8; + struct northbridge_via_vx900_config *nb = (void *)dev->chip_info; + + reg8 = pci_read_config8(dev, 0xb0); + reg8 &= ~((1 << 7) | (1 << 3)); + + if (nb->assign_pex_to_dp) + reg8 |= (1 << 7); + + if (!nb->pcie_port1_2_lane_wide) + reg8 |= (1 << 3); + + pci_write_config8(dev, 0xb0, reg8); +} + +static void vx900_traf_ctr_init(device_t dev) +{ + vx900_north_ioapic_setup(dev); + vx900_pex_link_setup(dev); +} + +static struct device_operations traf_ctrl_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = vx900_traf_ctr_init, + /* Need this here, or the IOAPIC driver won't be called */ + .scan_bus = scan_static_bus, +}; + +static const struct pci_driver traf_ctrl_driver __pci_driver = { + .ops = &traf_ctrl_ops, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VX900_TRAF, +}; |