142d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian/* 242d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian * This program is free software; you can redistribute it and/or modify it 342d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian * under the terms of the GNU General Public License as published by the 442d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian * Free Software Foundation; either version 2 of the License, or (at your 542d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian * option) any later version. 642d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian */ 742d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian#include <linux/fs.h> 842d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian#include <linux/fcntl.h> 942d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian#include <linux/mm.h> 1042d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian 11bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin#include <asm/bootinfo.h> 12bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin 135e983ff654ca3df3007b5b558b5271bb4622afa4Wu Zhangjin#include <loongson.h> 1485749d24bcf90440b10394312e5b1c96d1a62cdbWu Zhangjin#include <mem.h> 15659da2ba3ebf53dc49f7f9a357a1aef046bf3139Wu Zhangjin#include <pci.h> 16bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin 17bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjinvoid __init prom_init_memory(void) 18bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin{ 1950549bda2d47f419758dac9bc72e2b0eb9077d83Wu Zhangjin add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); 2050549bda2d47f419758dac9bc72e2b0eb9077d83Wu Zhangjin 2150549bda2d47f419758dac9bc72e2b0eb9077d83Wu Zhangjin add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << 2250549bda2d47f419758dac9bc72e2b0eb9077d83Wu Zhangjin 20), BOOT_MEM_RESERVED); 23659da2ba3ebf53dc49f7f9a357a1aef046bf3139Wu Zhangjin 2455045ff5557bc804752e84dca5d1b1f1d4bb4e31Wu Zhangjin#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG 256f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin { 266f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin int bit; 276f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin 286f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin bit = fls(memsize + highmemsize); 296f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin if (bit != ffs(memsize + highmemsize)) 306f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin bit += 20; 316f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin else 326f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin bit = bit + 20 - 1; 336f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin 346f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin /* set cpu window3 to map CPU to DDR: 2G -> 2G */ 356f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul, 366f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin 0x80000000ul, (1 << bit)); 376f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin mmiowb(); 386f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin } 3955045ff5557bc804752e84dca5d1b1f1d4bb4e31Wu Zhangjin#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ 406f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin 4155045ff5557bc804752e84dca5d1b1f1d4bb4e31Wu Zhangjin#ifdef CONFIG_64BIT 426f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin if (highmemsize > 0) 436f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin add_memory_region(LOONGSON_HIGHMEM_START, 446f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin highmemsize << 20, BOOT_MEM_RAM); 456f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin 466f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - 476f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); 486f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3Wu Zhangjin 4955045ff5557bc804752e84dca5d1b1f1d4bb4e31Wu Zhangjin#endif /* !CONFIG_64BIT */ 50bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin} 51bd92aa013e8fcd17328ec8e060477761cf3380d9Wu Zhangjin 5242d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian/* override of arch/mips/mm/cache.c: __uncached_access */ 5342d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tianint __uncached_access(struct file *file, unsigned long addr) 5442d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian{ 556b2f3d1f769be5779b479c37800229d9a4809fc3Christoph Hellwig if (file->f_flags & O_DSYNC) 5642d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian return 1; 5742d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian 5842d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian return addr >= __pa(high_memory) || 5985749d24bcf90440b10394312e5b1c96d1a62cdbWu Zhangjin ((addr >= LOONGSON_MMIO_MEM_START) && 6085749d24bcf90440b10394312e5b1c96d1a62cdbWu Zhangjin (addr < LOONGSON_MMIO_MEM_END)); 6142d226c7248a28ff8c478c06b7e9bd9ef5d73574Songmao Tian} 6222f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 6322f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED 6422f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 6522f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin#include <linux/pci.h> 6622f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin#include <linux/sched.h> 6722f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin#include <asm/current.h> 6822f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 6922f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjinstatic unsigned long uca_start, uca_end; 7022f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 7122f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjinpgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, 7222f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin unsigned long size, pgprot_t vma_prot) 7322f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin{ 7422f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin unsigned long offset = pfn << PAGE_SHIFT; 7522f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin unsigned long end = offset + size; 7622f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 7722f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin if (__uncached_access(file, offset)) { 78514b6d0c06a5d751259f145d9593b4d084c1cce3Arnaud Patard if (uca_start && (offset >= uca_start) && 7922f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin (end <= uca_end)) 8022f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin return __pgprot((pgprot_val(vma_prot) & 8122f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin ~_CACHE_MASK) | 8222f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin _CACHE_UNCACHED_ACCELERATED); 8322f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin else 8422f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin return pgprot_noncached(vma_prot); 8522f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin } 8622f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin return vma_prot; 8722f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin} 8822f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 8922f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjinstatic int __init find_vga_mem_init(void) 9022f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin{ 9122f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin struct pci_dev *dev = 0; 9222f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin struct resource *r; 9322f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin int idx; 9422f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 9522f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin if (uca_start) 9622f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin return 0; 9722f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 9822f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin for_each_pci_dev(dev) { 99ff40ad72addb448c1285181820597a17685ee69aRichard LIU if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { 10022f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { 10122f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin r = &dev->resource[idx]; 10222f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin if (!r->start && r->end) 10322f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin continue; 10422f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin if (r->flags & IORESOURCE_IO) 10522f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin continue; 10622f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin if (r->flags & IORESOURCE_MEM) { 10722f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin uca_start = r->start; 10822f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin uca_end = r->end; 10922f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin return 0; 11022f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin } 11122f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin } 11222f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin } 11322f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin } 11422f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 11522f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin return 0; 11622f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin} 11722f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin 11822f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjinlate_initcall(find_vga_mem_init); 11922f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4Wu Zhangjin#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */ 120