From 659da2ba3ebf53dc49f7f9a357a1aef046bf3139 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 16 Oct 2009 14:17:15 +0800 Subject: MIPS: Loongson: Register reserved memory pages Register reserved pages for Loongson family machines. Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Cc: yanh@lemote.com, Cc: huhb@lemote.com Cc: Zhang Le Cc: zhangfx@lemote.com, Signed-off-by: Ralf Baechle --- arch/mips/loongson/common/mem.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/mips/loongson/common/mem.c') diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index e94ef158f98..3f7f153b197 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -12,14 +12,22 @@ #include #include +#include void __init prom_init_memory(void) { add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); + + add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << + 20), BOOT_MEM_RESERVED); #ifdef CONFIG_64BIT if (highmemsize > 0) add_memory_region(LOONGSON_HIGHMEM_START, highmemsize << 20, BOOT_MEM_RAM); + + add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - + LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); + #endif /* CONFIG_64BIT */ } -- cgit v1.2.3-70-g09d2 From 6f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 6 Nov 2009 18:45:05 +0800 Subject: MIPS: Loongson: Add basic Loongson 2F support Loongson 2F has built-in DDR2 and PCI-X controller. The PCI-X controller has a programming interface similiar to the the FPGA northbridge used on Loongson 2E. The main differences between Loongson 2E and Loongson 2F include: 1. Loongson 2F has an extra address window configuration module, which is used to map CPU address space to DDR or PCI address space, or map the PCI-DMA address space to DDR or LIO address space. 2. Loongson 2F supports 8 levels of software configurable CPu frequency which can be configured in the LOONGSON_CHIPCFG0 register. The coming cpufreq and standby support are based on this feature. Loongson.h abstracts the modules and corresponding methods are abstracted. Add other Loongson-2F-specific source code including gcc 4.4 support, PCI memory space, PCI IO space, DMA address. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 18 +++++ arch/mips/Makefile | 2 + .../mips/include/asm/mach-loongson/dma-coherence.h | 4 ++ arch/mips/include/asm/mach-loongson/loongson.h | 84 +++++++++++++++++++++- arch/mips/include/asm/mach-loongson/mem.h | 27 ++++--- arch/mips/include/asm/mach-loongson/pci.h | 28 +++++++- arch/mips/loongson/common/bonito-irq.c | 5 +- arch/mips/loongson/common/init.c | 8 +++ arch/mips/loongson/common/mem.c | 33 ++++++--- arch/mips/loongson/common/pci.c | 8 +++ 10 files changed, 197 insertions(+), 20 deletions(-) (limited to 'arch/mips/loongson/common/mem.c') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a16b6dfe3bc..9618451011e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1073,6 +1073,21 @@ config CPU_LOONGSON2E The Loongson 2E processor implements the MIPS III instruction set with many extensions. + It has an internal FPGA northbridge, which is compatiable to + bonito64. + +config CPU_LOONGSON2F + bool "Loongson 2F" + depends on SYS_HAS_CPU_LOONGSON2F + select CPU_LOONGSON2 + help + The Loongson 2F processor implements the MIPS III instruction set + with many extensions. + + Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller + have a similar programming interface with FPGA northbridge used in + Loongson2E. + config CPU_MIPS32_R1 bool "MIPS32 Release 1" depends on SYS_HAS_CPU_MIPS32_R1 @@ -1317,6 +1332,9 @@ config CPU_LOONGSON2 config SYS_HAS_CPU_LOONGSON2E bool +config SYS_HAS_CPU_LOONGSON2F + bool + config SYS_HAS_CPU_MIPS32_R1 bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ba04782c4b9..47ecded2090 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -125,6 +125,8 @@ cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap cflags-$(CONFIG_CPU_LOONGSON2E) += \ $(call cc-option,-march=loongson2e,-march=r4600) +cflags-$(CONFIG_CPU_LOONGSON2F) += \ + $(call cc-option,-march=loongson2f,-march=r4600) cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ -Wa,-mips32 -Wa,--trap diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index 71a6851ba83..981c75f91a7 100644 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h @@ -28,7 +28,11 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); +#else return dma_addr & 0x7fffffff; +#endif } static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 722db9e811e..62171f240c7 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Copyright (C) 2009 Lemote, Inc. * Author: Wu Zhangjin * * This program is free software; you can redistribute it and/or modify it @@ -219,4 +219,86 @@ extern void mach_irq_dispatch(unsigned int pending); #define LOONGSON_PCIMAP_WIN(WIN, ADDR) \ ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) +/* Chip Config */ +#ifdef CONFIG_CPU_LOONGSON2F +#define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) +#endif + +/* + * address windows configuration module + * + * loongson2e do not have this module + */ +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + +/* address window config module base address */ +#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul +#define LOONGSON_ADDRWINCFG_SIZE 0x180 + +extern unsigned long _loongson_addrwincfg_base; +#define LOONGSON_ADDRWINCFG(offset) \ + (*(volatile u64 *)(_loongson_addrwincfg_base + (offset))) + +#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00) +#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08) +#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10) +#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18) + +#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20) +#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28) +#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30) +#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38) + +#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40) +#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48) +#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50) +#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58) + +#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60) +#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68) +#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70) +#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78) + +#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80) +#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88) +#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90) +#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98) + +#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0) +#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8) +#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0) +#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8) + +#define ADDRWIN_WIN0 0 +#define ADDRWIN_WIN1 1 +#define ADDRWIN_WIN2 2 +#define ADDRWIN_WIN3 3 + +#define ADDRWIN_MAP_DST_DDR 0 +#define ADDRWIN_MAP_DST_PCI 1 +#define ADDRWIN_MAP_DST_LIO 1 + +/* + * s: CPU, PCIDMA + * d: DDR, PCI, LIO + * win: 0, 1, 2, 3 + * src: map source + * dst: map destination + * size: ~mask + 1 + */ +#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\ + s##_WIN##w##_BASE = (src); \ + s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \ + s##_WIN##w##_MASK = ~(size-1); \ +} while (0) + +#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size) +#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size) +#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size) + +#endif /* ! CONFIG_CPU_LOONGSON2F && CONFIG_64BIT */ + #endif /* __ASM_MACH_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h index bd7b3cba7e3..e9960f341b9 100644 --- a/arch/mips/include/asm/mach-loongson/mem.h +++ b/arch/mips/include/asm/mach-loongson/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Copyright (C) 2009 Lemote, Inc. * Author: Wu Zhangjin * * This program is free software; you can redistribute it and/or modify it @@ -12,19 +12,30 @@ #define __ASM_MACH_LOONGSON_MEM_H /* - * On Lemote Loongson 2e + * high memory space * - * the high memory space starts from 512M. - * the peripheral registers reside between 0x1000:0000 and 0x2000:0000. + * in loongson2e, starts from 512M + * in loongson2f, starts from 2G 256M */ +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_HIGHMEM_START 0x20000000 +#else +#define LOONGSON_HIGHMEM_START 0x90000000 +#endif -#ifdef CONFIG_LEMOTE_FULOONG2E - -#define LOONGSON_HIGHMEM_START 0x20000000 +/* + * the peripheral registers(MMIO): + * + * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000. + * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000. + */ #define LOONGSON_MMIO_MEM_START 0x10000000 -#define LOONGSON_MMIO_MEM_END 0x20000000 +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_MMIO_MEM_END 0x20000000 +#else +#define LOONGSON_MMIO_MEM_END 0x80000000 #endif #endif /* __ASM_MACH_LOONGSON_MEM_H */ diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h index 576487c0047..31ba90891ec 100644 --- a/arch/mips/include/asm/mach-loongson/pci.h +++ b/arch/mips/include/asm/mach-loongson/pci.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2008 Zhang Le + * Copyright (c) 2009 Wu Zhangjin * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General @@ -24,7 +25,30 @@ extern struct pci_ops loongson_pci_ops; -#ifdef CONFIG_LEMOTE_FULOONG2E +/* this is an offset from mips_io_port_base */ +#define LOONGSON_PCI_IO_START 0x00004000UL + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + +/* + * we use address window2 to map cpu address space to pci space + * window2: cpu [1G, 2G] -> pci [1G, 2G] + * why not use window 0 & 1? because they are used by cpu when booting. + * window0: cpu [0, 256M] -> ddr [0, 256M] + * window1: cpu [256M, 512M] -> pci [256M, 512M] + */ + +/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */ +#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */ +#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC + +#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST +#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */ + +#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \ + LOONGSON_PCI_MEM_START + 1) + +#else /* loongson2f/32bit & loongson2e */ /* this pci memory space is mapped by pcimap in pci.c */ #define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE @@ -32,6 +56,6 @@ extern struct pci_ops loongson_pci_ops; /* this is an offset from mips_io_port_base */ #define LOONGSON_PCI_IO_START 0x00004000UL -#endif +#endif /* !(defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT))*/ #endif /* !__ASM_MACH_LOONGSON_PCI_H_ */ diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index a1cbd110a6e..2dc2a4cc632 100644 --- a/arch/mips/loongson/common/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c @@ -12,6 +12,7 @@ * option) any later version. */ #include +#include #include @@ -35,7 +36,7 @@ static struct irq_chip bonito_irq_type = { .unmask = bonito_irq_enable, }; -static struct irqaction dma_timeout_irqaction = { +static struct irqaction __maybe_unused dma_timeout_irqaction = { .handler = no_action, .name = "dma_timeout", }; @@ -47,5 +48,7 @@ void bonito_irq_init(void) for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); +#ifdef CONFIG_CPU_LOONGSON2E setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction); +#endif } diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index 3b1dbc1ca24..743d3571f01 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -12,12 +12,20 @@ #include +/* Loongson CPU address windows config space base address */ +unsigned long __maybe_unused _loongson_addrwincfg_base; + void __init prom_init(void) { /* init base address of io space */ set_io_port_base((unsigned long) ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + _loongson_addrwincfg_base = (unsigned long) + ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE); +#endif + prom_init_cmdline(); prom_init_env(); prom_init_memory(); diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index 3f7f153b197..e93551dbc9e 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -21,14 +21,31 @@ void __init prom_init_memory(void) add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << 20), BOOT_MEM_RESERVED); #ifdef CONFIG_64BIT - if (highmemsize > 0) - add_memory_region(LOONGSON_HIGHMEM_START, - highmemsize << 20, BOOT_MEM_RAM); - - add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - - LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); - -#endif /* CONFIG_64BIT */ +#ifdef CONFIG_CPU_LOONGSON2F + { + int bit; + + bit = fls(memsize + highmemsize); + if (bit != ffs(memsize + highmemsize)) + bit += 20; + else + bit = bit + 20 - 1; + + /* set cpu window3 to map CPU to DDR: 2G -> 2G */ + LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul, + 0x80000000ul, (1 << bit)); + mmiowb(); + } +#endif /* CONFIG_CPU_LOONGSON2F */ + + if (highmemsize > 0) + add_memory_region(LOONGSON_HIGHMEM_START, + highmemsize << 20, BOOT_MEM_RAM); + + add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - + LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); + +#endif /* CONFIG_64BIT */ } /* override of arch/mips/mm/cache.c: __uncached_access */ diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c index a7eb8b9c44e..eac43b8f695 100644 --- a/arch/mips/loongson/common/pci.c +++ b/arch/mips/loongson/common/pci.c @@ -67,6 +67,14 @@ static void __init setup_pcimap(void) /* can not change gnt to break pci transfer when device's gnt not deassert for some broken device */ LOONGSON_PXARB_CFG = 0x00fe0105ul; + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + /* + * set cpu addr window2 to map CPU address space to PCI address space + */ + LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC, + LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE); +#endif } static int __init pcibios_init(void) -- cgit v1.2.3-70-g09d2 From 55045ff5557bc804752e84dca5d1b1f1d4bb4e31 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 11 Nov 2009 13:39:12 +0800 Subject: MIPS: Loongson 2F: Cleanup the #if clauses This patch adds two new kernel options: CPU_SUPPORTS_CPUFREQ and CPU_SUPPORTS_ADDRWINCFG to describe the new features of Loongons 2F and replaces the several ugly #if clauses by them. These two options will be utilized by the future loongson revisions and related drivers such as the coming Loongson 2F CPUFreq driver. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: Wu Zhangjin Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 6 ++++++ arch/mips/include/asm/mach-loongson/loongson.h | 6 +++--- arch/mips/include/asm/mach-loongson/pci.h | 4 ++-- arch/mips/loongson/common/init.c | 2 +- arch/mips/loongson/common/mem.c | 8 ++++---- arch/mips/loongson/common/pci.c | 2 +- 6 files changed, 17 insertions(+), 11 deletions(-) (limited to 'arch/mips/loongson/common/mem.c') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c2b4cd51141..51e4e5b02f9 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1334,6 +1334,8 @@ config SYS_HAS_CPU_LOONGSON2E config SYS_HAS_CPU_LOONGSON2F bool + select CPU_SUPPORTS_CPUFREQ + select CPU_SUPPORTS_ADDRWINCFG if 64BIT config SYS_HAS_CPU_MIPS32_R1 bool @@ -1443,6 +1445,10 @@ config CPU_SUPPORTS_32BIT_KERNEL bool config CPU_SUPPORTS_64BIT_KERNEL bool +config CPU_SUPPORTS_CPUFREQ + bool +config CPU_SUPPORTS_ADDRWINCFG + bool config CPU_SUPPORTS_HUGEPAGES bool config MIPS_PGD_C0_CONTEXT diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 99113902719..9bccdb5d4b5 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -227,7 +227,7 @@ extern void mach_irq_dispatch(unsigned int pending); ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) /* Chip Config */ -#ifdef CONFIG_CPU_LOONGSON2F +#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ #define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) #endif @@ -236,7 +236,7 @@ extern void mach_irq_dispatch(unsigned int pending); * * loongson2e do not have this module */ -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG /* address window config module base address */ #define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul @@ -306,6 +306,6 @@ extern unsigned long _loongson_addrwincfg_base; #define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \ LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size) -#endif /* ! CONFIG_CPU_LOONGSON2F && CONFIG_64BIT */ +#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */ #endif /* __ASM_MACH_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h index 31ba90891ec..a199a4f6de4 100644 --- a/arch/mips/include/asm/mach-loongson/pci.h +++ b/arch/mips/include/asm/mach-loongson/pci.h @@ -28,7 +28,7 @@ extern struct pci_ops loongson_pci_ops; /* this is an offset from mips_io_port_base */ #define LOONGSON_PCI_IO_START 0x00004000UL -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG /* * we use address window2 to map cpu address space to pci space @@ -56,6 +56,6 @@ extern struct pci_ops loongson_pci_ops; /* this is an offset from mips_io_port_base */ #define LOONGSON_PCI_IO_START 0x00004000UL -#endif /* !(defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT))*/ +#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ #endif /* !__ASM_MACH_LOONGSON_PCI_H_ */ diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index 743d3571f01..2b92a23d29d 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -21,7 +21,7 @@ void __init prom_init(void) set_io_port_base((unsigned long) ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG _loongson_addrwincfg_base = (unsigned long) ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE); #endif diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index e93551dbc9e..981e9190f39 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -20,8 +20,7 @@ void __init prom_init_memory(void) add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << 20), BOOT_MEM_RESERVED); -#ifdef CONFIG_64BIT -#ifdef CONFIG_CPU_LOONGSON2F +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG { int bit; @@ -36,8 +35,9 @@ void __init prom_init_memory(void) 0x80000000ul, (1 << bit)); mmiowb(); } -#endif /* CONFIG_CPU_LOONGSON2F */ +#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ +#ifdef CONFIG_64BIT if (highmemsize > 0) add_memory_region(LOONGSON_HIGHMEM_START, highmemsize << 20, BOOT_MEM_RAM); @@ -45,7 +45,7 @@ void __init prom_init_memory(void) add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); -#endif /* CONFIG_64BIT */ +#endif /* !CONFIG_64BIT */ } /* override of arch/mips/mm/cache.c: __uncached_access */ diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c index eac43b8f695..31d8c5ecd16 100644 --- a/arch/mips/loongson/common/pci.c +++ b/arch/mips/loongson/common/pci.c @@ -68,7 +68,7 @@ static void __init setup_pcimap(void) deassert for some broken device */ LOONGSON_PXARB_CFG = 0x00fe0105ul; -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG /* * set cpu addr window2 to map CPU address space to PCI address space */ -- cgit v1.2.3-70-g09d2 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/mips/loongson/common/mem.c') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 51e4e5b02f9..e2116b1f968 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 d6eb6134abe..1854336e56a 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -389,6 +389,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 981e9190f39..ceacd092b44 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.2.3-70-g09d2