2 * This file is part of the coreboot project.
4 * Copyright (C) 2009 One Laptop per Child, Association, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 part of this file is from cx700 port, part of is from cn700 port,
24 #include <console/console.h>
27 #include <device/device.h>
28 #include <device/pci.h>
29 #include <device/pci_ids.h>
35 #include "northbridge.h"
38 /* !!FIXME!! This was meant to be a CONFIG option */
39 #define VIACONFIG_TOP_SM_SIZE_MB 32 // Set frame buffer 32M for default
40 /* !!FIXME!! I declared this to fix the build. */
41 u8 acpi_sleep_type = 0;
43 static void memctrl_init(device_t dev)
46 set VGA in uma_ram_setting.c, not in this function.
49 pci_write_config8(dev, 0x85, 0x20);
50 pci_write_config8(dev, 0x86, 0x2d);
52 /* Set up VGA timers */
53 pci_write_config8(dev, 0xa2, 0x44);
55 /* Enable VGA with a 32mb framebuffer */
56 pci_write_config16(dev, 0xa0, 0xd000);
58 pci_write_config16(dev, 0xa4, 0x0010);
60 //b0: 60 aa aa 5a 0f 00 00 00 08
61 pci_write_config16(dev, 0xb0, 0xaa00);
62 pci_write_config8(dev, 0xb8, 0x08);
66 static const struct device_operations memctrl_operations = {
67 .read_resources = vx800_noop,
71 static const struct pci_driver memctrl_driver __pci_driver = {
72 .ops = &memctrl_operations,
73 .vendor = PCI_VENDOR_ID_VIA,
74 .device = PCI_DEVICE_ID_VIA_VX855_MEMCTRL,
77 static void ram_resource(device_t dev, unsigned long index,
78 unsigned long basek, unsigned long sizek)
80 struct resource *resource;
85 resource = new_resource(dev, index);
86 resource->base = ((resource_t) basek) << 10;
87 resource->size = ((resource_t) sizek) << 10;
88 resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE |
89 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
92 static void tolm_test(void *gp, struct device *dev, struct resource *new)
94 struct resource **best_p = gp;
95 struct resource *best;
97 if (!best || (best->base > new->base)) {
103 static u32 find_pci_tolm(struct bus *bus)
105 print_debug("Entering find_pci_tolm\n");
106 struct resource *min;
109 search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM,
112 if (min && tolm > min->base) {
115 print_debug("Leaving find_pci_tolm\n");
119 static void pci_domain_set_resources(device_t dev)
122 * the order is important to find the correct ram size.
124 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
129 printk(BIOS_SPEW, "Entering vx800 pci_domain_set_resources.\n");
131 pci_tolm = find_pci_tolm(&dev->link[0]);
132 mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
133 PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
136 unsigned long tomk, tolmk;
137 unsigned char rambits;
141 * once the register value is not zero, the ramsize is
142 * this register's value multiply 64 * 1024 * 1024
144 for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
145 rambits = pci_read_config8(mc_dev, ramregs[i]);
150 Get memory size and frame buffer from northbridge's registers.
151 if register with invalid value we set frame buffer size to 32M for default, but it won't happen.
153 reg = pci_read_config8(mc_dev, 0xa1);
156 /* TOP 1M SM Memory */
158 tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024); // Set frame buffer 32M for default
161 (((rambits << 6) - (4 << reg) -
162 VIACONFIG_TOP_SM_SIZE_MB) * 1024);
164 printk(BIOS_SPEW, "tomk is 0x%lx\n", tomk);
165 /* Compute the Top Of Low Memory, in Kb */
166 tolmk = pci_tolm >> 10;
168 /* The PCI hole does does not overlap the memory. */
171 /* Report the memory regions */
173 /* TODO: Hole needed? */
174 ram_resource(dev, idx++, 0, 640); /* first 640k */
175 /* Leave a hole for vga, 0xa0000 - 0xc0000 */
176 ram_resource(dev, idx++, 768, (tolmk - 768));
178 assign_resources(&dev->link[0]);
181 static struct device_operations pci_domain_ops = {
182 .read_resources = pci_domain_read_resources,
183 .set_resources = pci_domain_set_resources,
184 .enable_resources = enable_childrens_resources,
186 .scan_bus = pci_domain_scan_bus,
189 static void cpu_bus_init(device_t dev)
191 initialize_cpus(&dev->link[0]);
194 static void cpu_bus_noop(device_t dev)
198 static struct device_operations cpu_bus_ops = {
199 .read_resources = cpu_bus_noop,
200 .set_resources = cpu_bus_noop,
201 .enable_resources = cpu_bus_noop,
202 .init = cpu_bus_init,
206 static void enable_dev(struct device *dev)
208 printk(BIOS_SPEW, "In VX800 enable_dev for device %s.\n", dev_path(dev));
210 /* Set the operations if it is a special bus type */
211 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
212 dev->ops = &pci_domain_ops;
214 } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
215 dev->ops = &cpu_bus_ops;
219 struct chip_operations northbridge_via_vx800_ops = {
220 CHIP_NAME("VIA VX800 Chipset")
221 .enable_dev = enable_dev,