1 #include <console/console.h>
5 #include <part/sizeram.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/hypertransport.h>
9 #include <device/pci_ids.h>
13 #include <cpu/p6/mtrr.h>
15 #include "northbridge.h"
17 static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d };
19 struct mem_range *sizeram(void)
21 unsigned long mmio_basek;
22 static struct mem_range mem[10];
25 unsigned char rambits;
27 dev = dev_find_slot(0, 0);
29 printk_err("Cannot find PCI: 0:0\n");
33 mem[0].sizek = 0xa0000 >>10; // first 640k
34 mem[1].basek = 0xc0000 >>10; // leave a hole for vga
36 while(idx < sizeof(mem)/sizeof(mem[0])) {
41 for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
43 reg = pci_read_config8(dev, ramregs[i]);
44 /* these are ENDING addresses, not sizes.
45 * if there is memory in this slot, then reg will be > rambits.
46 * So we just take the max, that gives us total.
47 * We take the highest one to cover for once and future linuxbios
48 * bugs. We warn about bugs.
53 printk_err("ERROR! register 0x%x is not set!\n",
57 printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024);
58 mem[1].sizek = rambits*16*1024 - 32768 - (0xc0000 >> 10);
60 for(i = 0; i < idx; i++) {
61 printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
62 i, mem[i].basek, i, mem[i].sizek);
68 static void enumerate(struct chip *chip)
70 extern struct device_operations default_pci_ops_bus;
72 chip->dev->ops = &default_pci_ops_bus;
76 * This fixup is based on capturing values from an Award bios. Without
77 * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x
78 * slower than normal, ethernet drops packets).
79 * Apparently these registers govern some sort of bus master behavior.
81 static void random_fixup() {
82 device_t pcidev0 = dev_find_slot(0, 0);
83 device_t pcidev1,pcidev2;
87 printk_debug("VT8623 random fixup ...\n");
89 pci_write_config8(pcidev0, 0x0d, 0x08);
90 pci_write_config8(pcidev0, 0x70, 0x82);
91 pci_write_config8(pcidev0, 0x71, 0xc8);
92 pci_write_config8(pcidev0, 0x72, 0x0);
93 pci_write_config8(pcidev0, 0x73, 0x01);
94 pci_write_config8(pcidev0, 0x74, 0x01);
95 pci_write_config8(pcidev0, 0x75, 0x08);
96 pci_write_config8(pcidev0, 0x76, 0x52);
97 pci_write_config8(pcidev0, 0x13, 0xd0);
98 pci_write_config8(pcidev0, 0x84, 0x80);
99 pci_write_config16(pcidev0,0x80, 0x610f);
100 pci_write_config32(pcidev0,0x88, 0x02);
102 printk_debug("VT8623 AGP random fixup ...\n");
103 pcidev1 = dev_find_device(PCI_VENDOR_ID_VIA,0xb091,0);
105 pci_write_config8(pcidev1,0x3e,0x0c);
106 pci_write_config8(pcidev1,0x40,0x83);
107 pci_write_config8(pcidev1,0x41,0xc5);
108 pci_write_config8(pcidev1,0x43,0x44);
109 pci_write_config8(pcidev1,0x44,0x34);
110 pci_write_config8(pcidev1,0x83,0x02);
112 printk_debug("VGA random fixup ...\n");
113 pcidev2 = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
115 pci_write_config8(pcidev2,0x04,0x07);
116 pci_write_config8(pcidev2,0x0d,0x20);
118 // fixup GART and framebuffer addresses properly
119 // first set up frame buffer properly
120 fb = pci_read_config32(pcidev2,0x10); // base address of framebuffer
121 printk_debug("Frame buffer at %8x\n",fb);
122 c = pci_read_config8(pcidev0,0xe1) & 0xf0; // size of vga
123 c |= fb>>28; // upper nibble of frame buffer address
124 pci_write_config8(pcidev0,0xe1,c);
125 c = (fb>>20) | 1; // enable framebuffer
126 pci_write_config8(pcidev0,0xe0,c);
127 pci_write_config8(pcidev0,0xe2,0x42); // 'cos award does
131 static void set_vga_mtrrs(void)
133 device_t pcidev = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
136 add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB);
137 fb = pci_read_config32(pcidev,0x10); // get the fb address
138 add_var_mtrr( fb>>10, 8192, MTRR_TYPE_WRCOMB);
143 static void northbridge_init(struct chip *chip, enum chip_pass pass)
146 struct northbridge_via_vt8623_config *conf =
147 (struct northbridge_via_vt8623_config *)chip->chip_info;
150 case CONF_PASS_PRE_PCI:
153 case CONF_PASS_POST_PCI:
157 case CONF_PASS_PRE_BOOT:
167 struct chip_control northbridge_via_vt8623_control = {
168 .enumerate = enumerate,
169 .enable = northbridge_init,
170 .name = "VIA vt8623 Northbridge",