Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22f1fdfd authored by Wu Zhangjin's avatar Wu Zhangjin Committed by Ralf Baechle
Browse files

MIPS: Add support for uncached accelerated mappings.



Loongson2f support video acceleration.

Signed-off-by: default avatarWu Zhangjin <wuzhangjin@gmail.com>
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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 55045ff5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+13 −0
Original line number Diff line number Diff line
@@ -389,6 +389,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.
+58 −0
Original line number Diff line number Diff line
@@ -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 */