- Bump the LinuxBIOS major version
[coreboot.git] / src / northbridge / via / vt8601 / northbridge.c
1 #include <console/console.h>
2 #include <arch/io.h>
3 #include <stdint.h>
4 #include <mem.h>
5 #include <part/sizeram.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/hypertransport.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <bitops.h>
12 #include "chip.h"
13 #include "northbridge.h"
14
15 static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
16                                         0x56, 0x57};
17
18 struct mem_range *sizeram(void)
19 {
20         unsigned long mmio_basek;
21         static struct mem_range mem[10];
22         device_t dev;
23         int i, idx;
24         unsigned char rambits;
25
26         dev = dev_find_slot(0, 0);
27         if (!dev) {
28                 printk_err("Cannot find PCI: 0:0\n");
29                 return 0;
30         }
31         mem[0].basek = 0;
32         mem[0].sizek = 65536;
33         idx = 1;
34         while(idx < sizeof(mem)/sizeof(mem[0])) {
35                 mem[idx].basek = 0;
36                 mem[idx].sizek = 0;
37                 idx++;
38         }
39         for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
40                 unsigned char reg;
41                 reg = pci_read_config8(dev, ramregs[i]);
42                 /* these are ENDING addresses, not sizes. 
43                  * if there is memory in this slot, then reg will be > rambits.
44                  * So we just take the max, that gives us total. 
45                  * We take the highest one to cover for once and future linuxbios
46                  * bugs. We warn about bugs.
47                  */
48                 if (reg > rambits)
49                         rambits = reg;
50                 if (reg < rambits)
51                         printk_err("ERROR! register 0x%x is not set!\n", 
52                                 ramregs[i]);
53         }
54         
55         printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
56         mem[0].sizek = rambits*8*1024;
57 #if 1
58         for(i = 0; i < idx; i++) {
59                 printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
60                         i, mem[i].basek, i, mem[i].sizek);
61         }
62 #endif
63
64         return mem;
65 }
66
67 /*
68  * This fixup is based on capturing values from an Award bios.  Without
69  * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x
70  * slower than normal, ethernet drops packets).
71  * Apparently these registers govern some sort of bus master behavior.
72  */
73 static void random_fixup() {
74         device_t pcidev = dev_find_slot(0, 0);
75
76         printk_spew("VT8601 random fixup ...\n");
77         if (pcidev) {
78                 pci_write_config8(pcidev, 0x70, 0xc0);
79                 pci_write_config8(pcidev, 0x71, 0x88);
80                 pci_write_config8(pcidev, 0x72, 0xec);
81                 pci_write_config8(pcidev, 0x73, 0x0c);
82                 pci_write_config8(pcidev, 0x74, 0x0e);
83                 pci_write_config8(pcidev, 0x75, 0x81);
84                 pci_write_config8(pcidev, 0x76, 0x52);
85         }
86 }
87
88 static void northbridge_init(struct chip *chip, enum chip_pass pass)
89 {
90
91         struct northbridge_via_vt8601_config *conf = 
92                 (struct northbridge_via_vt8601_config *)chip->chip_info;
93
94         switch (pass) {
95         case CONF_PASS_PRE_PCI:
96                 break;
97                 
98         case CONF_PASS_POST_PCI:
99                 break;
100                 
101         case CONF_PASS_PRE_BOOT:
102                 random_fixup();
103                 break;
104                 
105         default:
106                 /* nothing yet */
107                 break;
108         }
109 }
110
111 struct chip_operations northbridge_via_vt8601_control = {
112         .enable    = northbridge_init,
113         .name      = "VIA vt8601 Northbridge",
114 };