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 pci_domain_set_resources(device_t dev)
80 * the order is important to find the correct ram size.
82 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
87 printk(BIOS_SPEW, "Entering vx800 pci_domain_set_resources.\n");
89 pci_tolm = find_pci_tolm(dev->link_list);
90 mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
91 PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
94 unsigned long tomk, tolmk;
95 unsigned char rambits;
99 * once the register value is not zero, the ramsize is
100 * this register's value multiply 64 * 1024 * 1024
102 for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
103 rambits = pci_read_config8(mc_dev, ramregs[i]);
108 Get memory size and frame buffer from northbridge's registers.
109 if register with invalid value we set frame buffer size to 32M for default, but it won't happen.
111 reg = pci_read_config8(mc_dev, 0xa1);
114 /* TOP 1M SM Memory */
116 tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024); // Set frame buffer 32M for default
119 (((rambits << 6) - (4 << reg) -
120 VIACONFIG_TOP_SM_SIZE_MB) * 1024);
122 printk(BIOS_SPEW, "tomk is 0x%lx\n", tomk);
123 /* Compute the Top Of Low Memory, in Kb */
124 tolmk = pci_tolm >> 10;
126 /* The PCI hole does does not overlap the memory. */
129 /* Report the memory regions */
131 /* TODO: Hole needed? */
132 ram_resource(dev, idx++, 0, 640); /* first 640k */
133 /* Leave a hole for vga, 0xa0000 - 0xc0000 */
134 ram_resource(dev, idx++, 768, (tolmk - 768));
136 assign_resources(dev->link_list);
139 static struct device_operations pci_domain_ops = {
140 .read_resources = pci_domain_read_resources,
141 .set_resources = pci_domain_set_resources,
142 .enable_resources = NULL,
144 .scan_bus = pci_domain_scan_bus,
147 static void cpu_bus_init(device_t dev)
149 initialize_cpus(dev->link_list);
152 static void cpu_bus_noop(device_t dev)
156 static struct device_operations cpu_bus_ops = {
157 .read_resources = cpu_bus_noop,
158 .set_resources = cpu_bus_noop,
159 .enable_resources = cpu_bus_noop,
160 .init = cpu_bus_init,
164 static void enable_dev(struct device *dev)
166 printk(BIOS_SPEW, "In VX800 enable_dev for device %s.\n", dev_path(dev));
168 /* Set the operations if it is a special bus type */
169 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
170 dev->ops = &pci_domain_ops;
172 } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
173 dev->ops = &cpu_bus_ops;
177 struct chip_operations northbridge_via_vx800_ops = {
178 CHIP_NAME("VIA VX800 Chipset")
179 .enable_dev = enable_dev,