From 22f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 11 Nov 2009 13:59:23 +0800 Subject: MIPS: Add support for uncached accelerated mappings. Loongson2f support video acceleration. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/624/ Patchwork: http://patchwork.linux-mips.org/patch/625/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 3 +++ arch/mips/include/asm/pgtable.h | 13 +++++++++ arch/mips/loongson/common/mem.c | 58 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 51e4e5b..e2116b1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1336,6 +1336,7 @@ config SYS_HAS_CPU_LOONGSON2F bool select CPU_SUPPORTS_CPUFREQ select CPU_SUPPORTS_ADDRWINCFG if 64BIT + select CPU_SUPPORTS_UNCACHED_ACCELERATED config SYS_HAS_CPU_MIPS32_R1 bool @@ -1451,6 +1452,8 @@ config CPU_SUPPORTS_ADDRWINCFG bool config CPU_SUPPORTS_HUGEPAGES bool +config CPU_SUPPORTS_UNCACHED_ACCELERATED + bool config MIPS_PGD_C0_CONTEXT bool default y if 64BIT && CPU_MIPSR2 diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index d6eb613..1854336 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -390,6 +390,19 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, #include /* + * uncached accelerated TLB map for video memory access + */ +#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED +#define __HAVE_PHYS_MEM_ACCESS_PROT + +struct file; +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); +int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t *vma_prot); +#endif + +/* * We provide our own get_unmapped area to cope with the virtual aliasing * constraints placed on us by the cache architecture. */ diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index 981e919..ceacd09 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -58,3 +58,61 @@ int __uncached_access(struct file *file, unsigned long addr) ((addr >= LOONGSON_MMIO_MEM_START) && (addr < LOONGSON_MMIO_MEM_END)); } + +#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED + +#include +#include +#include + +static unsigned long uca_start, uca_end; + +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot) +{ + unsigned long offset = pfn << PAGE_SHIFT; + unsigned long end = offset + size; + + if (__uncached_access(file, offset)) { + if (((uca_start && offset) >= uca_start) && + (end <= uca_end)) + return __pgprot((pgprot_val(vma_prot) & + ~_CACHE_MASK) | + _CACHE_UNCACHED_ACCELERATED); + else + return pgprot_noncached(vma_prot); + } + return vma_prot; +} + +static int __init find_vga_mem_init(void) +{ + struct pci_dev *dev = 0; + struct resource *r; + int idx; + + if (uca_start) + return 0; + + for_each_pci_dev(dev) { + if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) { + for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) + continue; + if (r->flags & IORESOURCE_IO) + continue; + if (r->flags & IORESOURCE_MEM) { + uca_start = r->start; + uca_end = r->end; + return 0; + } + } + } + } + + return 0; +} + +late_initcall(find_vga_mem_init); +#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */ -- cgit v1.1