13 #include <linux/kernel.h>
14 #include <linux/types.h>
19 #include <linux/pci.h>
20 #include <linux/bitops.h>
25 #include <asm/iommu.h>
45 #define GART_MIN_ADDR (512ULL << 20)
46 #define GART_MAX_ADDR (1ULL << 32)
57 static struct resource gart_resource = {
62 static void __init insert_aperture_resource(
u32 aper_base,
u32 aper_size)
64 gart_resource.
start = aper_base;
65 gart_resource.
end = aper_base + aper_size - 1;
78 if (fallback_aper_order > 5)
80 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
89 aper_size, aper_size);
92 "Cannot allocate aperture memory hole (%lx,%uK)\n",
98 aper_size >> 10, addr);
99 insert_aperture_resource((
u32)addr, aper_size);
118 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
139 u32 aper_low, aper_hi;
145 if (apsizereg == 0xffffffff) {
153 apsize = apsizereg & 0xfff;
164 aper = (aper_low & ~((1<<22)-1)) | ((
u64)aper_hi << 32);
171 aper, 32 << old_order);
172 if (aper + (32ULL<<(20 + *order)) > 0x100000000ULL) {
173 printk(
KERN_INFO "Aperture size %u MB (APSIZE %x) is not right, using settings from NB\n",
174 32 << *order, apsizereg);
179 aper, 32 << *order, apsizereg);
181 if (!aperture_valid(aper, (32*1024*1024) << *order, 32<<20))
199 static u32 __init search_agp_bridge(
u32 *order,
int *valid_agp)
204 for (bus = 0; bus < 256; bus++) {
205 for (slot = 0; slot < 32; slot++) {
206 for (func = 0; func < 8; func++) {
211 if (
class == 0xffffffff)
214 switch (
class >> 16) {
218 cap = find_cap(bus, slot, func,
223 return read_agp(bus, slot, func, cap,
242 static int __init parse_gart_mem(
char *
p)
268 u32 agp_aper_order = 0;
269 int i, fix,
slot, valid_agp = 0;
271 u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
272 u64 aper_base = 0, last_aper_base = 0;
273 int aper_enabled = 0, last_aper_enabled = 0, last_valid = 0;
279 search_agp_bridge(&agp_aper_order, &valid_agp);
284 int dev_base, dev_limit;
290 for (slot = dev_base; slot < dev_limit; slot++) {
295 aper_enabled = ctl &
GARTEN;
296 aper_order = (ctl >> 1) & 7;
297 aper_size = (32 * 1024 * 1024) << aper_order;
302 if ((aper_order != last_aper_order) ||
303 (aper_base != last_aper_base) ||
304 (aper_enabled != last_aper_enabled)) {
310 last_aper_order = aper_order;
311 last_aper_base = aper_base;
312 last_aper_enabled = aper_enabled;
317 if (!fix && !aper_enabled)
320 if (!aper_base || !aper_size || aper_base + aper_size > 0x100000000UL)
323 if (gart_fix_e820 && !fix && aper_enabled) {
339 int dev_base, dev_limit;
345 for (slot = dev_base; slot < dev_limit; slot++) {
357 static int __initdata printed_gart_size_msg;
361 u32 agp_aper_base = 0, agp_aper_order = 0;
362 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
363 u64 aper_base, last_aper_base = 0;
364 int fix,
slot, valid_agp = 0;
374 agp_aper_base = search_agp_bridge(&agp_aper_order, &valid_agp);
380 int dev_base, dev_limit;
387 for (slot = dev_base; slot < dev_limit; slot++) {
407 aper_order = (ctl >> 1) & 7;
408 aper_size = (32 * 1024 * 1024) << aper_order;
413 node, aper_base, aper_size >> 20);
416 if (!aperture_valid(aper_base, aper_size, 64<<20)) {
417 if (valid_agp && agp_aper_base &&
418 agp_aper_base == aper_base &&
419 agp_aper_order == aper_order) {
423 !printed_gart_size_msg) {
424 printk(
KERN_ERR "you are using iommu with agp, but GART size is less than 64M\n");
425 printk(
KERN_ERR "please increase GART size in your BIOS setup\n");
426 printk(
KERN_ERR "if BIOS doesn't have that option, contact your HW vendor!\n");
427 printed_gart_size_msg = 1;
435 if ((last_aper_order && aper_order != last_aper_order) ||
436 (last_aper_base && aper_base != last_aper_base)) {
440 last_aper_order = aper_order;
441 last_aper_base = aper_base;
447 if (last_aper_base) {
448 unsigned long n = (32 * 1024 * 1024) << last_aper_order;
450 insert_aperture_resource((
u32)last_aper_base, n);
457 aper_alloc = agp_aper_base;
458 aper_order = agp_aper_order;
468 "Your BIOS doesn't leave a aperture memory hole\n");
470 "Please enable the IOMMU option in the BIOS setup\n");
472 "This costs you %d MB of RAM\n",
476 aper_alloc = allocate_aperture();
486 panic(
"Not enough memory for aperture");
494 int bus, dev_base, dev_limit;
500 u32 ctl = aper_order << 1;
505 for (slot = dev_base; slot < dev_limit; slot++) {