Commit | Line | Data |
---|---|---|
42d226c7 | 1 | /* |
70342287 RB |
2 | * This program is free software; you can redistribute it and/or modify it |
3 | * under the terms of the GNU General Public License as published by the | |
42d226c7 ST |
4 | * Free Software Foundation; either version 2 of the License, or (at your |
5 | * option) any later version. | |
6 | */ | |
7 | #include <linux/fs.h> | |
8 | #include <linux/fcntl.h> | |
9 | #include <linux/mm.h> | |
10 | ||
bd92aa01 WZ |
11 | #include <asm/bootinfo.h> |
12 | ||
5e983ff6 | 13 | #include <loongson.h> |
85749d24 | 14 | #include <mem.h> |
659da2ba | 15 | #include <pci.h> |
bd92aa01 WZ |
16 | |
17 | void __init prom_init_memory(void) | |
18 | { | |
50549bda WZ |
19 | add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); |
20 | ||
21 | add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << | |
22 | 20), BOOT_MEM_RESERVED); | |
659da2ba | 23 | |
55045ff5 | 24 | #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG |
6f7a251a WZ |
25 | { |
26 | int bit; | |
27 | ||
28 | bit = fls(memsize + highmemsize); | |
29 | if (bit != ffs(memsize + highmemsize)) | |
30 | bit += 20; | |
31 | else | |
32 | bit = bit + 20 - 1; | |
33 | ||
34 | /* set cpu window3 to map CPU to DDR: 2G -> 2G */ | |
35 | LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul, | |
36 | 0x80000000ul, (1 << bit)); | |
37 | mmiowb(); | |
38 | } | |
55045ff5 | 39 | #endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ |
6f7a251a | 40 | |
55045ff5 | 41 | #ifdef CONFIG_64BIT |
6f7a251a WZ |
42 | if (highmemsize > 0) |
43 | add_memory_region(LOONGSON_HIGHMEM_START, | |
44 | highmemsize << 20, BOOT_MEM_RAM); | |
45 | ||
46 | add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - | |
47 | LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); | |
48 | ||
55045ff5 | 49 | #endif /* !CONFIG_64BIT */ |
bd92aa01 WZ |
50 | } |
51 | ||
42d226c7 ST |
52 | /* override of arch/mips/mm/cache.c: __uncached_access */ |
53 | int __uncached_access(struct file *file, unsigned long addr) | |
54 | { | |
6b2f3d1f | 55 | if (file->f_flags & O_DSYNC) |
42d226c7 ST |
56 | return 1; |
57 | ||
42d226c7 | 58 | return addr >= __pa(high_memory) || |
85749d24 WZ |
59 | ((addr >= LOONGSON_MMIO_MEM_START) && |
60 | (addr < LOONGSON_MMIO_MEM_END)); | |
42d226c7 | 61 | } |
22f1fdfd WZ |
62 | |
63 | #ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED | |
64 | ||
65 | #include <linux/pci.h> | |
66 | #include <linux/sched.h> | |
67 | #include <asm/current.h> | |
68 | ||
69 | static unsigned long uca_start, uca_end; | |
70 | ||
71 | pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | |
72 | unsigned long size, pgprot_t vma_prot) | |
73 | { | |
74 | unsigned long offset = pfn << PAGE_SHIFT; | |
75 | unsigned long end = offset + size; | |
76 | ||
77 | if (__uncached_access(file, offset)) { | |
514b6d0c | 78 | if (uca_start && (offset >= uca_start) && |
22f1fdfd WZ |
79 | (end <= uca_end)) |
80 | return __pgprot((pgprot_val(vma_prot) & | |
81 | ~_CACHE_MASK) | | |
82 | _CACHE_UNCACHED_ACCELERATED); | |
83 | else | |
84 | return pgprot_noncached(vma_prot); | |
85 | } | |
86 | return vma_prot; | |
87 | } | |
88 | ||
89 | static int __init find_vga_mem_init(void) | |
90 | { | |
91 | struct pci_dev *dev = 0; | |
92 | struct resource *r; | |
93 | int idx; | |
94 | ||
95 | if (uca_start) | |
96 | return 0; | |
97 | ||
98 | for_each_pci_dev(dev) { | |
ff40ad72 | 99 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { |
22f1fdfd WZ |
100 | for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { |
101 | r = &dev->resource[idx]; | |
102 | if (!r->start && r->end) | |
103 | continue; | |
104 | if (r->flags & IORESOURCE_IO) | |
105 | continue; | |
106 | if (r->flags & IORESOURCE_MEM) { | |
107 | uca_start = r->start; | |
108 | uca_end = r->end; | |
109 | return 0; | |
110 | } | |
111 | } | |
112 | } | |
113 | } | |
114 | ||
115 | return 0; | |
116 | } | |
117 | ||
118 | late_initcall(find_vga_mem_init); | |
119 | #endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */ |