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