summaryrefslogtreecommitdiffstats
path: root/src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c
blob: dd11810483e04193d2515b8d379f54410cb4ebca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
 * Copyright  2005 AMD
 *  by yinghai.lu@amd.com
 */

#if USE_FALLBACK_IMAGE == 1

static void bcm5785_enable_rom(void)
{
        unsigned char byte;
        uint32_t dword;
        uint16_t word;
        device_t addr;

        /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
        /* Locate the BCM 5785 SB PCI Main */
        addr = pci_locate_device(PCI_ID(0x1166, 0x0205), 0); // 0x0201?

        /* Set the 4MB enable bit bit */
        byte = pci_read_config8(addr, 0x41);
        byte |= 0x0e;
        pci_write_config8(addr, 0x41, byte);
}

static void bcm5785_enable_lpc(void)
{

        uint8_t byte;
        device_t dev;

        dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);

        /* LPC Control 0 */
        byte = pci_read_config8(dev, 0x44);
        /* Serial 0 */
        byte |= (1<<6);
        pci_write_config8(dev, 0x44, byte);

        /* LPC Control 4 */
        byte = pci_read_config8(dev, 0x48);
        /* superio port 0x2e/4e enable */
        byte |=(1<<1)|(1<<0);
        pci_write_config8(dev, 0x48, byte);
}
#endif /* USE_FALLBACK_IMAGE == 1 */


static void bcm5785_enable_wdt_port_cf9(void)
{
        device_t dev;
        uint32_t dword;
        uint32_t dword_old;

        dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);

        dword_old = pci_read_config32(dev, 0x4c);
        dword = dword_old | (1<<4); //enable Timer Func
        if(dword != dword_old ) {
                pci_write_config32(dev, 0x4c, dword);
        }

        dword_old = pci_read_config32(dev, 0x6c);
        dword = dword_old | (1<<9); //unhide Timer Func in pci space
        if(dword != dword_old ) {
                pci_write_config32(dev, 0x6c, dword);
        }

        dev = pci_locate_device(PCI_ID(0x1166, 0x0238), 0);

        /* enable cf9 */
        pci_write_config8(dev, 0x40, (1<<2));
}

static unsigned get_sbdn(unsigned bus)
{
        device_t dev;

        /* Find the device.
         * There can only be one 8111 on a hypertransport chain/bus.
         */
        dev = pci_locate_device_on_bus(
                PCI_ID(0x1166, 0x0036),
                bus);

        return (dev>>15) & 0x1f;

}

#define SB_VFSMAF 0

static void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
{
	//ACPI Decode Enable	
	outb(0x0e, 0xcd6);
	outb((1<<3), 0xcd7);

	// set port to 0x2060
	outb(0x67, 0xcd6);
	outb(0x60, 0xcd7);
        outb(0x68, 0xcd6);
        outb(0x20, 0xcd7);

	outb(0x69, 0xcd6);
	outb(7, 0xcd7);

	outb(0x64, 0xcd6);
	outb(9, 0xcd7);
}

static void ldtstop_sb(void)
{
	outb(1, 0x2060);
}


static void hard_reset(void)
{
        bcm5785_enable_wdt_port_cf9();

        set_bios_reset();

        /* full reset */
        outb(0x0a, 0x0cf9);
        outb(0x0e, 0x0cf9);
}

static void soft_reset(void)
{
        bcm5785_enable_wdt_port_cf9();

        set_bios_reset();
#if 1
        /* link reset */
//        outb(0x02, 0x0cf9);
        outb(0x06, 0x0cf9);
#endif
}



static void bcm5785_enable_msg(void)
{
        device_t dev;
        uint32_t dword;
        uint32_t dword_old;
        uint8_t byte;

        dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);

        byte = pci_read_config8(dev, 0x42);
        byte = (1<<1); //enable a20
        pci_write_config8(dev, 0x42, byte);

        dword_old = pci_read_config32(dev, 0x6c);
        // bit 5: enable A20 Message
        // bit 4: enable interrupt messages
        // bit 3: enable reset init message
        // bit 2: enable keyboard init message
        // bit 1: enable upsteam messages
        // bit 0: enable shutdowm message to init generation
        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
        if(dword != dword_old ) {
                pci_write_config32(dev, 0x6c, dword);
        }

}

static void bcm5785_early_setup(void)
{
        uint8_t byte;
        uint16_t word;
        uint32_t dword;
        device_t dev;

//F0
        // enable device on bcm5785 at first
        dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
        dword = pci_read_config32(dev, 0x64);
        dword |=  (1<<15) | (1<<11) | (1<<3); // ioapci enable
        dword |= (1<<8); // USB enable
        dword |= /* (1<<27)|*/(1<<14); // IDE enable
        pci_write_config32(dev, 0x64, dword);

        byte = pci_read_config8(dev, 0x84);
        byte |= (1<<0); // SATA enable
        pci_write_config8(dev, 0x84, byte);

// wdt and cf9 for later in coreboot_ram to call hard_reset
        bcm5785_enable_wdt_port_cf9();

        bcm5785_enable_msg();


#if 1
// IDE related
	//F0
        byte = pci_read_config8(dev, 0x4e);
        byte |= (1<<4); //enable IDE ext regs
        pci_write_config8(dev, 0x4e, byte);

	//F1
        dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0);
        byte = pci_read_config8(dev, 0x48);
        byte &= ~1; // disable pri channel
        pci_write_config8(dev, 0x48, byte);
        pci_write_config8(dev, 0xb0, 0x01);
        pci_write_config8(dev, 0xb2, 0x02);
        byte = pci_read_config8(dev, 0x06);
        byte |= (1<<4); // so b0, b2 can not be changed from now
        pci_write_config8(dev, 0x06, byte);
        byte = pci_read_config8(dev, 0x49);
        byte |= 1; // enable second channel
        pci_write_config8(dev, 0x49, byte);
#endif

//F2
        dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);

        byte = pci_read_config8(dev, 0x40);
        byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable
        pci_write_config8(dev, 0x40, byte);

        pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end

#if 1
// USB related
        pci_write_config8(dev, 0x90, 0x40);
        pci_write_config8(dev, 0x92, 0x06);
        pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register
        pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func
        pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func
        pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func
        pci_write_config8(dev, 0xb4, 0x40);
#endif
}