- First stab at running linuxbios without the old static device tree.
[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 static void enumerate(struct chip *chip)
67 {
68         extern struct device_operations default_pci_ops_bus;
69         chip_enumerate(chip);
70         chip->dev->ops = &default_pci_ops_bus;
71 }
72
73 /*
74  * This fixup is based on capturing values from an Award bios.  Without
75  * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x
76  * slower than normal, ethernet drops packets).
77  * Apparently these registers govern some sort of bus master behavior.
78  */
79 static void random_fixup() {
80         device_t pcidev = dev_find_slot(0, 0);
81
82         printk_spew("VT8601 random fixup ...\n");
83         if (pcidev) {
84                 pci_write_config8(pcidev, 0x70, 0xc0);
85                 pci_write_config8(pcidev, 0x71, 0x88);
86                 pci_write_config8(pcidev, 0x72, 0xec);
87                 pci_write_config8(pcidev, 0x73, 0x0c);
88                 pci_write_config8(pcidev, 0x74, 0x0e);
89                 pci_write_config8(pcidev, 0x75, 0x81);
90                 pci_write_config8(pcidev, 0x76, 0x52);
91         }
92 }
93
94 static void northbridge_init(struct chip *chip, enum chip_pass pass)
95 {
96
97         struct northbridge_via_vt8601_config *conf = 
98                 (struct northbridge_via_vt8601_config *)chip->chip_info;
99
100         switch (pass) {
101         case CONF_PASS_PRE_PCI:
102                 break;
103                 
104         case CONF_PASS_POST_PCI:
105                 break;
106                 
107         case CONF_PASS_PRE_BOOT:
108                 random_fixup();
109                 break;
110                 
111         default:
112                 /* nothing yet */
113                 break;
114         }
115 }
116
117 struct chip_control northbridge_via_vt8601_control = {
118         .enumerate = enumerate,
119         .enable    = northbridge_init,
120         .name      = "VIA vt8601 Northbridge",
121 };