aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/via/vx900/traf_ctrl.c
diff options
context:
space:
mode:
authorAlexandru Gagniuc <mr.nuke.me@gmail.com>2013-06-09 16:06:07 -0500
committerRonald G. Minnich <rminnich@gmail.com>2013-06-10 22:58:21 +0200
commit23211b0200eac11c64fe9dadadb5ec5ef1deabc6 (patch)
tree865130c93105ab780e90d252a9fb66a0ad599380 /src/northbridge/via/vx900/traf_ctrl.c
parent7d31e7c13897e4b2548136c7a6f701b9121b7ad3 (diff)
VIA VX900: Add minimal ramstage needed to boot linux
This is the minimal code needed to get past ramstage, load SeaBIOS, jump to GRUB2, and boot linux (or load memtest). See individual source files for the status of each individual component. Change-Id: Ib7d5d7593c945f18af2c2fc5e0ae689ba66131a2 Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Reviewed-on: http://review.coreboot.org/3419 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/northbridge/via/vx900/traf_ctrl.c')
-rw-r--r--src/northbridge/via/vx900/traf_ctrl.c145
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,
+};