1/*
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
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
11#include <asm/bootinfo.h>
12
13#include <loongson.h>
14#include <boot_param.h>
15#include <mem.h>
16#include <pci.h>
17
18#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
19
20u32 memsize, highmemsize;
21
22void __init prom_init_memory(void)
23{
24	add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
25
26	add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
27				20), BOOT_MEM_RESERVED);
28
29#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
30	{
31		int bit;
32
33		bit = fls(memsize + highmemsize);
34		if (bit != ffs(memsize + highmemsize))
35			bit += 20;
36		else
37			bit = bit + 20 - 1;
38
39		/* set cpu window3 to map CPU to DDR: 2G -> 2G */
40		LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul,
41					  0x80000000ul, (1 << bit));
42		mmiowb();
43	}
44#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
45
46#ifdef CONFIG_64BIT
47	if (highmemsize > 0)
48		add_memory_region(LOONGSON_HIGHMEM_START,
49				  highmemsize << 20, BOOT_MEM_RAM);
50
51	add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START -
52			  LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED);
53
54#endif /* !CONFIG_64BIT */
55}
56
57#else /* CONFIG_LEFI_FIRMWARE_INTERFACE */
58
59void __init prom_init_memory(void)
60{
61	int i;
62	u32 node_id;
63	u32 mem_type;
64
65	/* parse memory information */
66	for (i = 0; i < loongson_memmap->nr_map; i++) {
67		node_id = loongson_memmap->map[i].node_id;
68		mem_type = loongson_memmap->map[i].mem_type;
69
70		if (node_id == 0) {
71			switch (mem_type) {
72			case SYSTEM_RAM_LOW:
73				add_memory_region(loongson_memmap->map[i].mem_start,
74					(u64)loongson_memmap->map[i].mem_size << 20,
75					BOOT_MEM_RAM);
76				break;
77			case SYSTEM_RAM_HIGH:
78				add_memory_region(loongson_memmap->map[i].mem_start,
79					(u64)loongson_memmap->map[i].mem_size << 20,
80					BOOT_MEM_RAM);
81				break;
82			case MEM_RESERVED:
83				add_memory_region(loongson_memmap->map[i].mem_start,
84					(u64)loongson_memmap->map[i].mem_size << 20,
85					BOOT_MEM_RESERVED);
86				break;
87			}
88		}
89	}
90}
91
92#endif /* CONFIG_LEFI_FIRMWARE_INTERFACE */
93
94/* override of arch/mips/mm/cache.c: __uncached_access */
95int __uncached_access(struct file *file, unsigned long addr)
96{
97	if (file->f_flags & O_DSYNC)
98		return 1;
99
100	return addr >= __pa(high_memory) ||
101		((addr >= LOONGSON_MMIO_MEM_START) &&
102		 (addr < LOONGSON_MMIO_MEM_END));
103}
104
105#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
106
107#include <linux/pci.h>
108#include <linux/sched.h>
109#include <asm/current.h>
110
111static unsigned long uca_start, uca_end;
112
113pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
114			      unsigned long size, pgprot_t vma_prot)
115{
116	unsigned long offset = pfn << PAGE_SHIFT;
117	unsigned long end = offset + size;
118
119	if (__uncached_access(file, offset)) {
120		if (uca_start && (offset >= uca_start) &&
121		    (end <= uca_end))
122			return __pgprot((pgprot_val(vma_prot) &
123					 ~_CACHE_MASK) |
124					_CACHE_UNCACHED_ACCELERATED);
125		else
126			return pgprot_noncached(vma_prot);
127	}
128	return vma_prot;
129}
130
131static int __init find_vga_mem_init(void)
132{
133	struct pci_dev *dev = 0;
134	struct resource *r;
135	int idx;
136
137	if (uca_start)
138		return 0;
139
140	for_each_pci_dev(dev) {
141		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
142			for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
143				r = &dev->resource[idx];
144				if (!r->start && r->end)
145					continue;
146				if (r->flags & IORESOURCE_IO)
147					continue;
148				if (r->flags & IORESOURCE_MEM) {
149					uca_start = r->start;
150					uca_end = r->end;
151					return 0;
152				}
153			}
154		}
155	}
156
157	return 0;
158}
159
160late_initcall(find_vga_mem_init);
161#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */
162