Add more missing GPL-headers, fix inconsistencies in others.
[coreboot.git] / src / southbridge / broadcom / bcm5785 / bcm5785_early_setup.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2005 AMD
5  * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
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 <reset.h>
22 #include "bcm5785.h"
23 #include "bcm5785_enable_rom.c"
24
25 static void bcm5785_enable_lpc(void)
26 {
27         uint8_t byte;
28         device_t dev;
29
30         dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
31
32         /* LPC Control 0 */
33         byte = pci_read_config8(dev, 0x44);
34         /* Serial 0 */
35         byte |= (1<<6);
36         pci_write_config8(dev, 0x44, byte);
37
38         /* LPC Control 4 */
39         byte = pci_read_config8(dev, 0x48);
40         /* superio port 0x2e/4e enable */
41         byte |=(1<<1)|(1<<0);
42         pci_write_config8(dev, 0x48, byte);
43 }
44
45 static void bcm5785_enable_wdt_port_cf9(void)
46 {
47         device_t dev;
48         uint32_t dword;
49         uint32_t dword_old;
50
51         dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
52
53         dword_old = pci_read_config32(dev, 0x4c);
54         dword = dword_old | (1<<4); //enable Timer Func
55         if(dword != dword_old ) {
56                 pci_write_config32(dev, 0x4c, dword);
57         }
58
59         dword_old = pci_read_config32(dev, 0x6c);
60         dword = dword_old | (1<<9); //unhide Timer Func in pci space
61         if(dword != dword_old ) {
62                 pci_write_config32(dev, 0x6c, dword);
63         }
64
65         dev = pci_locate_device(PCI_ID(0x1166, 0x0238), 0);
66
67         /* enable cf9 */
68         pci_write_config8(dev, 0x40, (1<<2));
69 }
70
71 unsigned get_sbdn(unsigned bus)
72 {
73         device_t dev;
74
75         /* Find the device.
76          * There can only be one bcm5785 on a hypertransport chain/bus.
77          */
78         dev = pci_locate_device_on_bus(
79                 PCI_ID(0x1166, 0x0036),
80                 bus);
81
82         return (dev>>15) & 0x1f;
83
84 }
85
86 #define SB_VFSMAF 0
87
88 void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
89 {
90         //ACPI Decode Enable
91         outb(0x0e, 0xcd6);
92         outb((1<<3), 0xcd7);
93
94         // set port to 0x2060
95         outb(0x67, 0xcd6);
96         outb(0x60, 0xcd7);
97         outb(0x68, 0xcd6);
98         outb(0x20, 0xcd7);
99
100         outb(0x69, 0xcd6);
101         outb(7, 0xcd7);
102
103         outb(0x64, 0xcd6);
104         outb(9, 0xcd7);
105 }
106
107 void ldtstop_sb(void)
108 {
109         outb(1, 0x2060);
110 }
111
112
113 void hard_reset(void)
114 {
115         bcm5785_enable_wdt_port_cf9();
116
117         set_bios_reset();
118
119         /* full reset */
120         outb(0x0a, 0x0cf9);
121         outb(0x0e, 0x0cf9);
122 }
123
124 void soft_reset(void)
125 {
126         bcm5785_enable_wdt_port_cf9();
127
128         set_bios_reset();
129 #if 1
130         /* link reset */
131 //        outb(0x02, 0x0cf9);
132         outb(0x06, 0x0cf9);
133 #endif
134 }
135
136 static void bcm5785_enable_msg(void)
137 {
138         device_t dev;
139         uint32_t dword;
140         uint32_t dword_old;
141         uint8_t byte;
142
143         dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
144
145         byte = pci_read_config8(dev, 0x42);
146         byte = (1<<1); //enable a20
147         pci_write_config8(dev, 0x42, byte);
148
149         dword_old = pci_read_config32(dev, 0x6c);
150         // bit 5: enable A20 Message
151         // bit 4: enable interrupt messages
152         // bit 3: enable reset init message
153         // bit 2: enable keyboard init message
154         // bit 1: enable upsteam messages
155         // bit 0: enable shutdowm message to init generation
156         dword = dword_old | (1<<5) | (1<<3) | (1<<2) | (1<<1) | (1<<0); // bit 1 and bit 4 must be set, otherwise interrupt msg will not be delivered to the processor
157         if(dword != dword_old ) {
158                 pci_write_config32(dev, 0x6c, dword);
159         }
160 }
161
162 static void bcm5785_early_setup(void)
163 {
164         uint8_t byte;
165         uint32_t dword;
166         device_t dev;
167
168 //F0
169         // enable device on bcm5785 at first
170         dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
171         dword = pci_read_config32(dev, 0x64);
172         dword |=  (1<<15) | (1<<11) | (1<<3); // ioapci enable
173         dword |= (1<<8); // USB enable
174         dword |= /* (1<<27)|*/(1<<14); // IDE enable
175         pci_write_config32(dev, 0x64, dword);
176
177         byte = pci_read_config8(dev, 0x84);
178         byte |= (1<<0); // SATA enable
179         pci_write_config8(dev, 0x84, byte);
180
181 // WDT and cf9 for later in coreboot_ram to call hard_reset
182         bcm5785_enable_wdt_port_cf9();
183
184         bcm5785_enable_msg();
185
186
187 // IDE related
188         //F0
189         byte = pci_read_config8(dev, 0x4e);
190         byte |= (1<<4); //enable IDE ext regs
191         pci_write_config8(dev, 0x4e, byte);
192
193         //F1
194         dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0);
195         byte = pci_read_config8(dev, 0x48);
196         byte &= ~1; // disable pri channel
197         pci_write_config8(dev, 0x48, byte);
198         pci_write_config8(dev, 0xb0, 0x01);
199         pci_write_config8(dev, 0xb2, 0x02);
200         byte = pci_read_config8(dev, 0x06);
201         byte |= (1<<4); // so b0, b2 can not be changed from now
202         pci_write_config8(dev, 0x06, byte);
203         byte = pci_read_config8(dev, 0x49);
204         byte |= 1; // enable second channel
205         pci_write_config8(dev, 0x49, byte);
206
207         //F2
208         dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
209
210         byte = pci_read_config8(dev, 0x40);
211         byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable
212         pci_write_config8(dev, 0x40, byte);
213
214         pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end
215
216 // USB related
217         pci_write_config8(dev, 0x90, 0x40);
218         pci_write_config8(dev, 0x92, 0x06);
219         pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register
220         pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func
221         pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func
222         pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func
223         pci_write_config8(dev, 0xb4, 0x40);
224 }