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 static void memctrl_init(device_t dev)
41 set VGA in UMARamSetting.c, not in this function.
44 pci_write_config8(dev, 0x85, 0x20);
45 pci_write_config8(dev, 0x86, 0x2d);
47 /* Set up VGA timers */
48 pci_write_config8(dev, 0xa2, 0x44);
50 /* Enable VGA with a 32mb framebuffer */
51 pci_write_config16(dev, 0xa0, 0xd000);
53 pci_write_config16(dev, 0xa4, 0x0010);
55 //b0: 60 aa aa 5a 0f 00 00 00 08
56 pci_write_config16(dev, 0xb0, 0xaa00);
57 pci_write_config8(dev, 0xb8, 0x08);
61 static const struct device_operations memctrl_operations = {
62 .read_resources = vx800_noop,
66 static const struct pci_driver memctrl_driver __pci_driver = {
67 .ops = &memctrl_operations,
68 .vendor = PCI_VENDOR_ID_VIA,
69 .device = PCI_DEVICE_ID_VIA_VX855_MEMCTRL,
72 static void pci_domain_read_resources(device_t dev)
74 struct resource *resource;
76 printk_spew("Entering vx800 pci_domain_read_resources.\n");
78 /* Initialize the system wide io space constraints */
79 resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
80 resource->limit = 0xffffUL;
81 resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
84 /* Initialize the system wide memory resources constraints */
85 resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
86 resource->limit = 0xffffffffULL;
87 resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
90 printk_spew("Leaving vx800 pci_domain_read_resources.\n");
93 static void ram_resource(device_t dev, unsigned long index,
94 unsigned long basek, unsigned long sizek)
96 struct resource *resource;
101 resource = new_resource(dev, index);
102 resource->base = ((resource_t) basek) << 10;
103 resource->size = ((resource_t) sizek) << 10;
104 resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE |
105 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
108 static void tolm_test(void *gp, struct device *dev, struct resource *new)
110 struct resource **best_p = gp;
111 struct resource *best;
113 if (!best || (best->base > new->base)) {
119 static u32 find_pci_tolm(struct bus *bus)
121 print_debug("Entering find_pci_tolm\n");
122 struct resource *min;
125 search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM,
128 if (min && tolm > min->base) {
131 print_debug("Leaving find_pci_tolm\n");
135 static void pci_domain_set_resources(device_t dev)
138 * the order is important to find the correct ram size.
140 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
145 printk_spew("Entering vx800 pci_domain_set_resources.\n");
147 pci_tolm = find_pci_tolm(&dev->link[0]);
148 mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
149 PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
152 unsigned long tomk, tolmk;
153 unsigned char rambits;
157 * once the register value is not zero, the ramsize is
158 * this register's value multiply 64 * 1024 * 1024
160 for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
162 rambits = pci_read_config8(mc_dev, ramregs[i]);
167 Get memory size and frame buffer from northbridge's registers.
168 if register with invalid value we set frame buffer size to 32M for default, but it won't happen.
170 reg = pci_read_config8(mc_dev, 0xa1);
173 /* TOP 1M SM Memory */
175 tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024); // Set frame buffer 32M for default
178 (((rambits << 6) - (4 << reg) -
179 VIACONFIG_TOP_SM_SIZE_MB) * 1024);
181 printk_spew("tomk is 0x%x\n", tomk);
182 /* Compute the Top Of Low Memory, in Kb */
183 tolmk = pci_tolm >> 10;
185 /* The PCI hole does does not overlap the memory. */
188 /* Report the memory regions */
190 /* TODO: Hole needed? */
191 ram_resource(dev, idx++, 0, 640); /* first 640k */
192 /* Leave a hole for vga, 0xa0000 - 0xc0000 */
193 ram_resource(dev, idx++, 768, (tolmk - 768));
195 assign_resources(&dev->link[0]);
198 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
200 printk_debug("Entering vx800 pci_domain_scan_bus.\n");
202 max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
206 static const struct device_operations pci_domain_ops = {
207 .read_resources = pci_domain_read_resources,
208 .set_resources = pci_domain_set_resources,
209 .enable_resources = enable_childrens_resources,
211 .scan_bus = pci_domain_scan_bus,
214 static void cpu_bus_init(device_t dev)
216 initialize_cpus(&dev->link[0]);
219 static void cpu_bus_noop(device_t dev)
223 static const struct device_operations cpu_bus_ops = {
224 .read_resources = cpu_bus_noop,
225 .set_resources = cpu_bus_noop,
226 .enable_resources = cpu_bus_noop,
227 .init = cpu_bus_init,
231 static void enable_dev(struct device *dev)
233 printk_spew("In VX800 enable_dev for device %s.\n", dev_path(dev));
235 /* Set the operations if it is a special bus type */
236 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
237 dev->ops = &pci_domain_ops;
239 } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
240 dev->ops = &cpu_bus_ops;
244 struct chip_operations northbridge_via_vx800_ops = {
245 CHIP_NAME("VIA VX800 Chipset")
246 .enable_dev = enable_dev,