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