Change all vx800 file names from CamelCase to camel_case to match
[coreboot.git] / src / northbridge / via / vx800 / northbridge.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2009 One Laptop per Child, Association, Inc.
5  *
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.
9  *
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.
14  *
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
18  */
19
20 /*
21     part of this file is from cx700 port, part of is from cn700 port,
22    */
23
24 #include <console/console.h>
25 #include <arch/io.h>
26 #include <stdint.h>
27 #include <device/device.h>
28 #include <device/pci.h>
29 #include <device/pci_ids.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <bitops.h>
33 #include <cpu/cpu.h>
34 #include "chip.h"
35 #include "northbridge.h"
36 #include "vx800.h"
37
38 static void memctrl_init(device_t dev)
39 {
40 /*
41   set VGA in uma_ram_setting.c, not in this function.
42 */
43 #if 0
44         pci_write_config8(dev, 0x85, 0x20);
45         pci_write_config8(dev, 0x86, 0x2d);
46
47         /* Set up VGA timers */
48         pci_write_config8(dev, 0xa2, 0x44);
49
50         /* Enable VGA with a 32mb framebuffer */
51         pci_write_config16(dev, 0xa0, 0xd000);
52
53         pci_write_config16(dev, 0xa4, 0x0010);
54
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);
58 #endif
59 }
60
61 static const struct device_operations memctrl_operations = {
62         .read_resources = vx800_noop,
63         .init = memctrl_init,
64 };
65
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,
70 };
71
72 static void pci_domain_read_resources(device_t dev)
73 {
74         struct resource *resource;
75
76         printk_spew("Entering vx800 pci_domain_read_resources.\n");
77
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 |
82             IORESOURCE_ASSIGNED;
83
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 |
88             IORESOURCE_ASSIGNED;
89
90         printk_spew("Leaving vx800 pci_domain_read_resources.\n");
91 }
92
93 static void ram_resource(device_t dev, unsigned long index,
94                          unsigned long basek, unsigned long sizek)
95 {
96         struct resource *resource;
97
98         if (!sizek) {
99                 return;
100         }
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;
106 }
107
108 static void tolm_test(void *gp, struct device *dev, struct resource *new)
109 {
110         struct resource **best_p = gp;
111         struct resource *best;
112         best = *best_p;
113         if (!best || (best->base > new->base)) {
114                 best = new;
115         }
116         *best_p = best;
117 }
118
119 static u32 find_pci_tolm(struct bus *bus)
120 {
121         print_debug("Entering find_pci_tolm\n");
122         struct resource *min;
123         u32 tolm;
124         min = 0;
125         search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM,
126                              tolm_test, &min);
127         tolm = 0xffffffffUL;
128         if (min && tolm > min->base) {
129                 tolm = min->base;
130         }
131         print_debug("Leaving find_pci_tolm\n");
132         return tolm;
133 }
134
135 static void pci_domain_set_resources(device_t dev)
136 {
137         /* 
138          * the order is important to find the correct ram size.
139          */
140         u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
141         device_t mc_dev;
142         u32 pci_tolm;
143         u8 reg;
144
145         printk_spew("Entering vx800 pci_domain_set_resources.\n");
146
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);
150
151         if (mc_dev) {
152                 unsigned long tomk, tolmk;
153                 unsigned char rambits;
154                 u8 i, idx;
155
156                 /*
157                  * once the register value is not zero, the ramsize is
158                  * this register's value multiply 64 * 1024 * 1024
159                  */
160                 for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
161                         unsigned char reg;
162                         rambits = pci_read_config8(mc_dev, ramregs[i]);
163                         if (rambits != 0)
164                                 break;
165                 }
166 /*
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.
169 */
170                 reg = pci_read_config8(mc_dev, 0xa1);
171                 reg &= 0x70;
172                 reg = reg >> 4;
173                 /* TOP 1M SM Memory */
174                 if (reg == 0x0)
175                         tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024);       // Set frame buffer 32M for default
176                 else
177                         tomk =
178                             (((rambits << 6) - (4 << reg) -
179                               VIACONFIG_TOP_SM_SIZE_MB) * 1024);
180
181                 printk_spew("tomk is 0x%x\n", tomk);
182                 /* Compute the Top Of Low Memory, in Kb */
183                 tolmk = pci_tolm >> 10;
184                 if (tolmk >= tomk) {
185                         /* The PCI hole does does not overlap the memory. */
186                         tolmk = tomk;
187                 }
188                 /* Report the memory regions */
189                 idx = 10;
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));
194         }
195         assign_resources(&dev->link[0]);
196 }
197
198 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
199 {
200         printk_debug("Entering vx800 pci_domain_scan_bus.\n");
201
202         max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
203         return max;
204 }
205
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,
210         .init = 0,
211         .scan_bus = pci_domain_scan_bus,
212 };
213
214 static void cpu_bus_init(device_t dev)
215 {
216         initialize_cpus(&dev->link[0]);
217 }
218
219 static void cpu_bus_noop(device_t dev)
220 {
221 }
222
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,
228         .scan_bus = 0,
229 };
230
231 static void enable_dev(struct device *dev)
232 {
233         printk_spew("In VX800 enable_dev for device %s.\n", dev_path(dev));
234
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;
238                 pci_set_method(dev);
239         } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
240                 dev->ops = &cpu_bus_ops;
241         }
242 }
243
244 struct chip_operations northbridge_via_vx800_ops = {
245         CHIP_NAME("VIA VX800 Chipset")
246             .enable_dev = enable_dev,
247 };