da7f6338211a60a037c3b81b201a72cda18badcd
[coreboot.git] / src / southbridge / via / vt8237r / vt8237_ctrl.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2008 Rudolf Marek <r.marek@assembler.cz>
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 v2 as published by
8  * the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 #include <device/device.h>
21 #include <device/pci.h>
22 #include <device/pci_ops.h>
23 #include <device/pci_ids.h>
24 #include <console/console.h>
25
26 /* We support here K8M890/K8T890 and VT8237/S/A PCI1/Vlink */
27
28 static void vt8237_cfg(struct device *dev)
29 {
30         u8 regm, regm2, regm3;
31         device_t devfun3;
32
33         devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
34                                   PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
35         if (!devfun3)
36                 devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
37                                           PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
38         if (!devfun3)
39                 die("Unknown NB");
40
41         /* CPU to PCI Flow Control 1 & 2, just fill in recommended. */
42         pci_write_config8(dev, 0x70, 0xc2);
43         pci_write_config8(dev, 0x71, 0xc8);
44
45         /* PCI Control */
46         pci_write_config8(dev, 0x72, 0xee);
47         pci_write_config8(dev, 0x73, 0x01);
48         pci_write_config8(dev, 0x74, 0x3c);
49         pci_write_config8(dev, 0x75, 0x0f);
50         pci_write_config8(dev, 0x76, 0x50);
51         pci_write_config8(dev, 0x77, 0x48);
52         pci_write_config8(dev, 0x78, 0x01);
53         /* APIC on HT */
54         /* Maybe Enable LDT APIC Mode bit3 set to 1 */
55         pci_write_config8(dev, 0x7c, 0x77);
56
57         /* WARNING: Need to copy some registers from NB (D0F3) to SB (D11F7). */
58
59         regm = pci_read_config8(devfun3, 0x88); /* Shadow mem CTRL */
60         pci_write_config8(dev, 0x57, regm);
61
62         regm = pci_read_config8(devfun3, 0x80); /* Shadow page C */
63         pci_write_config8(dev, 0x61, regm);
64
65         regm = pci_read_config8(devfun3, 0x81); /* Shadow page D */
66         pci_write_config8(dev, 0x62, regm);
67
68         /* Shadow page F + memhole copy */
69         regm = pci_read_config8(devfun3, 0x83);
70         pci_write_config8(dev, 0x63, regm);
71
72         regm3 = pci_read_config8(devfun3, 0x82);/* Shadow page E */
73         pci_write_config8(dev, 0x64, regm);
74
75         regm = pci_read_config8(devfun3, 0x86); /* SMM and APIC decoding */
76         pci_write_config8(dev, 0xe6, regm);
77 }
78
79 /**
80  * Example of setup: Setup the V-Link for VT8237R, 8X mode.
81  *
82  * For K8T890CF VIA recommends what is in VIA column, AW is award 8X:
83  *
84  *                                               REG   DEF   AW  VIA-8X VIA-4X
85  *                                               -----------------------------
86  * NB V-Link Manual Driving Control strobe       0xb5  0x46  0x46  0x88  0x88
87  * NB V-Link Manual Driving Control - Data       0xb6  0x46  0x46  0x88  0x88
88  * NB V-Link Receiving Strobe Delay              0xb7  0x02  0x02  0x61  0x01
89  * NB V-Link Compensation Control bit4,0 (b5,b6) 0xb4  0x10  0x10  0x11  0x11
90  * SB V-Link Strobe Drive Control                0xb9  0x00  0xa5  0x98  0x98
91  * SB V-Link Data drive Control????              0xba  0x00  0xbb  0x77  0x77
92  * SB V-Link Receive Strobe Delay????            0xbb  0x04  0x11  0x11  0x11
93  * SB V-Link Compensation Control bit0 (use b9)  0xb8  0x00  0x01  0x01  0x01
94  * V-Link CKG Control                            0xb0  0x05  0x05  0x06  0x03
95  * V-Link CKG Control                            0xb1  0x05  0x05  0x01  0x03
96  */
97
98 /* we setup 533MB/s mode full duplex */
99
100 static void vt8237s_vlink_init(struct device *dev)
101 {
102         u8 reg;
103         device_t devfun7;
104
105         devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
106                                   PCI_DEVICE_ID_VIA_K8T890CE_7, 0);
107         if (!devfun7)
108                 devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
109                                           PCI_DEVICE_ID_VIA_K8M890CE_7, 0);
110         /* No pairing NB was found. */
111         if (!devfun7)
112                 return;
113
114         /*
115          * This init code is valid only for the VT8237S! For different
116          * sounthbridges (e.g. VT8237A, VT8237S, VT8237R (without plus R)
117          * and VT8251) a different init code is required.
118          */
119
120         /* disable auto disconnect */
121         reg = pci_read_config8(devfun7, 0x42);
122         reg &= ~0x4;
123         pci_write_config8(devfun7, 0x42, reg);
124
125         /* NB part setup */
126         pci_write_config8(devfun7, 0xb5, 0x66);
127         pci_write_config8(devfun7, 0xb6, 0x66);
128         pci_write_config8(devfun7, 0xb7, 0x64);
129
130         reg = pci_read_config8(devfun7, 0xb4);
131         reg |= 0x1;
132         reg &= ~0x10;
133         pci_write_config8(devfun7, 0xb4, reg);
134
135         pci_write_config8(devfun7, 0xb0, 0x6);
136         pci_write_config8(devfun7, 0xb1, 0x1);
137
138         /* SB part setup */
139         pci_write_config8(dev, 0xb7, 0x60);
140         pci_write_config8(dev, 0xb9, 0x88);
141         pci_write_config8(dev, 0xba, 0x88);
142         pci_write_config8(dev, 0xbb, 0x89);
143
144         reg = pci_read_config8(dev, 0xbd);
145         reg |= 0x3;
146         reg &= ~0x4;
147         pci_write_config8(dev, 0xbd, reg);
148
149         reg = pci_read_config8(dev, 0xbc);
150         reg &= ~0x7;
151         pci_write_config8(dev, 0xbc, reg);
152
153         /* Program V-link 8X 8bit full duplex, parity enabled.  */
154         pci_write_config8(dev, 0x48, 0x23 | 0x80);
155
156         /* enable auto disconnect, for STPGNT and HALT */
157         reg = pci_read_config8(devfun7, 0x42);
158         reg |= 0x7;
159         pci_write_config8(devfun7, 0x42, reg);
160
161 }
162
163 static void ctrl_enable(struct device *dev)
164 {
165         /* Enable the 0:13 and 0:13.1. */
166         /* FIXME */
167         pci_write_config8(dev, 0x4f, 0x43);
168 }
169
170 extern void dump_south(device_t dev);
171
172 static void ctrl_init(struct device *dev)
173 {
174         /*
175          * TODO: Fix some ordering issue for V-link set Rx77[6] and
176          * PCI1_Rx4F[0] should to 1.
177          * FIXME DO you need?
178          */
179
180         /*
181          * VT8237R specific configuration. Other SB are done in their own
182          * directories. TODO: Add A version.
183          */
184         device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA,
185                                          PCI_DEVICE_ID_VIA_VT8237S_LPC, 0);
186         if (devsb) {
187                 vt8237s_vlink_init(dev);
188         }
189
190         /* Configure PCI1 and copy mirror registers from D0F3. */
191         vt8237_cfg(dev);
192         dump_south(dev);
193 }
194
195 static const struct device_operations ctrl_ops = {
196         .read_resources         = pci_dev_read_resources,
197         .set_resources          = pci_dev_set_resources,
198         .enable_resources       = pci_dev_enable_resources,
199         .init                   = ctrl_init,
200         .enable                 = ctrl_enable,
201         .ops_pci                = 0,
202 };
203
204 static const struct pci_driver northbridge_driver_t __pci_driver = {
205         .ops    = &ctrl_ops,
206         .vendor = PCI_VENDOR_ID_VIA,
207         .device = PCI_DEVICE_ID_VIA_VT8237_VLINK,
208 };