blob: 011bb4139d513e99dffd655d9e9768929cca7ec4 [file] [log] [blame]
Alexandru Gagniuc23211b02013-06-09 16:06:07 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
5 *
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.
10 *
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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <device/pci.h>
21#include <device/pci_ids.h>
22#include <console/console.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
25#include <drivers/generic/ioapic/chip.h>
26
27#include "vx900.h"
28#include "chip.h"
29
30/**
Martin Roth543888d2015-01-06 10:20:42 -070031 * @file vx900/traf_ctrl.c
Alexandru Gagniuc23211b02013-06-09 16:06:07 -050032 *
33 * STATUS:
34 * The same issues with the IOAPIC pointe in lpc.c also apply here.
35 *
36 * We need to check if the current PCIE lane configuration mechanism is sane.
37 */
38
39/**
40 * \brief VX900: Set up the north module IOAPIC (for PCIE and VGA)
41 *
42 * Enable the IOAPIC in the south module, and properly set it up.
43 * \n
44 * This is the hardware specific initialization for the IOAPIC, and complements
45 * the setup done by the generic IOAPIC driver. In order for the IOAPIC to work
46 * properly, it _must_ be declared in devicetree.cb .
47 * \n
48 * We are assuming this is called before the drivers/generic/ioapic code,
49 * which should be the case if devicetree.cb is set up properly.
50 */
51static void vx900_north_ioapic_setup(device_t dev)
52{
53 u8 base_val;
54 device_t ioapic;
55 ioapic_config_t *config;
56 /* Find the IOAPIC, and make sure it's set up correctly in devicetree.cb
57 * If it's not, then the generic ioapic driver will not set it up
58 * correctly, and the MP table will not be correctly generated */
59 for (ioapic = dev->next; ioapic; ioapic = ioapic->next) {
60 if (ioapic->path.type == DEVICE_PATH_IOAPIC)
61 break;
62 }
63 /* You did put an IOAPIC in devicetree.cb, didn't you? */
64 if (ioapic == 0) {
65 /* We don't have enough info to set up the IOAPIC */
66 printk(BIOS_ERR, "ERROR: North module IOAPIC not found. "
67 "Check your devicetree.cb\n");
68 return;
69 }
70 /* Found our IOAPIC, and it should not carry ISA interrupts */
71 config = (ioapic_config_t *) ioapic->chip_info;
72 if (config->have_isa_interrupts) {
73 /* Umh, is this the right IOAPIC ? */
74 printk(BIOS_ERR, "ERROR: North module IOAPIC should not carry "
75 "ISA interrupts.\n" "Check your devicetree.cb\n");
76 printk(BIOS_ERR, "Will not initialize this IOAPIC.\n");
77 return;
78 }
79 /* The base address of this IOAPIC _must_
80 * be between 0xfec00000 and 0xfecfff00
81 * be 256-byte aligned
82 */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080083 if ((config->base < (void *)0xfec0000 || config->base > (void *)0xfecfff00)
84 || (((uintptr_t)config->base & 0xff) != 0)) {
Alexandru Gagniuc23211b02013-06-09 16:06:07 -050085 printk(BIOS_ERR, "ERROR: North module IOAPIC base should be "
86 "between 0xfec00000 and 0xfecfff00\n"
87 "and must be aligned to a 256-byte boundary, "
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080088 "but we found it at 0x%p\n", config->base);
Alexandru Gagniuc23211b02013-06-09 16:06:07 -050089 return;
90 }
91
92 printk(BIOS_DEBUG, "VX900 TRAF_CTR: Setting up the north module IOAPIC "
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080093 "at %p\n", config->base);
Alexandru Gagniuc23211b02013-06-09 16:06:07 -050094
95 /* First register of the IOAPIC base */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080096 base_val = (((uintptr_t)config->base) >> 8) & 0xff;
Alexandru Gagniuc23211b02013-06-09 16:06:07 -050097 pci_write_config8(dev, 0x41, base_val);
98 /* Second register of the base.
99 * Bit[7] also enables the IOAPIC and bit[5] enables MSI cycles */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800100 base_val = (((uintptr_t)config->base) >> 16) & 0xf;
Alexandru Gagniuc23211b02013-06-09 16:06:07 -0500101 pci_mod_config8(dev, 0x40, 0, base_val | (1 << 7) | (1 << 5));
102}
103
104/*
105 * Configures the PCI-express ports
106 *
107 * FIXME: triple-quadruple-check this
108 */
109static void vx900_pex_link_setup(device_t dev)
110{
111 u8 reg8;
112 struct northbridge_via_vx900_config *nb = (void *)dev->chip_info;
113
114 reg8 = pci_read_config8(dev, 0xb0);
115 reg8 &= ~((1 << 7) | (1 << 3));
116
117 if (nb->assign_pex_to_dp)
118 reg8 |= (1 << 7);
119
120 if (!nb->pcie_port1_2_lane_wide)
121 reg8 |= (1 << 3);
122
123 pci_write_config8(dev, 0xb0, reg8);
124}
125
126static void vx900_traf_ctr_init(device_t dev)
127{
128 vx900_north_ioapic_setup(dev);
129 vx900_pex_link_setup(dev);
130}
131
132static struct device_operations traf_ctrl_ops = {
133 .read_resources = pci_dev_read_resources,
134 .set_resources = pci_dev_set_resources,
135 .enable_resources = pci_dev_enable_resources,
136 .init = vx900_traf_ctr_init,
Kyösti Mälkkid0e212c2015-02-26 20:47:47 +0200137 /* Need this here, or the IOAPIC driver won't be called.
138 * FIXME: Technically not a LPC bus. */
139 .scan_bus = scan_lpc_bus,
Alexandru Gagniuc23211b02013-06-09 16:06:07 -0500140};
141
142static const struct pci_driver traf_ctrl_driver __pci_driver = {
143 .ops = &traf_ctrl_ops,
144 .vendor = PCI_VENDOR_ID_VIA,
145 .device = PCI_DEVICE_ID_VIA_VX900_TRAF,
146};