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 <mem.h> 15#include <pci.h> 16 17void __init prom_init_memory(void) 18{ 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); 23 24#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG 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 } 39#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ 40 41#ifdef CONFIG_64BIT 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 49#endif /* !CONFIG_64BIT */ 50} 51 52/* override of arch/mips/mm/cache.c: __uncached_access */ 53int __uncached_access(struct file *file, unsigned long addr) 54{ 55 if (file->f_flags & O_DSYNC) 56 return 1; 57 58 return addr >= __pa(high_memory) || 59 ((addr >= LOONGSON_MMIO_MEM_START) && 60 (addr < LOONGSON_MMIO_MEM_END)); 61} 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 69static unsigned long uca_start, uca_end; 70 71pgprot_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)) { 78 if (uca_start && (offset >= uca_start) && 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 89static 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) { 99 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { 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 118late_initcall(find_vga_mem_init); 119#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */ 120