diff options
| -rw-r--r-- | arch/mips/Kconfig | 3 | ||||
| -rw-r--r-- | arch/mips/include/asm/pgtable.h | 13 | ||||
| -rw-r--r-- | arch/mips/loongson/common/mem.c | 58 | 
3 files changed, 74 insertions, 0 deletions
| diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 51e4e5b02f9d..e2116b1f968e 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 d6eb6134abec..1854336e56a2 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 <asm-generic/pgtable.h>  /* + * 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 981e9190f393..ceacd092b446 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 <linux/pci.h> +#include <linux/sched.h> +#include <asm/current.h> + +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 */ | 
