Revert my last cleanup patch.
[coreboot.git] / util / flashrom / chipset_enable.c
1 /*
2  * This file is part of the flashrom project.
3  *
4  * Copyright (C) 2000 Silicon Integrated System Corporation
5  * Copyright (C) 2005-2007 coresystems GmbH <stepan@coresystems.de>
6  * Copyright (C) 2006 Uwe Hermann <uwe@hermann-uwe.de>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20  */
21
22 /*
23  * Contains the chipset specific flash enables.
24  */
25
26 #include <stdio.h>
27 #include <pci/pci.h>
28 #include <stdlib.h>
29 #include "flash.h"
30
31 static int enable_flash_ali_m1533(struct pci_dev *dev, char *name)
32 {
33         uint8_t tmp;
34
35         /* ROM Write enable, 0xFFFC0000-0xFFFDFFFF and
36            0xFFFE0000-0xFFFFFFFF ROM select enable. */
37         tmp = pci_read_byte(dev, 0x47);
38         tmp |= 0x46;
39         pci_write_byte(dev, 0x47, tmp);
40
41         return 0;
42 }
43
44 static int enable_flash_sis630(struct pci_dev *dev, char *name)
45 {
46         char b;
47
48         /* Enable 0xFFF8000~0xFFFF0000 decoding on SiS 540/630 */
49         b = pci_read_byte(dev, 0x40);
50         pci_write_byte(dev, 0x40, b | 0xb);
51         /* Flash write enable on SiS 540/630 */
52         b = pci_read_byte(dev, 0x45);
53         pci_write_byte(dev, 0x45, b | 0x40);
54
55         /* The same thing on SiS 950 SuperIO side */
56         outb(0x87, 0x2e);
57         outb(0x01, 0x2e);
58         outb(0x55, 0x2e);
59         outb(0x55, 0x2e);
60
61         if (inb(0x2f) != 0x87) {
62                 outb(0x87, 0x4e);
63                 outb(0x01, 0x4e);
64                 outb(0x55, 0x4e);
65                 outb(0xaa, 0x4e);
66                 if (inb(0x4f) != 0x87) {
67                         printf("Can not access SiS 950\n");
68                         return -1;
69                 }
70                 outb(0x24, 0x4e);
71                 b = inb(0x4f) | 0xfc;
72                 outb(0x24, 0x4e);
73                 outb(b, 0x4f);
74                 outb(0x02, 0x4e);
75                 outb(0x02, 0x4f);
76         }
77
78         outb(0x24, 0x2e);
79         printf("2f is %#x\n", inb(0x2f));
80         b = inb(0x2f) | 0xfc;
81         outb(0x24, 0x2e);
82         outb(b, 0x2f);
83
84         outb(0x02, 0x2e);
85         outb(0x02, 0x2f);
86
87         return 0;
88 }
89
90 /* Datasheet:
91  *   - Name: 82371AB PCI-TO-ISA / IDE XCELERATOR (PIIX4)
92  *   - URL: http://www.intel.com/design/intarch/datashts/290562.htm
93  *   - PDF: http://www.intel.com/design/intarch/datashts/29056201.pdf
94  *   - Order Number: 290562-001
95  */
96 static int enable_flash_piix4(struct pci_dev *dev, char *name)
97 {
98         uint16_t old, new;
99         uint16_t xbcs = 0x4e;   /* X-Bus Chip Select register. */
100
101         old = pci_read_word(dev, xbcs);
102
103         /* Set bit 9: 1-Meg Extended BIOS Enable (PCI master accesses to
104          *            FFF00000-FFF7FFFF are forwarded to ISA).
105          * Set bit 7: Extended BIOS Enable (PCI master accesses to
106          *            FFF80000-FFFDFFFF are forwarded to ISA).
107          * Set bit 6: Lower BIOS Enable (PCI master, or ISA master accesses to
108          *            the lower 64-Kbyte BIOS block (E0000-EFFFF) at the top
109          *            of 1 Mbyte, or the aliases at the top of 4 Gbyte
110          *            (FFFE0000-FFFEFFFF) result in the generation of BIOSCS#.
111          * Note: Accesses to FFFF0000-FFFFFFFF are always forwarded to ISA.
112          * Set bit 2: BIOSCS# Write Enable (1=enable, 0=disable).
113          */
114         new = old | 0x2c4;
115
116         if (new == old)
117                 return 0;
118
119         pci_write_word(dev, xbcs, new);
120
121         if (pci_read_word(dev, xbcs) != new) {
122                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", xbcs, new, name);
123                 return -1;
124         }
125
126         return 0;
127 }
128
129 static int enable_flash_ich(struct pci_dev *dev, char *name, int bios_cntl)
130 {
131         /* register 4e.b gets or'ed with one */
132         uint8_t old, new;
133
134         /* if it fails, it fails. There are so many variations of broken mobos
135          * that it is hard to argue that we should quit at this point.
136          */
137
138         /* Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, but
139          * just treating it as 8 bit wide seems to work fine in practice.
140          */
141
142         /* see ie. page 375 of "Intel ICH7 External Design Specification"
143          * http://download.intel.com/design/chipsets/datashts/30701302.pdf
144          */
145
146         old = pci_read_byte(dev, bios_cntl);
147
148         new = old | 1;
149
150         if (new == old)
151                 return 0;
152
153         pci_write_byte(dev, bios_cntl, new);
154
155         if (pci_read_byte(dev, bios_cntl) != new) {
156                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", bios_cntl, new, name);
157                 return -1;
158         }
159
160         return 0;
161 }
162
163 static int enable_flash_ich_4e(struct pci_dev *dev, char *name)
164 {
165         return enable_flash_ich(dev, name, 0x4e);
166 }
167
168 static int enable_flash_ich_dc(struct pci_dev *dev, char *name)
169 {
170         return enable_flash_ich(dev, name, 0xdc);
171 }
172
173 static int enable_flash_vt823x(struct pci_dev *dev, char *name)
174 {
175         uint8_t val;
176
177         /* ROM write enable */
178         val = pci_read_byte(dev, 0x40);
179         val |= 0x10;
180         pci_write_byte(dev, 0x40, val);
181
182         if (pci_read_byte(dev, 0x40) != val) {
183                 printf("\nWARNING: Failed to enable ROM Write on \"%s\"\n",
184                        name);
185                 return -1;
186         }
187
188         return 0;
189 }
190
191 static int enable_flash_cs5530(struct pci_dev *dev, char *name)
192 {
193         uint8_t reg8;
194
195         #define DECODE_CONTROL_REG2             0x5b    /* F0 index 0x5b */
196         #define ROM_AT_LOGIC_CONTROL_REG        0x52    /* F0 index 0x52 */
197
198         #define LOWER_ROM_ADDRESS_RANGE         (1 << 0)
199         #define ROM_WRITE_ENABLE                (1 << 1)
200         #define UPPER_ROM_ADDRESS_RANGE         (1 << 2)
201         #define BIOS_ROM_POSITIVE_DECODE        (1 << 5)
202
203         /* Decode 0x000E0000-0x000FFFFF (128 KB), not just 64 KB, and
204          * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 KB.
205          * Make the configured ROM areas writable.
206          */
207         reg8 = pci_read_byte(dev, ROM_AT_LOGIC_CONTROL_REG);
208         reg8 |= LOWER_ROM_ADDRESS_RANGE;
209         reg8 |= UPPER_ROM_ADDRESS_RANGE;
210         reg8 |= ROM_WRITE_ENABLE;
211         pci_write_byte(dev, ROM_AT_LOGIC_CONTROL_REG, reg8);
212
213         /* Set positive decode on ROM. */
214         reg8 = pci_read_byte(dev, DECODE_CONTROL_REG2);
215         reg8 |= BIOS_ROM_POSITIVE_DECODE;
216         pci_write_byte(dev, DECODE_CONTROL_REG2, reg8);
217
218         return 0;
219 }
220
221 static int enable_flash_sc1100(struct pci_dev *dev, char *name)
222 {
223         uint8_t new;
224
225         pci_write_byte(dev, 0x52, 0xee);
226
227         new = pci_read_byte(dev, 0x52);
228
229         if (new != 0xee) {
230                 printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 0x52, new, name);
231                 return -1;
232         }
233
234         return 0;
235 }
236
237 static int enable_flash_sis5595(struct pci_dev *dev, char *name)
238 {
239         uint8_t new, newer;
240
241         new = pci_read_byte(dev, 0x45);
242
243         /* clear bit 5 */
244         new &= (~0x20);
245         /* set bit 2 */
246         new |= 0x4;
247
248         pci_write_byte(dev, 0x45, new);
249
250         newer = pci_read_byte(dev, 0x45);
251         if (newer != new) {
252                 printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 0x45, new, name);
253                 printf("Stuck at 0x%x\n", newer);
254                 return -1;
255         }
256
257         return 0;
258 }
259
260 static int enable_flash_amd8111(struct pci_dev *dev, char *name)
261 {
262         /* register 4e.b gets or'ed with one */
263         uint8_t old, new;
264
265         /* if it fails, it fails. There are so many variations of broken mobos
266          * that it is hard to argue that we should quit at this point.
267          */
268
269         /* enable decoding at 0xffb00000 to 0xffffffff */
270         old = pci_read_byte(dev, 0x43);
271         new = old | 0xC0;
272         if (new != old) {
273                 pci_write_byte(dev, 0x43, new);
274                 if (pci_read_byte(dev, 0x43) != new) {
275                         printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 0x43, new, name);
276                 }
277         }
278
279         old = pci_read_byte(dev, 0x40);
280         new = old | 0x01;
281         if (new == old)
282                 return 0;
283         pci_write_byte(dev, 0x40, new);
284
285         if (pci_read_byte(dev, 0x40) != new) {
286                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 0x40, new, name);
287                 return -1;
288         }
289
290         return 0;
291 }
292
293 static int enable_flash_ck804(struct pci_dev *dev, char *name)
294 {
295         /* register 4e.b gets or'ed with one */
296         uint8_t old, new;
297
298         /* if it fails, it fails. There are so many variations of broken mobos
299          * that it is hard to argue that we should quit at this point.
300          */
301
302         /* dump_pci_device(dev); */
303
304         old = pci_read_byte(dev, 0x88);
305         new = old | 0xc0;
306         if (new != old) {
307                 pci_write_byte(dev, 0x88, new);
308                 if (pci_read_byte(dev, 0x88) != new) {
309                         printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 0x88, new, name);
310                 }
311         }
312
313         old = pci_read_byte(dev, 0x6d);
314         new = old | 0x01;
315         if (new == old)
316                 return 0;
317         pci_write_byte(dev, 0x6d, new);
318
319         if (pci_read_byte(dev, 0x6d) != new) {
320                 printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 0x6d, new, name);
321                 return -1;
322         }
323
324         return 0;
325 }
326
327 static int enable_flash_sb400(struct pci_dev *dev, char *name)
328 {
329         uint8_t tmp;
330
331         struct pci_filter f;
332         struct pci_dev *smbusdev;
333
334         /* then look for the smbus device */
335         pci_filter_init((struct pci_access *)0, &f);
336         f.vendor = 0x1002;
337         f.device = 0x4372;
338
339         for (smbusdev = pacc->devices; smbusdev; smbusdev = smbusdev->next) {
340                 if (pci_filter_match(&f, smbusdev)) {
341                         break;
342                 }
343         }
344
345         if (!smbusdev) {
346                 fprintf(stderr, "ERROR: SMBus device not found. aborting\n");
347                 exit(1);
348         }
349
350         /* enable some smbus stuff */
351         tmp = pci_read_byte(smbusdev, 0x79);
352         tmp |= 0x01;
353         pci_write_byte(smbusdev, 0x79, tmp);
354
355         /* change southbridge */
356         tmp = pci_read_byte(dev, 0x48);
357         tmp |= 0x21;
358         pci_write_byte(dev, 0x48, tmp);
359
360         /* now become a bit silly. */
361         tmp = inb(0xc6f);
362         outb(tmp, 0xeb);
363         outb(tmp, 0xeb);
364         tmp |= 0x40;
365         outb(tmp, 0xc6f);
366         outb(tmp, 0xeb);
367         outb(tmp, 0xeb);
368
369         return 0;
370 }
371
372 static int enable_flash_mcp55(struct pci_dev *dev, char *name)
373 {
374         /* register 4e.b gets or'ed with one */
375         unsigned char old, new, byte;
376         unsigned short word;
377
378         /* if it fails, it fails. There are so many variations of broken mobos
379          * that it is hard to argue that we should quit at this point.
380          */
381
382         /* dump_pci_device(dev); */
383
384         /* Set the 4MB enable bit bit */
385         byte = pci_read_byte(dev, 0x88);
386         byte |= 0xff;           /* 256K */
387         pci_write_byte(dev, 0x88, byte);
388         byte = pci_read_byte(dev, 0x8c);
389         byte |= 0xff;           /* 1M */
390         pci_write_byte(dev, 0x8c, byte);
391         word = pci_read_word(dev, 0x90);
392         word |= 0x7fff;         /* 15M */
393         pci_write_word(dev, 0x90, word);
394
395         old = pci_read_byte(dev, 0x6d);
396         new = old | 0x01;
397         if (new == old)
398                 return 0;
399         pci_write_byte(dev, 0x6d, new);
400
401         if (pci_read_byte(dev, 0x6d) != new) {
402                 printf
403                     ("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
404                      0x6d, new, name);
405                 return -1;
406         }
407
408         return 0;
409 }
410
411 static int enable_flash_ht1000(struct pci_dev *dev, char *name)
412 {
413         uint8_t byte;
414
415         /* Set the 4MB enable bit. */
416         byte = pci_read_byte(dev, 0x41);
417         byte |= 0x0e;
418         pci_write_byte(dev, 0x41, byte);
419
420         byte = pci_read_byte(dev, 0x43);
421         byte |= (1 << 4);
422         pci_write_byte(dev, 0x43, byte);
423
424         return 0;
425 }
426
427 typedef struct penable {
428         unsigned short vendor, device;
429         char *name;
430         int (*doit) (struct pci_dev * dev, char *name);
431 } FLASH_ENABLE;
432
433 static FLASH_ENABLE enables[] = {
434         {0x1039, 0x0630, "SIS630", enable_flash_sis630},
435         {0x8086, 0x7110, "PIIX4/PIIX4E/PIIX4M", enable_flash_piix4},
436         {0x8086, 0x2410, "ICH", enable_flash_ich_4e},
437         {0x8086, 0x2420, "ICH0", enable_flash_ich_4e},
438         {0x8086, 0x2440, "ICH2", enable_flash_ich_4e},
439         {0x8086, 0x244c, "ICH2-M", enable_flash_ich_4e},
440         {0x8086, 0x2480, "ICH3-S", enable_flash_ich_4e},
441         {0x8086, 0x248c, "ICH3-M", enable_flash_ich_4e},
442         {0x8086, 0x24c0, "ICH4/ICH4-L", enable_flash_ich_4e},
443         {0x8086, 0x24cc, "ICH4-M", enable_flash_ich_4e},
444         {0x8086, 0x24d0, "ICH5/ICH5R", enable_flash_ich_4e},
445         {0x8086, 0x2640, "ICH6/ICH6R", enable_flash_ich_dc},
446         {0x8086, 0x2641, "ICH6-M", enable_flash_ich_dc},
447         {0x8086, 0x27b0, "ICH7DH", enable_flash_ich_dc},
448         {0x8086, 0x27b8, "ICH7/ICH7R", enable_flash_ich_dc},
449         {0x8086, 0x27b9, "ICH7M", enable_flash_ich_dc},
450         {0x8086, 0x27bd, "ICH7MDH", enable_flash_ich_dc},
451         {0x8086, 0x2810, "ICH8/ICH8R", enable_flash_ich_dc},
452         {0x8086, 0x2812, "ICH8DH", enable_flash_ich_dc},
453         {0x8086, 0x2814, "ICH8DO", enable_flash_ich_dc},
454         {0x1106, 0x8231, "VT8231", enable_flash_vt823x},
455         {0x1106, 0x3177, "VT8235", enable_flash_vt823x},
456         {0x1106, 0x3227, "VT8237", enable_flash_vt823x},
457         {0x1106, 0x8324, "CX700", enable_flash_vt823x},
458         {0x1106, 0x0686, "VT82C686", enable_flash_amd8111},
459         {0x1078, 0x0100, "CS5530/CS5530A", enable_flash_cs5530},
460         {0x100b, 0x0510, "SC1100", enable_flash_sc1100},
461         {0x1039, 0x0008, "SIS5595", enable_flash_sis5595},
462         {0x1022, 0x7468, "AMD8111", enable_flash_amd8111},
463         {0x10B9, 0x1533, "ALi M1533", enable_flash_ali_m1533},
464         /* this fallthrough looks broken. */
465         {0x10de, 0x0050, "NVIDIA CK804", enable_flash_ck804},   /* LPC */
466         {0x10de, 0x0051, "NVIDIA CK804", enable_flash_ck804},   /* Pro */
467         {0x10de, 0x00d3, "NVIDIA CK804", enable_flash_ck804},   /* Slave, should not be here, to fix known bug for A01. */
468
469         {0x10de, 0x0260, "NVidia MCP51", enable_flash_ck804},
470         {0x10de, 0x0261, "NVidia MCP51", enable_flash_ck804},
471         {0x10de, 0x0262, "NVidia MCP51", enable_flash_ck804},
472         {0x10de, 0x0263, "NVidia MCP51", enable_flash_ck804},
473
474         {0x10de, 0x0360, "NVIDIA MCP55", enable_flash_mcp55},   /* Gigabyte m57sli-s4 */
475         {0x10de, 0x0361, "NVIDIA MCP55", enable_flash_mcp55},   /* LPC */
476         {0x10de, 0x0362, "NVIDIA MCP55", enable_flash_mcp55},   /* LPC */
477         {0x10de, 0x0363, "NVIDIA MCP55", enable_flash_mcp55},   /* LPC */
478         {0x10de, 0x0364, "NVIDIA MCP55", enable_flash_mcp55},   /* LPC */
479         {0x10de, 0x0365, "NVIDIA MCP55", enable_flash_mcp55},   /* LPC */
480         {0x10de, 0x0366, "NVIDIA MCP55", enable_flash_mcp55},   /* LPC */
481         {0x10de, 0x0367, "NVIDIA MCP55", enable_flash_mcp55},   /* Pro */
482
483         {0x1002, 0x4377, "ATI SB400", enable_flash_sb400},      /* ATI Technologies Inc IXP SB400 PCI-ISA Bridge (rev 80) */
484
485         {0x1166, 0x0205, "Broadcom HT-1000", enable_flash_ht1000},
486 };
487
488 int chipset_flash_enable(void)
489 {
490         struct pci_dev *dev = 0;
491         int ret = -2;           /* nothing! */
492         int i;
493
494         /* now let's try to find the chipset we have ... */
495         for (i = 0; i < sizeof(enables) / sizeof(enables[0]); i++) {
496                 dev = pci_dev_find(enables[i].vendor, enables[i].device);
497                 if (dev)
498                         break;
499         }
500
501         if (dev) {
502                 printf("Found chipset \"%s\": Enabling flash write... ",
503                        enables[i].name);
504
505                 ret = enables[i].doit(dev, enables[i].name);
506                 if (ret)
507                         printf("Failed!\n");
508                 else
509                         printf("OK.\n");
510         }
511
512         return ret;
513 }