2 * This file is part of the coreboot project.
4 * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <console/console.h>
22 #include <device/device.h>
23 #include <device/pci.h>
24 #include <device/pci_ids.h>
26 #include "northbridge.h"
29 static void noop_1k(u32 knops)
33 for (i = 0; i < 1024 * knops; i++) {
34 __asm__ volatile ("nop\n\t");
40 /* Vlink Performance Improvements */
41 static void vlink_init(device_t dev)
46 printk(BIOS_SPEW, "Entering CN400 %s\n", __func__);
48 /* Disconnect the VLink Before Changing Settings */
49 reg = pci_read_config8(dev, 0x47);
51 pci_write_config8(dev, 0x47, reg);
53 /* Wait for anything pending to flush */
56 /* Setup Vlink Mode 1 */
57 pci_write_config8(dev, 0x4F, 0x01);
58 pci_write_config8(dev, 0x48, 0x13);
60 /* PCI Buffer Control */
61 pci_write_config8(dev, 0x70, 0x82);
63 /* CPU to PCI Flow Control */
64 pci_write_config8(dev, 0x71, 0xc8);
65 pci_write_config8(dev, 0x72, 0xee);
67 /* PCI Master Control */
68 pci_write_config8(dev, 0x73, 0x01);
69 pci_write_config8(dev, 0x74, 0x20);
71 /* PCI Arbitration 1 */
72 pci_write_config8(dev, 0x75, 0x0f);
74 /* PCI Arbitration 2 */
75 pci_write_config8(dev, 0x76, 0x50);
76 pci_write_config8(dev, 0x77, 0x6e);
77 pci_write_config8(dev, 0x7F, 0x10);
79 pci_write_config8(dev, 0x94, 0x20);
80 pci_write_config8(dev, 0x95, 0x0f);
82 /* V-Link CKG Control 1 */
83 pci_write_config8(dev, 0xB0, 0x01);
85 /* V-Link NB Compensation Control */
86 pci_write_config8(dev, 0xB5, 0x46);
87 pci_write_config8(dev, 0xB6, 0x68);
88 reg = pci_read_config8(dev, 0xB4);
90 pci_write_config8(dev, 0xB4, reg);
92 /* V-Link NB Receive Strobe Delay */
93 pci_write_config8(dev, 0xB7, 0x02);
95 /* V-Link SB Compensation Control */
96 pci_write_config8(dev, 0xB9, 0x84);
97 reg = pci_read_config8(dev, 0xB8);
99 pci_write_config8(dev, 0xB8, reg);
101 pci_write_config8(dev, 0xBA, 0x6a);
102 pci_write_config8(dev, 0xBB, 0x01);
105 /* Reconnect the VLink Before Continuing*/
106 reg = pci_read_config8(dev, 0x47);
108 pci_write_config8(dev, 0x47, reg);
110 printk(BIOS_SPEW, "%s PCI Header Regs::\n", dev_path(dev));
112 for (i = 0 ; i < 16; i++)
114 printk(BIOS_SPEW, "%02X: ", i*16);
115 for (j = 0; j < 16; j++)
117 reg8 = pci_read_config8(dev, j+(i*16));
118 printk(BIOS_SPEW, "%02X ", reg8);
120 printk(BIOS_SPEW, "\n");
125 static const struct device_operations vlink_operations = {
126 .read_resources = pci_dev_read_resources,
127 .set_resources = pci_dev_set_resources,
128 .enable_resources = pci_dev_enable_resources,
133 static const struct pci_driver vlink_driver __pci_driver = {
134 .ops = &vlink_operations,
135 .vendor = PCI_VENDOR_ID_VIA,
136 .device = PCI_DEVICE_ID_VIA_CN400_VLINK,
139 static void c3_host_init(device_t dev)
144 printk(BIOS_SPEW, "Entering CN400 %s\n", __func__);
146 printk(BIOS_SPEW, "%s PCI Header Regs::\n", dev_path(dev));
148 for (i = 0 ; i < 16; i++)
150 printk(BIOS_SPEW, "%02X: ", i*16);
151 for (j = 0; j < 16; j++)
153 reg8 = pci_read_config8(dev, j+(i*16));
154 printk(BIOS_SPEW, "%02X ", reg8);
156 printk(BIOS_SPEW, "\n");
161 static const struct device_operations c3_host_operations = {
162 .read_resources = cn400_noop,
163 .set_resources = cn400_noop,
164 .enable_resources = cn400_noop,
165 .init = c3_host_init,
169 static const struct pci_driver c3_host_driver __pci_driver = {
170 .ops = &c3_host_operations,
171 .vendor = PCI_VENDOR_ID_VIA,
172 .device = PCI_DEVICE_ID_VIA_CN400_HOST,
176 static void c3_err_init(device_t dev)
181 printk(BIOS_SPEW, "Entering CN400 %s\n", __func__);
183 printk(BIOS_SPEW, "%s PCI Header Regs::\n", dev_path(dev));
185 for (i = 0 ; i < 16; i++)
187 printk(BIOS_SPEW, "%02X: ", i*16);
188 for (j = 0; j < 16; j++)
190 reg8 = pci_read_config8(dev, j+(i*16));
191 printk(BIOS_SPEW, "%02X ", reg8);
193 printk(BIOS_SPEW, "\n");
198 static const struct device_operations c3_err_operations = {
199 .read_resources = cn400_noop,
200 .set_resources = cn400_noop,
201 .enable_resources = cn400_noop,
206 static const struct pci_driver c3_err_driver __pci_driver = {
207 .ops = &c3_err_operations,
208 .vendor = PCI_VENDOR_ID_VIA,
209 .device = PCI_DEVICE_ID_VIA_CN400_ERR,
212 static void cn400_pm_init(device_t dev)
217 printk(BIOS_SPEW, "Entering CN400 %s\n", __func__);
219 printk(BIOS_SPEW, "%s PCI Header Regs::\n", dev_path(dev));
221 for (i = 0 ; i < 16; i++)
223 printk(BIOS_SPEW, "%02X: ", i*16);
224 for (j = 0; j < 16; j++)
226 reg8 = pci_read_config8(dev, j+(i*16));
227 printk(BIOS_SPEW, "%02X ", reg8);
229 printk(BIOS_SPEW, "\n");
234 static const struct device_operations cn400_pm_operations = {
235 .read_resources = cn400_noop,
236 .set_resources = cn400_noop,
237 .enable_resources = cn400_noop,
238 .init = cn400_pm_init,
242 static const struct pci_driver cn400_pm_driver __pci_driver = {
243 .ops = &c3_err_operations,
244 .vendor = PCI_VENDOR_ID_VIA,
245 .device = PCI_DEVICE_ID_VIA_CN400_PM,