Use common GPL-header format in CK804 files, add missing ones (trivial).
[coreboot.git] / src / southbridge / nvidia / ck804 / ck804.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2004 Tyan Computer
5  * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; version 2 of the License.
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, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #include <console/console.h>
22 #include <arch/io.h>
23 #include <device/device.h>
24 #include <device/pci.h>
25 #include <device/pci_ids.h>
26 #include <device/pci_ops.h>
27 #include "ck804.h"
28
29 static uint32_t final_reg;
30
31 static device_t find_lpc_dev(device_t dev, unsigned devfn)
32 {
33         device_t lpc_dev;
34
35         lpc_dev = dev_find_slot(dev->bus->secondary, devfn);
36         if (!lpc_dev)
37                 return lpc_dev;
38
39         if ((lpc_dev->vendor != PCI_VENDOR_ID_NVIDIA)
40                 || ((lpc_dev->device != PCI_DEVICE_ID_NVIDIA_CK804_LPC)
41                 && (lpc_dev->device != PCI_DEVICE_ID_NVIDIA_CK804_PRO)
42                 && (lpc_dev->device != PCI_DEVICE_ID_NVIDIA_CK804_SLAVE)))
43         {
44                 uint32_t id;
45                 id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
46                 if ((id != (PCI_VENDOR_ID_NVIDIA |
47                       (PCI_DEVICE_ID_NVIDIA_CK804_LPC << 16)))
48                     && (id != (PCI_VENDOR_ID_NVIDIA |
49                          (PCI_DEVICE_ID_NVIDIA_CK804_PRO << 16)))
50                     && (id != (PCI_VENDOR_ID_NVIDIA |
51                          (PCI_DEVICE_ID_NVIDIA_CK804_SLAVE << 16))))
52                 {
53                         lpc_dev = 0;
54                 }
55         }
56
57         return lpc_dev;
58 }
59
60 void ck804_enable(device_t dev)
61 {
62         device_t lpc_dev;
63         unsigned index = 0, index2 = 0, deviceid, vendorid, devfn;
64         uint32_t reg_old, reg;
65         uint8_t byte;
66
67         struct southbridge_nvidia_ck804_config *conf;
68         conf = dev->chip_info;
69
70         if (dev->device == 0x0000) {
71                 vendorid = pci_read_config32(dev, PCI_VENDOR_ID);
72                 deviceid = (vendorid >> 16) & 0xffff;
73                 /* vendorid &= 0xffff; */
74         } else {
75                 /* vendorid = dev->vendor; */
76                 deviceid = dev->device;
77         }
78
79         devfn = (dev->path.pci.devfn) & ~7;
80         switch (deviceid) {
81         case PCI_DEVICE_ID_NVIDIA_CK804_SM:
82                 index = 16;
83                 break;
84         case PCI_DEVICE_ID_NVIDIA_CK804_USB:
85                 devfn -= (1 << 3);
86                 index = 8;
87                 break;
88         case PCI_DEVICE_ID_NVIDIA_CK804_USB2:
89                 devfn -= (1 << 3);
90                 index = 20;
91                 break;
92         case PCI_DEVICE_ID_NVIDIA_CK804_NIC:
93                 devfn -= (9 << 3);
94                 index = 10;
95                 break;
96         case PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE:
97                 devfn -= (9 << 3);
98                 index = 10;
99                 break;
100         case PCI_DEVICE_ID_NVIDIA_CK804_ACI:
101                 devfn -= (3 << 3);
102                 index = 12;
103                 break;
104         case PCI_DEVICE_ID_NVIDIA_CK804_MCI:
105                 devfn -= (3 << 3);
106                 index = 13;
107                 break;
108         case PCI_DEVICE_ID_NVIDIA_CK804_IDE:
109                 devfn -= (5 << 3);
110                 index = 14;
111                 break;
112         case PCI_DEVICE_ID_NVIDIA_CK804_SATA0:
113                 devfn -= (6 << 3);
114                 index = 22;
115                 break;
116         case PCI_DEVICE_ID_NVIDIA_CK804_SATA1:
117                 devfn -= (7 << 3);
118                 index = 18;
119                 break;
120         case PCI_DEVICE_ID_NVIDIA_CK804_PCI:
121                 devfn -= (8 << 3);
122                 index = 15;
123                 break;
124         case PCI_DEVICE_ID_NVIDIA_CK804_PCI_E:
125                 devfn -= (0xa << 3);
126                 index2 = 19;
127                 break;
128         default:
129                 index = 0;
130         }
131
132         if (index2 != 0) {
133                 int i;
134                 for (i = 0; i < 4; i++) {
135                         lpc_dev = find_lpc_dev(dev, devfn - (i << 3));
136                         if (!lpc_dev)
137                                 continue;
138                         index2 -= i;
139                         break;
140                 }
141
142                 if (lpc_dev) {
143                         reg_old = reg = pci_read_config32(lpc_dev, 0xe4);
144                         if (!dev->enabled)
145                                 reg |= (1 << index2);
146                         if (reg != reg_old)
147                                 pci_write_config32(lpc_dev, 0xe4, reg);
148                 }
149
150                 index2 = 0;
151                 return;
152         }
153
154         lpc_dev = find_lpc_dev(dev, devfn);
155         if (!lpc_dev)
156                 return;
157
158         if (index == 0) {
159                 final_reg = pci_read_config32(lpc_dev, 0xe8);
160                 final_reg &= ~((1 << 16) | (1 << 8) | (1 << 20) | (1 << 10)
161                         | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 22)
162                         | (1 << 18) | (1 << 15));
163                 pci_write_config32(lpc_dev, 0xe8, final_reg);
164
165                 reg_old = reg = pci_read_config32(lpc_dev, 0xe4);
166                 reg |= (1 << 20);
167                 if (reg != reg_old)
168                         pci_write_config32(lpc_dev, 0xe4, reg);
169
170                 byte = pci_read_config8(lpc_dev, 0x74);
171                 byte |= ((1 << 1));
172                 pci_write_config8(dev, 0x74, byte);
173
174                 byte = pci_read_config8(lpc_dev, 0xdd);
175                 byte |= ((1 << 0) | (1 << 3));
176                 pci_write_config8(dev, 0xdd, byte);
177
178                 return;
179         }
180
181         if (!dev->enabled)
182                 final_reg |= (1 << index);
183
184         if (index == 10) {
185                 reg_old = pci_read_config32(lpc_dev, 0xe8);
186                 if (final_reg != reg_old)
187                         pci_write_config32(lpc_dev, 0xe8, final_reg);
188         }
189 }
190
191 struct chip_operations southbridge_nvidia_ck804_ops = {
192         CHIP_NAME("NVIDIA CK804 Southbridge")
193         .enable_dev = ck804_enable,
194 };