2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <device/pci.h>
18 #include <device/pci_ids.h>
19 #include <console/console.h>
20 #include <device/pci.h>
21 #include <device/pci_ids.h>
22 #include <drivers/generic/ioapic/chip.h>
28 * @file vx900/traf_ctrl.c
31 * The same issues with the IOAPIC pointe in lpc.c also apply here.
33 * We need to check if the current PCIE lane configuration mechanism is sane.
37 * \brief VX900: Set up the north module IOAPIC (for PCIE and VGA)
39 * Enable the IOAPIC in the south module, and properly set it up.
41 * This is the hardware specific initialization for the IOAPIC, and complements
42 * the setup done by the generic IOAPIC driver. In order for the IOAPIC to work
43 * properly, it _must_ be declared in devicetree.cb .
45 * We are assuming this is called before the drivers/generic/ioapic code,
46 * which should be the case if devicetree.cb is set up properly.
48 static void vx900_north_ioapic_setup(device_t dev
)
52 ioapic_config_t
*config
;
53 /* Find the IOAPIC, and make sure it's set up correctly in devicetree.cb
54 * If it's not, then the generic ioapic driver will not set it up
55 * correctly, and the MP table will not be correctly generated */
56 for (ioapic
= dev
->next
; ioapic
; ioapic
= ioapic
->next
) {
57 if (ioapic
->path
.type
== DEVICE_PATH_IOAPIC
)
60 /* You did put an IOAPIC in devicetree.cb, didn't you? */
62 /* We don't have enough info to set up the IOAPIC */
63 printk(BIOS_ERR
, "ERROR: North module IOAPIC not found. "
64 "Check your devicetree.cb\n");
67 /* Found our IOAPIC, and it should not carry ISA interrupts */
68 config
= (ioapic_config_t
*) ioapic
->chip_info
;
69 if (config
->have_isa_interrupts
) {
70 /* Umh, is this the right IOAPIC ? */
71 printk(BIOS_ERR
, "ERROR: North module IOAPIC should not carry "
72 "ISA interrupts.\n" "Check your devicetree.cb\n");
73 printk(BIOS_ERR
, "Will not initialize this IOAPIC.\n");
76 /* The base address of this IOAPIC _must_
77 * be between 0xfec00000 and 0xfecfff00
80 if ((config
->base
< (void *)0xfec0000 || config
->base
> (void *)0xfecfff00)
81 || (((uintptr_t)config
->base
& 0xff) != 0)) {
82 printk(BIOS_ERR
, "ERROR: North module IOAPIC base should be "
83 "between 0xfec00000 and 0xfecfff00\n"
84 "and must be aligned to a 256-byte boundary, "
85 "but we found it at 0x%p\n", config
->base
);
89 printk(BIOS_DEBUG
, "VX900 TRAF_CTR: Setting up the north module IOAPIC "
90 "at %p\n", config
->base
);
92 /* First register of the IOAPIC base */
93 base_val
= (((uintptr_t)config
->base
) >> 8) & 0xff;
94 pci_write_config8(dev
, 0x41, base_val
);
95 /* Second register of the base.
96 * Bit[7] also enables the IOAPIC and bit[5] enables MSI cycles */
97 base_val
= (((uintptr_t)config
->base
) >> 16) & 0xf;
98 pci_mod_config8(dev
, 0x40, 0, base_val
| (1 << 7) | (1 << 5));
102 * Configures the PCI-express ports
104 * FIXME: triple-quadruple-check this
106 static void vx900_pex_link_setup(device_t dev
)
109 struct northbridge_via_vx900_config
*nb
= (void *)dev
->chip_info
;
111 reg8
= pci_read_config8(dev
, 0xb0);
112 reg8
&= ~((1 << 7) | (1 << 3));
114 if (nb
->assign_pex_to_dp
)
117 if (!nb
->pcie_port1_2_lane_wide
)
120 pci_write_config8(dev
, 0xb0, reg8
);
123 static void vx900_traf_ctr_init(device_t dev
)
125 vx900_north_ioapic_setup(dev
);
126 vx900_pex_link_setup(dev
);
129 static struct device_operations traf_ctrl_ops
= {
130 .read_resources
= pci_dev_read_resources
,
131 .set_resources
= pci_dev_set_resources
,
132 .enable_resources
= pci_dev_enable_resources
,
133 .init
= vx900_traf_ctr_init
,
134 /* Need this here, or the IOAPIC driver won't be called.
135 * FIXME: Technically not a LPC bus. */
136 .scan_bus
= scan_lpc_bus
,
139 static const struct pci_driver traf_ctrl_driver __pci_driver
= {
140 .ops
= &traf_ctrl_ops
,
141 .vendor
= PCI_VENDOR_ID_VIA
,
142 .device
= PCI_DEVICE_ID_VIA_VX900_TRAF
,