blob: e29fab470092e1f5a19cdb1193e6f35e6257d040 [file] [log] [blame]
Yinghai Luafd34e62006-02-16 17:22:19 +00001/*
Uwe Hermannc6a10622010-10-17 19:30:58 +00002 * 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.
Yinghai Luafd34e62006-02-16 17:22:19 +000015 */
16
Stefan Reinauer2c0db452010-04-09 15:29:13 +000017#include <reset.h>
Stefan Reinauer6f57b512010-07-08 16:41:05 +000018#include "bcm5785.h"
Yinghai Luafd34e62006-02-16 17:22:19 +000019
20static void bcm5785_enable_lpc(void)
21{
Yinghai Luafd34e62006-02-16 17:22:19 +000022 uint8_t byte;
23 device_t dev;
24
25 dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
26
27 /* LPC Control 0 */
28 byte = pci_read_config8(dev, 0x44);
29 /* Serial 0 */
30 byte |= (1<<6);
31 pci_write_config8(dev, 0x44, byte);
32
33 /* LPC Control 4 */
34 byte = pci_read_config8(dev, 0x48);
35 /* superio port 0x2e/4e enable */
36 byte |=(1<<1)|(1<<0);
37 pci_write_config8(dev, 0x48, byte);
38}
Yinghai Luafd34e62006-02-16 17:22:19 +000039
40static void bcm5785_enable_wdt_port_cf9(void)
41{
42 device_t dev;
43 uint32_t dword;
44 uint32_t dword_old;
45
46 dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
47
48 dword_old = pci_read_config32(dev, 0x4c);
49 dword = dword_old | (1<<4); //enable Timer Func
50 if(dword != dword_old ) {
51 pci_write_config32(dev, 0x4c, dword);
52 }
53
54 dword_old = pci_read_config32(dev, 0x6c);
55 dword = dword_old | (1<<9); //unhide Timer Func in pci space
56 if(dword != dword_old ) {
57 pci_write_config32(dev, 0x6c, dword);
58 }
59
60 dev = pci_locate_device(PCI_ID(0x1166, 0x0238), 0);
61
62 /* enable cf9 */
63 pci_write_config8(dev, 0x40, (1<<2));
64}
65
Stefan Reinauer6f57b512010-07-08 16:41:05 +000066unsigned get_sbdn(unsigned bus)
Yinghai Lud4b278c2006-10-04 20:46:15 +000067{
68 device_t dev;
69
70 /* Find the device.
Stefan Reinauer6f57b512010-07-08 16:41:05 +000071 * There can only be one bcm5785 on a hypertransport chain/bus.
Yinghai Lud4b278c2006-10-04 20:46:15 +000072 */
73 dev = pci_locate_device_on_bus(
74 PCI_ID(0x1166, 0x0036),
75 bus);
76
77 return (dev>>15) & 0x1f;
78
79}
80
81#define SB_VFSMAF 0
82
Stefan Reinauer6f57b512010-07-08 16:41:05 +000083void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
Yinghai Lud4b278c2006-10-04 20:46:15 +000084{
Stefan Reinauer14e22772010-04-27 06:56:47 +000085 //ACPI Decode Enable
Yinghai Lud4b278c2006-10-04 20:46:15 +000086 outb(0x0e, 0xcd6);
87 outb((1<<3), 0xcd7);
88
89 // set port to 0x2060
90 outb(0x67, 0xcd6);
91 outb(0x60, 0xcd7);
92 outb(0x68, 0xcd6);
93 outb(0x20, 0xcd7);
94
95 outb(0x69, 0xcd6);
96 outb(7, 0xcd7);
97
98 outb(0x64, 0xcd6);
99 outb(9, 0xcd7);
100}
101
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000102void ldtstop_sb(void)
Yinghai Lud4b278c2006-10-04 20:46:15 +0000103{
104 outb(1, 0x2060);
105}
106
107
Stefan Reinauerc51dc442010-04-07 01:44:04 +0000108void hard_reset(void)
Yinghai Luafd34e62006-02-16 17:22:19 +0000109{
110 bcm5785_enable_wdt_port_cf9();
111
112 set_bios_reset();
113
114 /* full reset */
115 outb(0x0a, 0x0cf9);
116 outb(0x0e, 0x0cf9);
117}
118
Stefan Reinauerc51dc442010-04-07 01:44:04 +0000119void soft_reset(void)
Yinghai Luafd34e62006-02-16 17:22:19 +0000120{
121 bcm5785_enable_wdt_port_cf9();
122
123 set_bios_reset();
124#if 1
125 /* link reset */
126// outb(0x02, 0x0cf9);
127 outb(0x06, 0x0cf9);
128#endif
129}
130
Yinghai Luafd34e62006-02-16 17:22:19 +0000131static void bcm5785_enable_msg(void)
132{
133 device_t dev;
134 uint32_t dword;
135 uint32_t dword_old;
136 uint8_t byte;
137
138 dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
139
140 byte = pci_read_config8(dev, 0x42);
141 byte = (1<<1); //enable a20
142 pci_write_config8(dev, 0x42, byte);
143
144 dword_old = pci_read_config32(dev, 0x6c);
145 // bit 5: enable A20 Message
146 // bit 4: enable interrupt messages
147 // bit 3: enable reset init message
148 // bit 2: enable keyboard init message
149 // bit 1: enable upsteam messages
150 // bit 0: enable shutdowm message to init generation
151 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
152 if(dword != dword_old ) {
153 pci_write_config32(dev, 0x6c, dword);
154 }
Yinghai Luafd34e62006-02-16 17:22:19 +0000155}
156
157static void bcm5785_early_setup(void)
158{
159 uint8_t byte;
Yinghai Luafd34e62006-02-16 17:22:19 +0000160 uint32_t dword;
161 device_t dev;
162
163//F0
164 // enable device on bcm5785 at first
165 dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
166 dword = pci_read_config32(dev, 0x64);
167 dword |= (1<<15) | (1<<11) | (1<<3); // ioapci enable
168 dword |= (1<<8); // USB enable
169 dword |= /* (1<<27)|*/(1<<14); // IDE enable
170 pci_write_config32(dev, 0x64, dword);
171
172 byte = pci_read_config8(dev, 0x84);
173 byte |= (1<<0); // SATA enable
174 pci_write_config8(dev, 0x84, byte);
175
Furquan Shaikh20f25dd2014-04-22 10:41:05 -0700176// WDT and cf9 for later in ramstage to call hard_reset
Yinghai Luafd34e62006-02-16 17:22:19 +0000177 bcm5785_enable_wdt_port_cf9();
178
179 bcm5785_enable_msg();
180
181
Yinghai Luafd34e62006-02-16 17:22:19 +0000182// IDE related
183 //F0
184 byte = pci_read_config8(dev, 0x4e);
185 byte |= (1<<4); //enable IDE ext regs
186 pci_write_config8(dev, 0x4e, byte);
187
188 //F1
189 dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0);
190 byte = pci_read_config8(dev, 0x48);
191 byte &= ~1; // disable pri channel
192 pci_write_config8(dev, 0x48, byte);
193 pci_write_config8(dev, 0xb0, 0x01);
194 pci_write_config8(dev, 0xb2, 0x02);
195 byte = pci_read_config8(dev, 0x06);
196 byte |= (1<<4); // so b0, b2 can not be changed from now
197 pci_write_config8(dev, 0x06, byte);
198 byte = pci_read_config8(dev, 0x49);
199 byte |= 1; // enable second channel
200 pci_write_config8(dev, 0x49, byte);
Yinghai Luafd34e62006-02-16 17:22:19 +0000201
Stefan Reinauerc51dc442010-04-07 01:44:04 +0000202 //F2
Yinghai Luafd34e62006-02-16 17:22:19 +0000203 dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
204
205 byte = pci_read_config8(dev, 0x40);
206 byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable
207 pci_write_config8(dev, 0x40, byte);
208
209 pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end
210
Yinghai Luafd34e62006-02-16 17:22:19 +0000211// USB related
212 pci_write_config8(dev, 0x90, 0x40);
213 pci_write_config8(dev, 0x92, 0x06);
214 pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register
215 pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func
216 pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func
217 pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func
218 pci_write_config8(dev, 0xb4, 0x40);
Yinghai Luafd34e62006-02-16 17:22:19 +0000219}