From 1b2e2b73b4c84c918686c04a00724197036c0847 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 21 Aug 2006 17:06:38 +0100 Subject: [ARM] Cleanup arch/arm/mm a little Move top_pmd into arch/arm/mm/mm.h - nothing outside arch/arm/mm references it. Move the repeated definition of TOP_PTE into mm/mm.h, as well as a few function prototypes. Signed-off-by: Russell King --- arch/arm/mm/copypage-v4mc.c | 4 ++-- arch/arm/mm/copypage-v6.c | 4 ++-- arch/arm/mm/copypage-xscale.c | 4 ++-- arch/arm/mm/flush.c | 4 ++-- arch/arm/mm/init.c | 20 +++++++------------- arch/arm/mm/mm-armv.c | 14 ++------------ arch/arm/mm/mm.h | 19 +++++++++++++++++++ 7 files changed, 36 insertions(+), 33 deletions(-) create mode 100644 arch/arm/mm/mm.h (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index fc69dccdace1..df1645e14b4c 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -20,6 +20,8 @@ #include #include +#include "mm.h" + /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -27,8 +29,6 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_CACHEABLE) -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static DEFINE_SPINLOCK(minicache_lock); /* diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 269ce6913ee9..3d0d3a963d20 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -17,6 +17,8 @@ #include #include +#include "mm.h" + #if SHMLBA > 16384 #error FIX ME #endif @@ -24,8 +26,6 @@ #define from_address (0xffff8000) #define to_address (0xffffc000) -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static DEFINE_SPINLOCK(v6_lock); /* diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 42a6ee255ce0..84ebe0aa379e 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -20,6 +20,8 @@ #include #include +#include "mm.h" + /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -29,8 +31,6 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_CACHEABLE) -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static DEFINE_SPINLOCK(minicache_lock); /* diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index d438ce41cdd5..1efb05c64db3 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -15,12 +15,12 @@ #include #include +#include "mm.h" + #ifdef CONFIG_CPU_CACHE_VIPT #define ALIAS_FLUSH_START 0xffff4000 -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) { unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index fe3f7f625008..1099af6d470a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -25,6 +25,8 @@ #include #include +#include "mm.h" + DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; @@ -44,6 +46,11 @@ static struct meminfo meminfo __initdata = { 0, }; */ struct page *empty_zero_page; +/* + * The pmd table for the upper-most set of pages. + */ +pmd_t *top_pmd; + void show_mem(void) { int free = 0, total = 0, reserved = 0; @@ -83,16 +90,6 @@ void show_mem(void) printk("%d pages swap cached\n", cached); } -static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) -{ - return pmd_offset(pgd, virt); -} - -static inline pmd_t *pmd_off_k(unsigned long virt) -{ - return pmd_off(pgd_offset_k(virt), virt); -} - #define for_each_nodebank(iter,mi,no) \ for (iter = 0; iter < mi->nr_banks; iter++) \ if (mi->bank[iter].node == no) @@ -229,9 +226,6 @@ static __init void reserve_node_zero(pg_data_t *pgdat) reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); } -void __init build_mem_type_table(void); -void __init create_mapping(struct map_desc *md); - static unsigned long __init bootmem_init_node(int node, int initrd_node, struct meminfo *mi) { diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 38769f5862bc..ee9647823fad 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -23,6 +23,8 @@ #include +#include "mm.h" + #define CPOLICY_UNCACHED 0 #define CPOLICY_BUFFERED 1 #define CPOLICY_WRITETHROUGH 2 @@ -35,8 +37,6 @@ pgprot_t pgprot_kernel; EXPORT_SYMBOL(pgprot_kernel); -pmd_t *top_pmd; - struct cachepolicy { const char policy[16]; unsigned int cr_mask; @@ -142,16 +142,6 @@ __setup("noalign", noalign_setup); #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) -static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) -{ - return pmd_offset(pgd, virt); -} - -static inline pmd_t *pmd_off_k(unsigned long virt) -{ - return pmd_off(pgd_offset_k(virt), virt); -} - /* * need to get a 16k page for level 1 */ diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h new file mode 100644 index 000000000000..8d73ffbce8df --- /dev/null +++ b/arch/arm/mm/mm.h @@ -0,0 +1,19 @@ +/* the upper-most page table pointer */ +extern pmd_t *top_pmd; + +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) + +static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) +{ + return pmd_offset(pgd, virt); +} + +static inline pmd_t *pmd_off_k(unsigned long virt) +{ + return pmd_off(pgd_offset_k(virt), virt); +} + +struct map_desc; + +void __init build_mem_type_table(void); +void __init create_mapping(struct map_desc *md); -- cgit v1.2.3-70-g09d2 From d84b47115a04d9f6b0da777e8aa8cd930d5b6b8b Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 21 Aug 2006 19:23:38 +0100 Subject: [ARM] Move mmu.c out of the way Rename mmu.c to context.c - it's the ARMv6 ASID context handling code rather than generic "mmu" handling code. Signed-off-by: Russell King --- arch/arm/mm/Makefile | 2 +- arch/arm/mm/context.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/mmu.c | 45 --------------------------------------------- 3 files changed, 46 insertions(+), 46 deletions(-) create mode 100644 arch/arm/mm/context.c delete mode 100644 arch/arm/mm/mmu.c (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 21a2770226ee..1a1563f859af 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -33,7 +33,7 @@ obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o -obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o +obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c new file mode 100644 index 000000000000..79e800202424 --- /dev/null +++ b/arch/arm/mm/context.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mm/context.c + * + * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include + +#include +#include + +unsigned int cpu_last_asid = { 1 << ASID_BITS }; + +/* + * We fork()ed a process, and we need a new context for the child + * to run in. We reserve version 0 for initial tasks so we will + * always allocate an ASID. + */ +void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + mm->context.id = 0; +} + +void __new_context(struct mm_struct *mm) +{ + unsigned int asid; + + asid = ++cpu_last_asid; + if (asid == 0) + asid = cpu_last_asid = 1 << ASID_BITS; + + /* + * If we've used up all our ASIDs, we need + * to start a new version and flush the TLB. + */ + if ((asid & ~ASID_MASK) == 0) + flush_tlb_all(); + + mm->context.id = asid; +} diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c deleted file mode 100644 index 0d90227a0a32..000000000000 --- a/arch/arm/mm/mmu.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/arm/mm/mmu.c - * - * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -#include -#include - -unsigned int cpu_last_asid = { 1 << ASID_BITS }; - -/* - * We fork()ed a process, and we need a new context for the child - * to run in. We reserve version 0 for initial tasks so we will - * always allocate an ASID. - */ -void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - mm->context.id = 0; -} - -void __new_context(struct mm_struct *mm) -{ - unsigned int asid; - - asid = ++cpu_last_asid; - if (asid == 0) - asid = cpu_last_asid = 1 << ASID_BITS; - - /* - * If we've used up all our ASIDs, we need - * to start a new version and flush the TLB. - */ - if ((asid & ~ASID_MASK) == 0) - flush_tlb_all(); - - mm->context.id = asid; -} -- cgit v1.2.3-70-g09d2 From 51635ad282ead58b9d164f07e1fb62a9456b427c Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 16 Sep 2006 10:50:22 +0100 Subject: [ARM] 3813/1: prevent >= 4G /dev/mem mmap() Prevent userland from mapping in physical address regions >= 4G by checking for that in valid_mmap_phys_addr_range(). Unfortunately, we cannot override valid_mmap_phys_addr_range() without also overriding valid_phys_addr_range(), so copy drivers/char/mem.c's version of valid_phys_addr_range() over to arch/arm/mm/mmap.c as well. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mm/mmap.c | 22 ++++++++++++++++++++++ include/asm-arm/io.h | 4 ++++ 2 files changed, 26 insertions(+) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 29e54807c5bc..b0b5f4694070 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -114,3 +114,25 @@ full_search: } } + +/* + * You really shouldn't be using read() or write() on /dev/mem. This + * might go away in the future. + */ +int valid_phys_addr_range(unsigned long addr, size_t size) +{ + if (addr + size > __pa(high_memory)) + return 0; + + return 1; +} + +/* + * We don't use supersection mappings for mmap() on /dev/mem, which + * means that we can't map the memory area above the 4G barrier into + * userspace. + */ +int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) +{ + return !(pfn + (size >> PAGE_SHIFT) > 0x00100000); +} diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index bf7b9dea30f1..8076a85c3675 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -280,6 +280,10 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); #define BIOVEC_MERGEABLE(vec1, vec2) \ ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE +extern int valid_phys_addr_range(unsigned long addr, size_t size); +extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); + /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem * access -- cgit v1.2.3-70-g09d2 From 197c9444d6093b70c8faa24e7ab04a2423c9d14d Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 16 Sep 2006 10:52:02 +0100 Subject: [ARM] 3814/1: move 80200 dma_inv_range() erratum check out of line On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't clear the dirty bits, which means that if we invalidate a dirty line, the dirty data can still be written back to memory later on. To work around this, dma_inv_range() on these two processors is implemented as dma_flush_range() (i.e. do a clean D-cache line before doing the invalidate D-cache line.) For this, we currently have a processor ID check in xscale_dma_inv_range(), but a better solution is to add a separate cache_fns and proc_info for A0/A1 80200. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mm/proc-xscale.S | 58 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 3ca0c92e98a2..e8b377d637f6 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -311,12 +311,6 @@ ENTRY(xscale_flush_kern_dcache_page) * - end - virtual end address */ ENTRY(xscale_dma_inv_range) - mrc p15, 0, r2, c0, c0, 0 @ read ID - eor r2, r2, #0x69000000 - eor r2, r2, #0x00052000 - bics r2, r2, #1 - beq xscale_dma_flush_range - tst r0, #CACHELINESIZE - 1 bic r0, r0, #CACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry @@ -375,6 +369,30 @@ ENTRY(xscale_cache_fns) .long xscale_dma_clean_range .long xscale_dma_flush_range +/* + * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't + * clear the dirty bits, which means that if we invalidate a dirty line, + * the dirty data can still be written back to external memory later on. + * + * The recommended workaround is to always do a clean D-cache line before + * doing an invalidate D-cache line, so on the affected processors, + * dma_inv_range() is implemented as dma_flush_range(). + * + * See erratum #25 of "Intel 80200 Processor Specification Update", + * revision January 22, 2003, available at: + * http://www.intel.com/design/iio/specupdt/273415.htm + */ +ENTRY(xscale_80200_A0_A1_cache_fns) + .long xscale_flush_kern_cache_all + .long xscale_flush_user_cache_all + .long xscale_flush_user_cache_range + .long xscale_coherent_kern_range + .long xscale_coherent_user_range + .long xscale_flush_kern_dcache_page + .long xscale_dma_flush_range + .long xscale_dma_clean_range + .long xscale_dma_flush_range + ENTRY(cpu_xscale_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHELINESIZE @@ -531,6 +549,11 @@ cpu_elf_name: .asciz "v5" .size cpu_elf_name, . - cpu_elf_name + .type cpu_80200_A0_A1_name, #object +cpu_80200_A0_A1_name: + .asciz "XScale-80200 A0/A1" + .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name + .type cpu_80200_name, #object cpu_80200_name: .asciz "XScale-80200" @@ -595,6 +618,29 @@ cpu_pxa270_name: .section ".proc.info.init", #alloc, #execinstr + .type __80200_A0_A1_proc_info,#object +__80200_A0_A1_proc_info: + .long 0x69052000 + .long 0xfffffffe + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + .long PMD_TYPE_SECT | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_80200_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_80200_A0_A1_cache_fns + .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info + .type __80200_proc_info,#object __80200_proc_info: .long 0x69052000 -- cgit v1.2.3-70-g09d2 From 3f7e5815f4b774270e6506962de37af85aa9c830 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 18 Sep 2006 23:10:26 +0100 Subject: [ARM] 3817/1: iop3xx: split the iop3xx mach into iop32x and iop33x Split the iop3xx mach type into iop32x and iop33x -- split the config symbols, and move the code in the mach-iop3xx directory to the mach-iop32x and mach-iop33x directories. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/Kconfig | 20 +- arch/arm/Makefile | 3 +- arch/arm/configs/ep80219_defconfig | 5 +- arch/arm/configs/iq31244_defconfig | 5 +- arch/arm/configs/iq80321_defconfig | 5 +- arch/arm/configs/iq80331_defconfig | 4 +- arch/arm/configs/iq80332_defconfig | 4 +- arch/arm/mach-iop32x/Kconfig | 28 +++ arch/arm/mach-iop32x/Makefile | 11 + arch/arm/mach-iop32x/Makefile.boot | 3 + arch/arm/mach-iop32x/common.c | 72 ++++++ arch/arm/mach-iop32x/iq31244-mm.c | 45 ++++ arch/arm/mach-iop32x/iq31244-pci.c | 129 +++++++++++ arch/arm/mach-iop32x/iq80321-mm.c | 45 ++++ arch/arm/mach-iop32x/iq80321-pci.c | 123 ++++++++++ arch/arm/mach-iop32x/irq.c | 97 ++++++++ arch/arm/mach-iop32x/pci.c | 220 ++++++++++++++++++ arch/arm/mach-iop32x/setup.c | 173 ++++++++++++++ arch/arm/mach-iop32x/time.c | 108 +++++++++ arch/arm/mach-iop33x/Kconfig | 27 +++ arch/arm/mach-iop33x/Makefile | 11 + arch/arm/mach-iop33x/Makefile.boot | 3 + arch/arm/mach-iop33x/common.c | 22 ++ arch/arm/mach-iop33x/iq80331-mm.c | 35 +++ arch/arm/mach-iop33x/iq80331-pci.c | 119 ++++++++++ arch/arm/mach-iop33x/iq80332-mm.c | 35 +++ arch/arm/mach-iop33x/iq80332-pci.c | 125 ++++++++++ arch/arm/mach-iop33x/irq.c | 129 +++++++++++ arch/arm/mach-iop33x/pci.c | 222 ++++++++++++++++++ arch/arm/mach-iop33x/setup.c | 221 ++++++++++++++++++ arch/arm/mach-iop33x/time.c | 106 +++++++++ arch/arm/mach-iop3xx/Kconfig | 66 ------ arch/arm/mach-iop3xx/Makefile | 23 -- arch/arm/mach-iop3xx/Makefile.boot | 9 - arch/arm/mach-iop3xx/common.c | 72 ------ arch/arm/mach-iop3xx/iop321-irq.c | 97 -------- arch/arm/mach-iop3xx/iop321-pci.c | 220 ------------------ arch/arm/mach-iop3xx/iop321-setup.c | 173 -------------- arch/arm/mach-iop3xx/iop321-time.c | 108 --------- arch/arm/mach-iop3xx/iop331-irq.c | 129 ----------- arch/arm/mach-iop3xx/iop331-pci.c | 222 ------------------ arch/arm/mach-iop3xx/iop331-setup.c | 221 ------------------ arch/arm/mach-iop3xx/iop331-time.c | 106 --------- arch/arm/mach-iop3xx/iq31244-mm.c | 45 ---- arch/arm/mach-iop3xx/iq31244-pci.c | 129 ----------- arch/arm/mach-iop3xx/iq80321-mm.c | 45 ---- arch/arm/mach-iop3xx/iq80321-pci.c | 123 ---------- arch/arm/mach-iop3xx/iq80331-mm.c | 35 --- arch/arm/mach-iop3xx/iq80331-pci.c | 119 ---------- arch/arm/mach-iop3xx/iq80332-mm.c | 35 --- arch/arm/mach-iop3xx/iq80332-pci.c | 125 ---------- arch/arm/mm/Kconfig | 2 +- drivers/i2c/busses/Kconfig | 2 +- include/asm-arm/arch-iop32x/debug-macro.S | 20 ++ include/asm-arm/arch-iop32x/dma.h | 9 + include/asm-arm/arch-iop32x/entry-macro.S | 28 +++ include/asm-arm/arch-iop32x/hardware.h | 54 +++++ include/asm-arm/arch-iop32x/io.h | 21 ++ include/asm-arm/arch-iop32x/iop321.h | 341 ++++++++++++++++++++++++++++ include/asm-arm/arch-iop32x/iq31244.h | 24 ++ include/asm-arm/arch-iop32x/iq80321.h | 24 ++ include/asm-arm/arch-iop32x/irqs.h | 98 ++++++++ include/asm-arm/arch-iop32x/memory.h | 27 +++ include/asm-arm/arch-iop32x/system.h | 29 +++ include/asm-arm/arch-iop32x/timex.h | 8 + include/asm-arm/arch-iop32x/uncompress.h | 38 ++++ include/asm-arm/arch-iop32x/vmalloc.h | 16 ++ include/asm-arm/arch-iop33x/debug-macro.S | 24 ++ include/asm-arm/arch-iop33x/dma.h | 9 + include/asm-arm/arch-iop33x/entry-macro.S | 34 +++ include/asm-arm/arch-iop33x/hardware.h | 54 +++++ include/asm-arm/arch-iop33x/io.h | 21 ++ include/asm-arm/arch-iop33x/iop331.h | 358 +++++++++++++++++++++++++++++ include/asm-arm/arch-iop33x/iq80331.h | 23 ++ include/asm-arm/arch-iop33x/iq80332.h | 23 ++ include/asm-arm/arch-iop33x/irqs.h | 130 +++++++++++ include/asm-arm/arch-iop33x/memory.h | 26 +++ include/asm-arm/arch-iop33x/system.h | 29 +++ include/asm-arm/arch-iop33x/timex.h | 8 + include/asm-arm/arch-iop33x/uncompress.h | 36 +++ include/asm-arm/arch-iop33x/vmalloc.h | 16 ++ include/asm-arm/arch-iop3xx/debug-macro.S | 35 --- include/asm-arm/arch-iop3xx/dma.h | 9 - include/asm-arm/arch-iop3xx/entry-macro.S | 57 ----- include/asm-arm/arch-iop3xx/hardware.h | 57 ----- include/asm-arm/arch-iop3xx/io.h | 21 -- include/asm-arm/arch-iop3xx/iop321-irqs.h | 100 -------- include/asm-arm/arch-iop3xx/iop321.h | 345 ---------------------------- include/asm-arm/arch-iop3xx/iop331-irqs.h | 132 ----------- include/asm-arm/arch-iop3xx/iop331.h | 363 ------------------------------ include/asm-arm/arch-iop3xx/iq31244.h | 24 -- include/asm-arm/arch-iop3xx/iq80321.h | 24 -- include/asm-arm/arch-iop3xx/iq80331.h | 23 -- include/asm-arm/arch-iop3xx/iq80332.h | 23 -- include/asm-arm/arch-iop3xx/irqs.h | 21 -- include/asm-arm/arch-iop3xx/memory.h | 38 ---- include/asm-arm/arch-iop3xx/system.h | 35 --- include/asm-arm/arch-iop3xx/timex.h | 20 -- include/asm-arm/arch-iop3xx/uncompress.h | 48 ---- include/asm-arm/arch-iop3xx/vmalloc.h | 16 -- 100 files changed, 3666 insertions(+), 3514 deletions(-) create mode 100644 arch/arm/mach-iop32x/Kconfig create mode 100644 arch/arm/mach-iop32x/Makefile create mode 100644 arch/arm/mach-iop32x/Makefile.boot create mode 100644 arch/arm/mach-iop32x/common.c create mode 100644 arch/arm/mach-iop32x/iq31244-mm.c create mode 100644 arch/arm/mach-iop32x/iq31244-pci.c create mode 100644 arch/arm/mach-iop32x/iq80321-mm.c create mode 100644 arch/arm/mach-iop32x/iq80321-pci.c create mode 100644 arch/arm/mach-iop32x/irq.c create mode 100644 arch/arm/mach-iop32x/pci.c create mode 100644 arch/arm/mach-iop32x/setup.c create mode 100644 arch/arm/mach-iop32x/time.c create mode 100644 arch/arm/mach-iop33x/Kconfig create mode 100644 arch/arm/mach-iop33x/Makefile create mode 100644 arch/arm/mach-iop33x/Makefile.boot create mode 100644 arch/arm/mach-iop33x/common.c create mode 100644 arch/arm/mach-iop33x/iq80331-mm.c create mode 100644 arch/arm/mach-iop33x/iq80331-pci.c create mode 100644 arch/arm/mach-iop33x/iq80332-mm.c create mode 100644 arch/arm/mach-iop33x/iq80332-pci.c create mode 100644 arch/arm/mach-iop33x/irq.c create mode 100644 arch/arm/mach-iop33x/pci.c create mode 100644 arch/arm/mach-iop33x/setup.c create mode 100644 arch/arm/mach-iop33x/time.c delete mode 100644 arch/arm/mach-iop3xx/Kconfig delete mode 100644 arch/arm/mach-iop3xx/Makefile delete mode 100644 arch/arm/mach-iop3xx/Makefile.boot delete mode 100644 arch/arm/mach-iop3xx/common.c delete mode 100644 arch/arm/mach-iop3xx/iop321-irq.c delete mode 100644 arch/arm/mach-iop3xx/iop321-pci.c delete mode 100644 arch/arm/mach-iop3xx/iop321-setup.c delete mode 100644 arch/arm/mach-iop3xx/iop321-time.c delete mode 100644 arch/arm/mach-iop3xx/iop331-irq.c delete mode 100644 arch/arm/mach-iop3xx/iop331-pci.c delete mode 100644 arch/arm/mach-iop3xx/iop331-setup.c delete mode 100644 arch/arm/mach-iop3xx/iop331-time.c delete mode 100644 arch/arm/mach-iop3xx/iq31244-mm.c delete mode 100644 arch/arm/mach-iop3xx/iq31244-pci.c delete mode 100644 arch/arm/mach-iop3xx/iq80321-mm.c delete mode 100644 arch/arm/mach-iop3xx/iq80321-pci.c delete mode 100644 arch/arm/mach-iop3xx/iq80331-mm.c delete mode 100644 arch/arm/mach-iop3xx/iq80331-pci.c delete mode 100644 arch/arm/mach-iop3xx/iq80332-mm.c delete mode 100644 arch/arm/mach-iop3xx/iq80332-pci.c create mode 100644 include/asm-arm/arch-iop32x/debug-macro.S create mode 100644 include/asm-arm/arch-iop32x/dma.h create mode 100644 include/asm-arm/arch-iop32x/entry-macro.S create mode 100644 include/asm-arm/arch-iop32x/hardware.h create mode 100644 include/asm-arm/arch-iop32x/io.h create mode 100644 include/asm-arm/arch-iop32x/iop321.h create mode 100644 include/asm-arm/arch-iop32x/iq31244.h create mode 100644 include/asm-arm/arch-iop32x/iq80321.h create mode 100644 include/asm-arm/arch-iop32x/irqs.h create mode 100644 include/asm-arm/arch-iop32x/memory.h create mode 100644 include/asm-arm/arch-iop32x/system.h create mode 100644 include/asm-arm/arch-iop32x/timex.h create mode 100644 include/asm-arm/arch-iop32x/uncompress.h create mode 100644 include/asm-arm/arch-iop32x/vmalloc.h create mode 100644 include/asm-arm/arch-iop33x/debug-macro.S create mode 100644 include/asm-arm/arch-iop33x/dma.h create mode 100644 include/asm-arm/arch-iop33x/entry-macro.S create mode 100644 include/asm-arm/arch-iop33x/hardware.h create mode 100644 include/asm-arm/arch-iop33x/io.h create mode 100644 include/asm-arm/arch-iop33x/iop331.h create mode 100644 include/asm-arm/arch-iop33x/iq80331.h create mode 100644 include/asm-arm/arch-iop33x/iq80332.h create mode 100644 include/asm-arm/arch-iop33x/irqs.h create mode 100644 include/asm-arm/arch-iop33x/memory.h create mode 100644 include/asm-arm/arch-iop33x/system.h create mode 100644 include/asm-arm/arch-iop33x/timex.h create mode 100644 include/asm-arm/arch-iop33x/uncompress.h create mode 100644 include/asm-arm/arch-iop33x/vmalloc.h delete mode 100644 include/asm-arm/arch-iop3xx/debug-macro.S delete mode 100644 include/asm-arm/arch-iop3xx/dma.h delete mode 100644 include/asm-arm/arch-iop3xx/entry-macro.S delete mode 100644 include/asm-arm/arch-iop3xx/hardware.h delete mode 100644 include/asm-arm/arch-iop3xx/io.h delete mode 100644 include/asm-arm/arch-iop3xx/iop321-irqs.h delete mode 100644 include/asm-arm/arch-iop3xx/iop321.h delete mode 100644 include/asm-arm/arch-iop3xx/iop331-irqs.h delete mode 100644 include/asm-arm/arch-iop3xx/iop331.h delete mode 100644 include/asm-arm/arch-iop3xx/iq31244.h delete mode 100644 include/asm-arm/arch-iop3xx/iq80321.h delete mode 100644 include/asm-arm/arch-iop3xx/iq80331.h delete mode 100644 include/asm-arm/arch-iop3xx/iq80332.h delete mode 100644 include/asm-arm/arch-iop3xx/irqs.h delete mode 100644 include/asm-arm/arch-iop3xx/memory.h delete mode 100644 include/asm-arm/arch-iop3xx/system.h delete mode 100644 include/asm-arm/arch-iop3xx/timex.h delete mode 100644 include/asm-arm/arch-iop3xx/uncompress.h delete mode 100644 include/asm-arm/arch-iop3xx/vmalloc.h (limited to 'arch/arm/mm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d9376f048ed7..0fb17bbb86bc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -202,12 +202,20 @@ config ARCH_IMX help Support for Motorola's i.MX family of processors (MX1, MXL). -config ARCH_IOP3XX - bool "IOP3xx-based" +config ARCH_IOP32X + bool "IOP32x-based" depends on MMU select PCI help - Support for Intel's IOP3XX (XScale) family of processors. + Support for Intel's 80219 and IOP32X (XScale) family of + processors. + +config ARCH_IOP33X + bool "IOP33x-based" + depends on MMU + select PCI + help + Support for Intel's IOP33X (XScale) family of processors. config ARCH_IXP4XX bool "IXP4xx-based" @@ -312,7 +320,9 @@ source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-integrator/Kconfig" -source "arch/arm/mach-iop3xx/Kconfig" +source "arch/arm/mach-iop32x/Kconfig" + +source "arch/arm/mach-iop33x/Kconfig" source "arch/arm/mach-ixp4xx/Kconfig" @@ -848,7 +858,7 @@ source "drivers/block/Kconfig" source "drivers/acorn/block/Kconfig" -if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ +if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ || ARCH_IXP23XX diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 92873cdee31f..ac786bf0f546 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -101,7 +101,8 @@ endif machine-$(CONFIG_ARCH_INTEGRATOR) := integrator textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x - machine-$(CONFIG_ARCH_IOP3XX) := iop3xx + machine-$(CONFIG_ARCH_IOP32X) := iop32x + machine-$(CONFIG_ARCH_IOP33X) := iop33x machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx diff --git a/arch/arm/configs/ep80219_defconfig b/arch/arm/configs/ep80219_defconfig index 199f1567345d..f91cf8ff359d 100644 --- a/arch/arm/configs/ep80219_defconfig +++ b/arch/arm/configs/ep80219_defconfig @@ -66,7 +66,8 @@ CONFIG_KMOD=y # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +CONFIG_ARCH_IOP32X=y +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_L7200 is not set @@ -93,8 +94,6 @@ CONFIG_ARCH_IQ31244=y # CONFIG_ARCH_IQ80331 is not set # CONFIG_MACH_IQ80332 is not set CONFIG_ARCH_EP80219=y -CONFIG_ARCH_IOP32X=y -# CONFIG_ARCH_IOP33X is not set # # IOP3xx Chipset Features diff --git a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig index 27f884417b90..ce1b1f20b763 100644 --- a/arch/arm/configs/iq31244_defconfig +++ b/arch/arm/configs/iq31244_defconfig @@ -67,7 +67,8 @@ CONFIG_KMOD=y # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +CONFIG_ARCH_IOP32X=y +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_L7200 is not set @@ -94,8 +95,6 @@ CONFIG_ARCH_IQ31244=y # CONFIG_ARCH_IQ80331 is not set # CONFIG_MACH_IQ80332 is not set # CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP32X=y -# CONFIG_ARCH_IOP33X is not set # # IOP3xx Chipset Features diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig index 33f21a24cf4e..f00b0d2159dd 100644 --- a/arch/arm/configs/iq80321_defconfig +++ b/arch/arm/configs/iq80321_defconfig @@ -66,7 +66,8 @@ CONFIG_KMOD=y # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +CONFIG_ARCH_IOP32X=y +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_L7200 is not set @@ -93,8 +94,6 @@ CONFIG_ARCH_IQ80321=y # CONFIG_ARCH_IQ80331 is not set # CONFIG_MACH_IQ80332 is not set # CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP32X=y -# CONFIG_ARCH_IOP33X is not set # # IOP3xx Chipset Features diff --git a/arch/arm/configs/iq80331_defconfig b/arch/arm/configs/iq80331_defconfig index 67a8bd7dba29..af3a87e469d5 100644 --- a/arch/arm/configs/iq80331_defconfig +++ b/arch/arm/configs/iq80331_defconfig @@ -66,7 +66,8 @@ CONFIG_KMOD=y # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IOP32X is not set +CONFIG_ARCH_IOP33X=y # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_L7200 is not set @@ -93,7 +94,6 @@ CONFIG_ARCH_IOP3XX=y CONFIG_ARCH_IQ80331=y # CONFIG_MACH_IQ80332 is not set # CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP33X=y # # IOP3xx Chipset Features diff --git a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iq80332_defconfig index c8dea45cb017..931c78755a30 100644 --- a/arch/arm/configs/iq80332_defconfig +++ b/arch/arm/configs/iq80332_defconfig @@ -66,7 +66,8 @@ CONFIG_KMOD=y # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IOP32X is not set +CONFIG_ARCH_IOP33X=y # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_L7200 is not set @@ -93,7 +94,6 @@ CONFIG_ARCH_IOP3XX=y # CONFIG_ARCH_IQ80331 is not set CONFIG_MACH_IQ80332=y # CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP33X=y # # IOP3xx Chipset Features diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig new file mode 100644 index 000000000000..21e3e8c8c2ad --- /dev/null +++ b/arch/arm/mach-iop32x/Kconfig @@ -0,0 +1,28 @@ +if ARCH_IOP32X + +menu "IOP32x Implementation Options" + +comment "IOP32x Platform Types" + +config ARCH_IQ80321 + bool "Enable support for IQ80321" + help + Say Y here if you want to run your kernel on the Intel IQ80321 + evaluation kit for the IOP321 chipset. + +config ARCH_IQ31244 + bool "Enable support for IQ31244" + help + Say Y here if you want to run your kernel on the Intel IQ31244 + evaluation kit for the IOP321 chipset. + +config ARCH_EP80219 + bool "Enable support for EP80219" + select ARCH_IQ31244 + help + Say Y here if you want to run your kernel on the Intel EP80219 + evaluation kit for the Intel 80219 chipset (a IOP321 variant). + +endmenu + +endif diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile new file mode 100644 index 000000000000..94144f7efa6c --- /dev/null +++ b/arch/arm/mach-iop32x/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +obj-y := common.o setup.o irq.o pci.o time.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_IQ80321) += iq80321-mm.o iq80321-pci.o +obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o diff --git a/arch/arm/mach-iop32x/Makefile.boot b/arch/arm/mach-iop32x/Makefile.boot new file mode 100644 index 000000000000..47000dccd61f --- /dev/null +++ b/arch/arm/mach-iop32x/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0xa0008000 +params_phys-y := 0xa0000100 +initrd_phys-y := 0xa0800000 diff --git a/arch/arm/mach-iop32x/common.c b/arch/arm/mach-iop32x/common.c new file mode 100644 index 000000000000..8044af6a54e1 --- /dev/null +++ b/arch/arm/mach-iop32x/common.c @@ -0,0 +1,72 @@ +/* + * arch/arm/mach-iop32x/common.c + * + * Common routines shared across all IOP3xx implementations + * + * Author: Deepak Saxena + * + * Copyright 2003 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include + +/* + * Shared variables + */ +unsigned long iop3xx_pcibios_min_io = 0; +unsigned long iop3xx_pcibios_min_mem = 0; + +#ifdef CONFIG_ARCH_EP80219 +#include +/* + * Default power-off for EP80219 + */ + +static inline void ep80219_send_to_pic(__u8 c) { +} + +void ep80219_power_off(void) +{ + /* + * This function will send a SHUTDOWN_COMPLETE message to the PIC controller + * over I2C. We are not using the i2c subsystem since we are going to power + * off and it may be removed + */ + + /* Send the Address byte w/ the start condition */ + *IOP321_IDBR1 = 0x60; + *IOP321_ICR1 = 0xE9; + mdelay(1); + + /* Send the START_MSG byte w/ no start or stop condition */ + *IOP321_IDBR1 = 0x0F; + *IOP321_ICR1 = 0xE8; + mdelay(1); + + /* Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or stop condition */ + *IOP321_IDBR1 = 0x03; + *IOP321_ICR1 = 0xE8; + mdelay(1); + + /* Send an ignored byte w/ stop condition */ + *IOP321_IDBR1 = 0x00; + *IOP321_ICR1 = 0xEA; + + while (1) ; +} + +#include +#include + +static int __init ep80219_init(void) +{ + pm_power_off = ep80219_power_off; + return 0; +} +arch_initcall(ep80219_init); +#endif diff --git a/arch/arm/mach-iop32x/iq31244-mm.c b/arch/arm/mach-iop32x/iq31244-mm.c new file mode 100644 index 000000000000..ffc6692c95ad --- /dev/null +++ b/arch/arm/mach-iop32x/iq31244-mm.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-iop32x/iq31244-mm.c + * + * Low level memory initialization for iq80321 platform + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80321 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ +static struct map_desc iq31244_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = IQ31244_UART, + .pfn = __phys_to_pfn(IQ31244_UART), + .length = 0x00100000, + .type = MT_DEVICE + } +}; + +void __init iq31244_map_io(void) +{ + iop321_map_io(); + + iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc)); +} diff --git a/arch/arm/mach-iop32x/iq31244-pci.c b/arch/arm/mach-iop32x/iq31244-pci.c new file mode 100644 index 000000000000..e447c8103ecd --- /dev/null +++ b/arch/arm/mach-iop32x/iq31244-pci.c @@ -0,0 +1,129 @@ +/* + * arch/arm/mach-iop32x/iq31244-pci.c + * + * PCI support for the Intel IQ31244 reference board + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ31244_INTA +#define INTB IRQ_IQ31244_INTB +#define INTC IRQ_IQ31244_INTC +#define INTD IRQ_IQ31244_INTD + +#define INTE IRQ_IQ31244_I82546 + +static inline int __init +iq31244_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ +#ifdef CONFIG_ARCH_EP80219 + {INTB, INTB, INTB, INTB}, /* CFlash */ + {INTE, INTE, INTE, INTE}, /* 82551 Pro 100 */ + {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ + {INTC, INTC, INTC, INTC}, /* SATA */ +#else + {INTB, INTB, INTB, INTB}, /* CFlash */ + {INTC, INTC, INTC, INTC}, /* SATA */ + {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ + {INTE, INTE, INTE, INTE}, /* 82546 GigE */ +#endif // CONFIG_ARCH_EP80219 + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(0, 7); +} + +static int iq31244_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP321_PCI_LOWER_IO_VA; + res[0].end = IOP321_PCI_UPPER_IO_VA; + res[0].name = "IQ31244 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP321_PCI_LOWER_MEM_PA; + res[1].end = IOP321_PCI_UPPER_MEM_PA; + res[1].name = "IQ31244 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP321_PCI_MEM_OFFSET; + sys->io_offset = IOP321_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq31244_preinit(void) +{ + iop321_init(); +} + +static struct hw_pci iq31244_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq31244_setup, + .scan = iop321_scan_bus, + .preinit = iq31244_preinit, + .map_irq = iq31244_map_irq +}; + +static int __init iq31244_pci_init(void) +{ + if (machine_is_iq31244()) + pci_common_init(&iq31244_pci); + return 0; +} + +subsys_initcall(iq31244_pci_init); + + + + diff --git a/arch/arm/mach-iop32x/iq80321-mm.c b/arch/arm/mach-iop32x/iq80321-mm.c new file mode 100644 index 000000000000..5f702a7ff622 --- /dev/null +++ b/arch/arm/mach-iop32x/iq80321-mm.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-iop32x/iq80321-mm.c + * + * Low level memory initialization for iq80321 platform + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80321 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ +static struct map_desc iq80321_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = IQ80321_UART, + .pfn = __phys_to_pfn(IQ80321_UART), + .length = 0x00100000, + .type = MT_DEVICE + } +}; + +void __init iq80321_map_io(void) +{ + iop321_map_io(); + + iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc)); +} diff --git a/arch/arm/mach-iop32x/iq80321-pci.c b/arch/arm/mach-iop32x/iq80321-pci.c new file mode 100644 index 000000000000..8767950e131f --- /dev/null +++ b/arch/arm/mach-iop32x/iq80321-pci.c @@ -0,0 +1,123 @@ +/* + * arch/arm/mach-iop32x/iq80321-pci.c + * + * PCI support for the Intel IQ80321 reference board + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80321_INTA +#define INTB IRQ_IQ80321_INTB +#define INTC IRQ_IQ80321_INTC +#define INTD IRQ_IQ80321_INTD + +#define INTE IRQ_IQ80321_I82544 + +static inline int __init +iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTE, INTE, INTE, INTE}, /* Gig-E */ + {-1, -1, -1, -1}, /* Unused */ + {INTC, INTD, INTA, INTB}, /* PCI-X Slot */ + {-1, -1, -1, -1}, + }; + + BUG_ON(pin < 1 || pin > 4); + +// return PCI_IRQ_TABLE_LOOKUP(4, 7); + return pci_irq_table[idsel%4][pin-1]; +} + +static int iq80321_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP321_PCI_LOWER_IO_VA; + res[0].end = IOP321_PCI_UPPER_IO_VA; + res[0].name = "IQ80321 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP321_PCI_LOWER_MEM_PA; + res[1].end = IOP321_PCI_UPPER_MEM_PA; + res[1].name = "IQ80321 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP321_PCI_MEM_OFFSET; + sys->io_offset = IOP321_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80321_preinit(void) +{ + iop321_init(); +} + +static struct hw_pci iq80321_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80321_setup, + .scan = iop321_scan_bus, + .preinit = iq80321_preinit, + .map_irq = iq80321_map_irq +}; + +static int __init iq80321_pci_init(void) +{ + if (machine_is_iq80321()) + pci_common_init(&iq80321_pci); + return 0; +} + +subsys_initcall(iq80321_pci_init); + + + + diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c new file mode 100644 index 000000000000..c5f633d2d632 --- /dev/null +++ b/arch/arm/mach-iop32x/irq.c @@ -0,0 +1,97 @@ +/* + * linux/arch/arm/mach-iop32x/irq.c + * + * Generic IOP32X IRQ handling functionality + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Added IOP3XX chipset and IQ80321 board masking code. + * + */ +#include +#include +#include + +#include +#include +#include + +#include + +static u32 iop321_mask /* = 0 */; + +static inline void intctl_write(u32 val) +{ + asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); +} + +static inline void intstr_write(u32 val) +{ + asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val)); +} + +static void +iop321_irq_mask (unsigned int irq) +{ + + iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS)); + + intctl_write(iop321_mask); +} + +static void +iop321_irq_unmask (unsigned int irq) +{ + iop321_mask |= (1 << (irq - IOP321_IRQ_OFS)); + + intctl_write(iop321_mask); +} + +struct irq_chip ext_chip = { + .name = "IOP", + .ack = iop321_irq_mask, + .mask = iop321_irq_mask, + .unmask = iop321_irq_unmask, +}; + +void __init iop321_init_irq(void) +{ + unsigned int i, tmp; + + /* Enable access to coprocessor 6 for dealing with IRQs. + * From RMK: + * Basically, the Intel documentation here is poor. It appears that + * you need to set the bit to be able to access the coprocessor from + * SVC mode. Whether that allows access from user space or not is + * unclear. + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "orr %0, %0, %1\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + /* The action is delayed, so we have to do this: */ + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4" + : "=r" (tmp) : "i" (1 << 6) ); + + intctl_write(0); // disable all interrupts + intstr_write(0); // treat all as IRQ + if(machine_is_iq80321() || + machine_is_iq31244()) // all interrupts are inputs to chip + *IOP321_PCIIRSR = 0x0f; + + for(i = IOP321_IRQ_OFS; i < NR_IRQS; i++) + { + set_irq_chip(i, &ext_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + + } +} + diff --git a/arch/arm/mach-iop32x/pci.c b/arch/arm/mach-iop32x/pci.c new file mode 100644 index 000000000000..1a7c683673f2 --- /dev/null +++ b/arch/arm/mach-iop32x/pci.c @@ -0,0 +1,220 @@ +/* + * arch/arm/mach-iop32x/pci.c + * + * PCI support for the Intel IOP321 chipset + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// #define DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +/* + * This routine builds either a type0 or type1 configuration command. If the + * bus is on the 80321 then a type0 made, else a type1 is created. + */ +static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | (where & ~3); + + return addr; +} + +/* + * This routine checks the status of the last configuration cycle. If an error + * was detected it returns a 1, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop321_pci_status(void) +{ + unsigned int status; + int ret = 0; + + /* + * Check the status registers. + */ + status = *IOP321_ATUSR; + if (status & 0xf900) + { + DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); + *IOP321_ATUSR = status & 0xf900; + ret = 1; + } + status = *IOP321_ATUISR; + if (status & 0x679f) + { + DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); + *IOP321_ATUISR = status & 0x679f; + ret = 1; + } + return ret; +} + +/* + * Simply write the address register and read the configuration + * data. Note that the 4 nop's ensure that we are able to handle + * a delayed abort (in theory.) + */ +static inline u32 iop321_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); + + return val; +} + +/* + * The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop321_cfg_address(bus, devfn, where); + u32 val = iop321_read(addr) >> ((where & 3) * 8); + + if( iop321_pci_status() ) + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop321_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop321_read(addr); + if (!iop321_pci_status() == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + *IOP321_OCCDR = val | value << where; + } else { + asm volatile( + "str %1, [%2]\n\t" + "str %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : + : "r" (value), "r" (addr), + "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop321_ops = { + .read = iop321_read_config, + .write = iop321_write_config, +}; + +/* + * When a PCI device does not exist during config cycles, the 80200 gets a + * bus error instead of returning 0xffffffff. This handler simply returns. + */ +int +iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +/* + * Scan an IOP321 PCI bus. sys->bus defines which bus we scan. + */ +struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &iop321_ops, sys); +} + +void iop321_init(void) +{ + DBG("PCI: Intel 80321 PCI init code.\n"); + DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD); + DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n", + *IOP321_OMWTVR0, + *IOP321_OIOWTVR); + DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR); + DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", + *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0); + DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0); + DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n", + *IOP321_IABAR1, *IOP321_IALR1); + DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", + *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR); + DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", + *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2); + DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", + *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3); + + hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort"); +} + diff --git a/arch/arm/mach-iop32x/setup.c b/arch/arm/mach-iop32x/setup.c new file mode 100644 index 000000000000..729678799271 --- /dev/null +++ b/arch/arm/mach-iop32x/setup.c @@ -0,0 +1,173 @@ +/* + * linux/arch/arm/mach-iop32x/setup.c + * + * Author: Nicolas Pitre + * Copyright (C) 2001 MontaVista Software, Inc. + * Copyright (C) 2004 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IOP321_UART_XTAL 1843200 + +/* + * Standard IO mapping for all IOP321 based systems + */ +static struct map_desc iop321_std_desc[] __initdata = { + { /* mem mapped registers */ + .virtual = IOP321_VIRT_MEM_BASE, + .pfn = __phys_to_pfn(IOP321_PHYS_MEM_BASE), + .length = 0x00002000, + .type = MT_DEVICE + }, { /* PCI IO space */ + .virtual = IOP321_PCI_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA), + .length = IOP321_PCI_IO_WINDOW_SIZE, + .type = MT_DEVICE + } +}; + +#ifdef CONFIG_ARCH_IQ80321 +#define UARTBASE IQ80321_UART +#define IRQ_UART IRQ_IQ80321_UART +#endif + +#ifdef CONFIG_ARCH_IQ31244 +#define UARTBASE IQ31244_UART +#define IRQ_UART IRQ_IQ31244_UART +#endif + +static struct uart_port iop321_serial_ports[] = { + { + .membase = (char*)(UARTBASE), + .mapbase = (UARTBASE), + .irq = IRQ_UART, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = IOP321_UART_XTAL, + .line = 0, + .type = PORT_16550A, + .fifosize = 16 + } +}; + +static struct resource iop32x_i2c_0_resources[] = { + [0] = { + .start = 0xfffff680, + .end = 0xfffff698, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP321_I2C_0, + .end = IRQ_IOP321_I2C_0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop32x_i2c_1_resources[] = { + [0] = { + .start = 0xfffff6a0, + .end = 0xfffff6b8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP321_I2C_1, + .end = IRQ_IOP321_I2C_1, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device iop32x_i2c_0_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop32x_i2c_0_resources +}; + +static struct platform_device iop32x_i2c_1_controller = { + .name = "IOP3xx-I2C", + .id = 1, + .num_resources = 2, + .resource = iop32x_i2c_1_resources +}; + +static struct platform_device *iop32x_devices[] __initdata = { + &iop32x_i2c_0_controller, + &iop32x_i2c_1_controller +}; + +void __init iop32x_init(void) +{ + if(iop_is_321()) + { + platform_add_devices(iop32x_devices, + ARRAY_SIZE(iop32x_devices)); + } +} + +void __init iop321_map_io(void) +{ + iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc)); + early_serial_setup(&iop321_serial_ports[0]); +} + +#ifdef CONFIG_ARCH_IQ80321 +extern void iq80321_map_io(void); +extern struct sys_timer iop321_timer; +extern void iop321_init_time(void); +#endif + +#ifdef CONFIG_ARCH_IQ31244 +extern void iq31244_map_io(void); +extern struct sys_timer iop321_timer; +extern void iop321_init_time(void); +#endif + +#if defined(CONFIG_ARCH_IQ80321) +MACHINE_START(IQ80321, "Intel IQ80321") + /* Maintainer: Intel Corporation */ + .phys_io = IQ80321_UART, + .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, + .map_io = iq80321_map_io, + .init_irq = iop321_init_irq, + .timer = &iop321_timer, + .boot_params = 0xa0000100, + .init_machine = iop32x_init, +MACHINE_END +#elif defined(CONFIG_ARCH_IQ31244) +MACHINE_START(IQ31244, "Intel IQ31244") + /* Maintainer: Intel Corp. */ + .phys_io = IQ31244_UART, + .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, + .map_io = iq31244_map_io, + .init_irq = iop321_init_irq, + .timer = &iop321_timer, + .boot_params = 0xa0000100, + .init_machine = iop32x_init, +MACHINE_END +#else +#error No machine descriptor defined for this IOP3XX implementation +#endif diff --git a/arch/arm/mach-iop32x/time.c b/arch/arm/mach-iop32x/time.c new file mode 100644 index 000000000000..3cabbbca0a02 --- /dev/null +++ b/arch/arm/mach-iop32x/time.c @@ -0,0 +1,108 @@ +/* + * arch/arm/mach-iop32x/time.c + * + * Timer code for IOP321 based systems + * + * Author: Deepak Saxena + * + * Copyright 2002-2003 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define IOP321_TIME_SYNC 0 + +static inline unsigned long get_elapsed(void) +{ + return LATCH - *IOP321_TU_TCR0; +} + +static unsigned long iop321_gettimeoffset(void) +{ + unsigned long elapsed, usec; + u32 tisr1, tisr2; + + /* + * If an interrupt was pending before we read the timer, + * we've already wrapped. Factor this into the time. + * If an interrupt was pending after we read the timer, + * it may have wrapped between checking the interrupt + * status and reading the timer. Re-read the timer to + * be sure its value is after the wrap. + */ + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); + elapsed = get_elapsed(); + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); + + if(tisr1 & 1) + elapsed += LATCH; + else if (tisr2 & 1) + elapsed = LATCH + get_elapsed(); + + /* + * Now convert them to usec. + */ + usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); + + return usec; +} + +static irqreturn_t +iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 tisr; + + write_seqlock(&xtime_lock); + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); + tisr |= 1; + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction iop321_timer_irq = { + .name = "IOP321 Timer Tick", + .handler = iop321_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER, +}; + +static void __init iop321_timer_init(void) +{ + u32 timer_ctl; + + setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq); + + timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD | + IOP321_TMR_RATIO_1_1; + + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); + + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); +} + +struct sys_timer iop321_timer = { + .init = &iop321_timer_init, + .offset = iop321_gettimeoffset, +}; diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig new file mode 100644 index 000000000000..410df546e954 --- /dev/null +++ b/arch/arm/mach-iop33x/Kconfig @@ -0,0 +1,27 @@ +if ARCH_IOP33X + +menu "IOP33x Implementation Options" + +comment "IOP33x Platform Types" + +config ARCH_IQ80331 + bool "Enable support for IQ80331" + help + Say Y here if you want to run your kernel on the Intel IQ80331 + evaluation kit for the IOP331 chipset. + +config MACH_IQ80332 + bool "Enable support for IQ80332" + help + Say Y here if you want to run your kernel on the Intel IQ80332 + evaluation kit for the IOP332 chipset. + +config IOP331_STEPD + bool "Chip stepping D of the IOP80331 processor or IOP80333" + help + Say Y here if you have StepD of the IOP80331 or IOP8033 + based platforms. + +endmenu + +endif diff --git a/arch/arm/mach-iop33x/Makefile b/arch/arm/mach-iop33x/Makefile new file mode 100644 index 000000000000..0f1a8fffe187 --- /dev/null +++ b/arch/arm/mach-iop33x/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +obj-y := common.o setup.o irq.o pci.o time.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o +obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o diff --git a/arch/arm/mach-iop33x/Makefile.boot b/arch/arm/mach-iop33x/Makefile.boot new file mode 100644 index 000000000000..67039c3e0c48 --- /dev/null +++ b/arch/arm/mach-iop33x/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-iop33x/common.c b/arch/arm/mach-iop33x/common.c new file mode 100644 index 000000000000..dd75f2b8e74f --- /dev/null +++ b/arch/arm/mach-iop33x/common.c @@ -0,0 +1,22 @@ +/* + * arch/arm/mach-iop33x/common.c + * + * Common routines shared across all IOP3xx implementations + * + * Author: Deepak Saxena + * + * Copyright 2003 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include + +/* + * Shared variables + */ +unsigned long iop3xx_pcibios_min_io = 0; +unsigned long iop3xx_pcibios_min_mem = 0; diff --git a/arch/arm/mach-iop33x/iq80331-mm.c b/arch/arm/mach-iop33x/iq80331-mm.c new file mode 100644 index 000000000000..eb59445a0fca --- /dev/null +++ b/arch/arm/mach-iop33x/iq80331-mm.c @@ -0,0 +1,35 @@ +/* + * linux/arch/arm/mach-iop33x/iq80331-mm.c + * + * Low level memory initialization for iq80331 platform + * + * Author: Dave Jiang + * Copyright (C) 2003 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80331 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ + +void __init iq80331_map_io(void) +{ + iop331_map_io(); +} diff --git a/arch/arm/mach-iop33x/iq80331-pci.c b/arch/arm/mach-iop33x/iq80331-pci.c new file mode 100644 index 000000000000..71adb12a9421 --- /dev/null +++ b/arch/arm/mach-iop33x/iq80331-pci.c @@ -0,0 +1,119 @@ +/* + * arch/arm/mach-iop33x/iq80331-pci.c + * + * PCI support for the Intel IQ80331 reference board + * + * Author: Dave Jiang + * Copyright (C) 2003, 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80331_INTA +#define INTB IRQ_IQ80331_INTB +#define INTC IRQ_IQ80331_INTC +#define INTD IRQ_IQ80331_INTD + +//#define INTE IRQ_IQ80331_I82544 + +static inline int __init +iq80331_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTB, INTC, INTD, INTA}, /* PCI-X Slot */ + {INTC, INTC, INTC, INTC}, /* GigE */ + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(1, 7); +} + +static int iq80331_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP331_PCI_LOWER_IO_VA; + res[0].end = IOP331_PCI_UPPER_IO_VA; + res[0].name = "IQ80331 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP331_PCI_LOWER_MEM_PA; + res[1].end = IOP331_PCI_UPPER_MEM_PA; + res[1].name = "IQ80331 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP331_PCI_MEM_OFFSET; + sys->io_offset = IOP331_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80331_preinit(void) +{ + iop331_init(); +} + +static struct hw_pci iq80331_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80331_setup, + .scan = iop331_scan_bus, + .preinit = iq80331_preinit, + .map_irq = iq80331_map_irq +}; + +static int __init iq80331_pci_init(void) +{ + if (machine_is_iq80331()) + pci_common_init(&iq80331_pci); + return 0; +} + +subsys_initcall(iq80331_pci_init); + + + + diff --git a/arch/arm/mach-iop33x/iq80332-mm.c b/arch/arm/mach-iop33x/iq80332-mm.c new file mode 100644 index 000000000000..f7bc73113ea8 --- /dev/null +++ b/arch/arm/mach-iop33x/iq80332-mm.c @@ -0,0 +1,35 @@ +/* + * linux/arch/arm/mach-iop33x/iq80332-mm.c + * + * Low level memory initialization for iq80332 platform + * + * Author: Dave Jiang + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80332 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ + +void __init iq80332_map_io(void) +{ + iop331_map_io(); +} diff --git a/arch/arm/mach-iop33x/iq80332-pci.c b/arch/arm/mach-iop33x/iq80332-pci.c new file mode 100644 index 000000000000..f3010f85b1a2 --- /dev/null +++ b/arch/arm/mach-iop33x/iq80332-pci.c @@ -0,0 +1,125 @@ +/* + * arch/arm/mach-iop33x/iq80332-pci.c + * + * PCI support for the Intel IQ80332 reference board + * + * Author: Dave Jiang + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80332_INTA +#define INTB IRQ_IQ80332_INTB +#define INTC IRQ_IQ80332_INTC +#define INTD IRQ_IQ80332_INTD + +//#define INTE IRQ_IQ80332_I82544 + +static inline int __init +iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][8] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + {INTA, INTB, INTC, INTD}, /* PCI-X Slot */ + {-1, -1, -1, -1}, + {INTC, INTC, INTC, INTC}, /* GigE */ + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(1, 7); +} + +static int iq80332_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP331_PCI_LOWER_IO_VA; + res[0].end = IOP331_PCI_UPPER_IO_VA; + res[0].name = "IQ80332 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP331_PCI_LOWER_MEM_PA; + res[1].end = IOP331_PCI_UPPER_MEM_PA; + res[1].name = "IQ80332 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP331_PCI_MEM_OFFSET; + sys->io_offset = IOP331_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80332_preinit(void) +{ + iop331_init(); +} + +static struct hw_pci iq80332_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80332_setup, + .scan = iop331_scan_bus, + .preinit = iq80332_preinit, + .map_irq = iq80332_map_irq +}; + +static int __init iq80332_pci_init(void) +{ + if (machine_is_iq80332()) + pci_common_init(&iq80332_pci); + return 0; +} + +subsys_initcall(iq80332_pci_init); + + + + diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c new file mode 100644 index 000000000000..029fa78876a5 --- /dev/null +++ b/arch/arm/mach-iop33x/irq.c @@ -0,0 +1,129 @@ +/* + * linux/arch/arm/mach-iop33x/irq.c + * + * Generic IOP331 IRQ handling functionality + * + * Author: Dave Jiang + * Copyright (C) 2003 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * + */ +#include +#include +#include + +#include +#include +#include + +#include + +static u32 iop331_mask0 = 0; +static u32 iop331_mask1 = 0; + +static inline void intctl_write0(u32 val) +{ + // INTCTL0 + asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); +} + +static inline void intctl_write1(u32 val) +{ + // INTCTL1 + asm volatile("mcr p6,0,%0,c1,c0,0"::"r" (val)); +} + +static inline void intstr_write0(u32 val) +{ + // INTSTR0 + asm volatile("mcr p6,0,%0,c2,c0,0"::"r" (val)); +} + +static inline void intstr_write1(u32 val) +{ + // INTSTR1 + asm volatile("mcr p6,0,%0,c3,c0,0"::"r" (val)); +} + +static void +iop331_irq_mask1 (unsigned int irq) +{ + iop331_mask0 &= ~(1 << (irq - IOP331_IRQ_OFS)); + intctl_write0(iop331_mask0); +} + +static void +iop331_irq_mask2 (unsigned int irq) +{ + iop331_mask1 &= ~(1 << (irq - IOP331_IRQ_OFS - 32)); + intctl_write1(iop331_mask1); +} + +static void +iop331_irq_unmask1(unsigned int irq) +{ + iop331_mask0 |= (1 << (irq - IOP331_IRQ_OFS)); + intctl_write0(iop331_mask0); +} + +static void +iop331_irq_unmask2(unsigned int irq) +{ + iop331_mask1 |= (1 << (irq - IOP331_IRQ_OFS - 32)); + intctl_write1(iop331_mask1); +} + +struct irq_chip iop331_irqchip1 = { + .name = "IOP-1", + .ack = iop331_irq_mask1, + .mask = iop331_irq_mask1, + .unmask = iop331_irq_unmask1, +}; + +struct irq_chip iop331_irqchip2 = { + .name = "IOP-2", + .ack = iop331_irq_mask2, + .mask = iop331_irq_mask2, + .unmask = iop331_irq_unmask2, +}; + +void __init iop331_init_irq(void) +{ + unsigned int i, tmp; + + /* Enable access to coprocessor 6 for dealing with IRQs. + * From RMK: + * Basically, the Intel documentation here is poor. It appears that + * you need to set the bit to be able to access the coprocessor from + * SVC mode. Whether that allows access from user space or not is + * unclear. + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "orr %0, %0, %1\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + /* The action is delayed, so we have to do this: */ + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4" + : "=r" (tmp) : "i" (1 << 6) ); + + intctl_write0(0); // disable all interrupts + intctl_write1(0); + intstr_write0(0); // treat all as IRQ + intstr_write1(0); + if(machine_is_iq80331()) // all interrupts are inputs to chip + *IOP331_PCIIRSR = 0x0f; + + for(i = IOP331_IRQ_OFS; i < NR_IRQS; i++) + { + set_irq_chip(i, (i < 32) ? &iop331_irqchip1 : &iop331_irqchip2); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } +} + diff --git a/arch/arm/mach-iop33x/pci.c b/arch/arm/mach-iop33x/pci.c new file mode 100644 index 000000000000..bf6aba91b47d --- /dev/null +++ b/arch/arm/mach-iop33x/pci.c @@ -0,0 +1,222 @@ +/* + * arch/arm/mach-iop33x/pci.c + * + * PCI support for the Intel IOP331 chipset + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2003, 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#undef DEBUG +#undef DEBUG1 + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +#ifdef DEBUG1 +#define DBG1(x...) printk(x) +#else +#define DBG1(x...) do { } while (0) +#endif + +/* + * This routine builds either a type0 or type1 configuration command. If the + * bus is on the 80331 then a type0 made, else a type1 is created. + */ +static u32 iop331_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | (where & ~3); + + return addr; +} + +/* + * This routine checks the status of the last configuration cycle. If an error + * was detected it returns a 1, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop331_pci_status(void) +{ + unsigned int status; + int ret = 0; + + /* + * Check the status registers. + */ + status = *IOP331_ATUSR; + if (status & 0xf900) + { + DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); + *IOP331_ATUSR = status & 0xf900; + ret = 1; + } + status = *IOP331_ATUISR; + if (status & 0x679f) + { + DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); + *IOP331_ATUISR = status & 0x679f; + ret = 1; + } + return ret; +} + +/* + * Simply write the address register and read the configuration + * data. Note that the 4 nop's ensure that we are able to handle + * a delayed abort (in theory.) + */ +static inline u32 iop331_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); + + return val; +} + +/* + * The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop331_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop331_cfg_address(bus, devfn, where); + u32 val = iop331_read(addr) >> ((where & 3) * 8); + + if( iop331_pci_status() ) + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop331_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop331_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop331_read(addr); + if (!iop331_pci_status() == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + *IOP331_OCCDR = val | value << where; + } else { + asm volatile( + "str %1, [%2]\n\t" + "str %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : + : "r" (value), "r" (addr), + "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop331_ops = { + .read = iop331_read_config, + .write = iop331_write_config, +}; + +/* + * When a PCI device does not exist during config cycles, the XScale gets a + * bus error instead of returning 0xffffffff. This handler simply returns. + */ +int +iop331_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +/* + * Scan an IOP331 PCI bus. sys->bus defines which bus we scan. + */ +struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &iop331_ops, sys); +} + +void iop331_init(void) +{ + DBG1("PCI: Intel 80331 PCI init code.\n"); + DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD); + DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n", + *IOP331_OMWTVR0, + *IOP331_OIOWTVR); + DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1); + DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR); + DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0); + DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1); + DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR); + DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2); + DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3); + + hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort"); +} + diff --git a/arch/arm/mach-iop33x/setup.c b/arch/arm/mach-iop33x/setup.c new file mode 100644 index 000000000000..c14c7da5ec4c --- /dev/null +++ b/arch/arm/mach-iop33x/setup.c @@ -0,0 +1,221 @@ +/* + * linux/arch/arm/mach-iop33x/setup.c + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2004 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IOP331_UART_XTAL 33334000 + +/* + * Standard IO mapping for all IOP331 based systems + */ +static struct map_desc iop331_std_desc[] __initdata = { + { /* mem mapped registers */ + .virtual = IOP331_VIRT_MEM_BASE, + .pfn = __phys_to_pfn(IOP331_PHYS_MEM_BASE), + .length = 0x00002000, + .type = MT_DEVICE + }, { /* PCI IO space */ + .virtual = IOP331_PCI_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA), + .length = IOP331_PCI_IO_WINDOW_SIZE, + .type = MT_DEVICE + } +}; + +static struct resource iop33x_uart0_resources[] = { + [0] = { + .start = IOP331_UART0_PHYS, + .end = IOP331_UART0_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_UART0, + .end = IRQ_IOP331_UART0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop33x_uart1_resources[] = { + [0] = { + .start = IOP331_UART1_PHYS, + .end = IOP331_UART1_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_UART1, + .end = IRQ_IOP331_UART1, + .flags = IORESOURCE_IRQ + } +}; + +static struct plat_serial8250_port iop33x_uart0_data[] = { + { + .membase = (char*)(IOP331_UART0_VIRT), + .mapbase = (IOP331_UART0_PHYS), + .irq = IRQ_IOP331_UART0, + .uartclk = IOP331_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct plat_serial8250_port iop33x_uart1_data[] = { + { + .membase = (char*)(IOP331_UART1_VIRT), + .mapbase = (IOP331_UART1_PHYS), + .irq = IRQ_IOP331_UART1, + .uartclk = IOP331_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device iop33x_uart0 = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev.platform_data = iop33x_uart0_data, + .num_resources = 2, + .resource = iop33x_uart0_resources, +}; + +static struct platform_device iop33x_uart1 = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM1, + .dev.platform_data = iop33x_uart1_data, + .num_resources = 2, + .resource = iop33x_uart1_resources, +}; + +static struct resource iop33x_i2c_0_resources[] = { + [0] = { + .start = 0xfffff680, + .end = 0xfffff698, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_I2C_0, + .end = IRQ_IOP331_I2C_0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop33x_i2c_1_resources[] = { + [0] = { + .start = 0xfffff6a0, + .end = 0xfffff6b8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_I2C_1, + .end = IRQ_IOP331_I2C_1, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device iop33x_i2c_0_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop33x_i2c_0_resources +}; + +static struct platform_device iop33x_i2c_1_controller = { + .name = "IOP3xx-I2C", + .id = 1, + .num_resources = 2, + .resource = iop33x_i2c_1_resources +}; + +static struct platform_device *iop33x_devices[] __initdata = { + &iop33x_uart0, + &iop33x_uart1, + &iop33x_i2c_0_controller, + &iop33x_i2c_1_controller +}; + +void __init iop33x_init(void) +{ + if(iop_is_331()) + { + platform_add_devices(iop33x_devices, + ARRAY_SIZE(iop33x_devices)); + } +} + +void __init iop331_map_io(void) +{ + iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc)); +} + +#ifdef CONFIG_ARCH_IOP33X +extern void iop331_init_irq(void); +extern struct sys_timer iop331_timer; +#endif + +#ifdef CONFIG_ARCH_IQ80331 +extern void iq80331_map_io(void); +#endif + +#ifdef CONFIG_MACH_IQ80332 +extern void iq80332_map_io(void); +#endif + +#if defined(CONFIG_ARCH_IQ80331) +MACHINE_START(IQ80331, "Intel IQ80331") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80331_map_io, + .init_irq = iop331_init_irq, + .timer = &iop331_timer, + .boot_params = 0x0100, + .init_machine = iop33x_init, +MACHINE_END + +#elif defined(CONFIG_MACH_IQ80332) +MACHINE_START(IQ80332, "Intel IQ80332") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80332_map_io, + .init_irq = iop331_init_irq, + .timer = &iop331_timer, + .boot_params = 0x0100, + .init_machine = iop33x_init, +MACHINE_END + +#else +#error No machine descriptor defined for this IOP3XX implementation +#endif + + diff --git a/arch/arm/mach-iop33x/time.c b/arch/arm/mach-iop33x/time.c new file mode 100644 index 000000000000..d839cd0d926e --- /dev/null +++ b/arch/arm/mach-iop33x/time.c @@ -0,0 +1,106 @@ +/* + * arch/arm/mach-iop33x/time.c + * + * Timer code for IOP331 based systems + * + * Author: Dave Jiang + * + * Copyright 2003 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static inline unsigned long get_elapsed(void) +{ + return LATCH - *IOP331_TU_TCR0; +} + +static unsigned long iop331_gettimeoffset(void) +{ + unsigned long elapsed, usec; + u32 tisr1, tisr2; + + /* + * If an interrupt was pending before we read the timer, + * we've already wrapped. Factor this into the time. + * If an interrupt was pending after we read the timer, + * it may have wrapped between checking the interrupt + * status and reading the timer. Re-read the timer to + * be sure its value is after the wrap. + */ + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); + elapsed = get_elapsed(); + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); + + if(tisr1 & 1) + elapsed += LATCH; + else if (tisr2 & 1) + elapsed = LATCH + get_elapsed(); + + /* + * Now convert them to usec. + */ + usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); + + return usec; +} + +static irqreturn_t +iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 tisr; + + write_seqlock(&xtime_lock); + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); + tisr |= 1; + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction iop331_timer_irq = { + .name = "IOP331 Timer Tick", + .handler = iop331_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER, +}; + +static void __init iop331_timer_init(void) +{ + u32 timer_ctl; + + setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq); + + timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD | + IOP331_TMR_RATIO_1_1; + + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); + + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); + +} + +struct sys_timer iop331_timer = { + .init = iop331_timer_init, + .offset = iop331_gettimeoffset, +}; diff --git a/arch/arm/mach-iop3xx/Kconfig b/arch/arm/mach-iop3xx/Kconfig deleted file mode 100644 index 887c3753727f..000000000000 --- a/arch/arm/mach-iop3xx/Kconfig +++ /dev/null @@ -1,66 +0,0 @@ -if ARCH_IOP3XX - -menu "IOP3xx Implementation Options" - -comment "IOP3xx Platform Types" - -config ARCH_IQ80321 - bool "Enable support for IQ80321" - select ARCH_IOP32X - help - Say Y here if you want to run your kernel on the Intel IQ80321 - evaluation kit for the IOP321 chipset. - -config ARCH_IQ31244 - bool "Enable support for IQ31244" - select ARCH_IOP32X - help - Say Y here if you want to run your kernel on the Intel IQ31244 - evaluation kit for the IOP321 chipset. - -config ARCH_IQ80331 - bool "Enable support for IQ80331" - select ARCH_IOP33X - help - Say Y here if you want to run your kernel on the Intel IQ80331 - evaluation kit for the IOP331 chipset. - -config MACH_IQ80332 - bool "Enable support for IQ80332" - select ARCH_IOP33X - help - Say Y here if you want to run your kernel on the Intel IQ80332 - evaluation kit for the IOP332 chipset. - -config ARCH_EP80219 - bool "Enable support for EP80219" - select ARCH_IOP32X - select ARCH_IQ31244 - help - Say Y here if you want to run your kernel on the Intel EP80219 - evaluation kit for the Intel 80219 chipset (a IOP321 variant). - -# Which IOP variant are we running? -config ARCH_IOP32X - bool - help - The IQ80321 uses the IOP321 variant. - The IQ31244 and EP80219 uses the IOP321 variant. - -config ARCH_IOP33X - bool - default ARCH_IQ80331 - help - The IQ80331, IQ80332, and IQ80333 uses the IOP331 variant. - -comment "IOP3xx Chipset Features" - -config IOP331_STEPD - bool "Chip stepping D of the IOP80331 processor or IOP80333" - depends on ARCH_IOP33X - help - Say Y here if you have StepD of the IOP80331 or IOP8033 - based platforms. - -endmenu -endif diff --git a/arch/arm/mach-iop3xx/Makefile b/arch/arm/mach-iop3xx/Makefile deleted file mode 100644 index ad3051524480..000000000000 --- a/arch/arm/mach-iop3xx/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := common.o - -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_ARCH_IOP32X) += iop321-setup.o iop321-irq.o iop321-pci.o iop321-time.o - -obj-$(CONFIG_ARCH_IOP33X) += iop331-setup.o iop331-irq.o iop331-pci.o iop331-time.o - -obj-$(CONFIG_ARCH_IQ80321) += iq80321-mm.o iq80321-pci.o - -obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o - -obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o - -obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o diff --git a/arch/arm/mach-iop3xx/Makefile.boot b/arch/arm/mach-iop3xx/Makefile.boot deleted file mode 100644 index e120c233b706..000000000000 --- a/arch/arm/mach-iop3xx/Makefile.boot +++ /dev/null @@ -1,9 +0,0 @@ - zreladdr-y := 0xa0008000 -params_phys-y := 0xa0000100 -initrd_phys-y := 0xa0800000 -ifeq ($(CONFIG_ARCH_IOP33X),y) - zreladdr-y := 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 -endif - diff --git a/arch/arm/mach-iop3xx/common.c b/arch/arm/mach-iop3xx/common.c deleted file mode 100644 index d7f50e57e753..000000000000 --- a/arch/arm/mach-iop3xx/common.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * arch/arm/mach-iop3xx/common.c - * - * Common routines shared across all IOP3xx implementations - * - * Author: Deepak Saxena - * - * Copyright 2003 (c) MontaVista, Software, Inc. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include - -/* - * Shared variables - */ -unsigned long iop3xx_pcibios_min_io = 0; -unsigned long iop3xx_pcibios_min_mem = 0; - -#ifdef CONFIG_ARCH_EP80219 -#include -/* - * Default power-off for EP80219 - */ - -static inline void ep80219_send_to_pic(__u8 c) { -} - -void ep80219_power_off(void) -{ - /* - * This function will send a SHUTDOWN_COMPLETE message to the PIC controller - * over I2C. We are not using the i2c subsystem since we are going to power - * off and it may be removed - */ - - /* Send the Address byte w/ the start condition */ - *IOP321_IDBR1 = 0x60; - *IOP321_ICR1 = 0xE9; - mdelay(1); - - /* Send the START_MSG byte w/ no start or stop condition */ - *IOP321_IDBR1 = 0x0F; - *IOP321_ICR1 = 0xE8; - mdelay(1); - - /* Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or stop condition */ - *IOP321_IDBR1 = 0x03; - *IOP321_ICR1 = 0xE8; - mdelay(1); - - /* Send an ignored byte w/ stop condition */ - *IOP321_IDBR1 = 0x00; - *IOP321_ICR1 = 0xEA; - - while (1) ; -} - -#include -#include - -static int __init ep80219_init(void) -{ - pm_power_off = ep80219_power_off; - return 0; -} -arch_initcall(ep80219_init); -#endif diff --git a/arch/arm/mach-iop3xx/iop321-irq.c b/arch/arm/mach-iop3xx/iop321-irq.c deleted file mode 100644 index 88ac333472c8..000000000000 --- a/arch/arm/mach-iop3xx/iop321-irq.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop321-irq.c - * - * Generic IOP321 IRQ handling functionality - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Added IOP3XX chipset and IQ80321 board masking code. - * - */ -#include -#include -#include - -#include -#include -#include - -#include - -static u32 iop321_mask /* = 0 */; - -static inline void intctl_write(u32 val) -{ - asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); -} - -static inline void intstr_write(u32 val) -{ - asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val)); -} - -static void -iop321_irq_mask (unsigned int irq) -{ - - iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS)); - - intctl_write(iop321_mask); -} - -static void -iop321_irq_unmask (unsigned int irq) -{ - iop321_mask |= (1 << (irq - IOP321_IRQ_OFS)); - - intctl_write(iop321_mask); -} - -struct irq_chip ext_chip = { - .name = "IOP", - .ack = iop321_irq_mask, - .mask = iop321_irq_mask, - .unmask = iop321_irq_unmask, -}; - -void __init iop321_init_irq(void) -{ - unsigned int i, tmp; - - /* Enable access to coprocessor 6 for dealing with IRQs. - * From RMK: - * Basically, the Intel documentation here is poor. It appears that - * you need to set the bit to be able to access the coprocessor from - * SVC mode. Whether that allows access from user space or not is - * unclear. - */ - asm volatile ( - "mrc p15, 0, %0, c15, c1, 0\n\t" - "orr %0, %0, %1\n\t" - "mcr p15, 0, %0, c15, c1, 0\n\t" - /* The action is delayed, so we have to do this: */ - "mrc p15, 0, %0, c15, c1, 0\n\t" - "mov %0, %0\n\t" - "sub pc, pc, #4" - : "=r" (tmp) : "i" (1 << 6) ); - - intctl_write(0); // disable all interrupts - intstr_write(0); // treat all as IRQ - if(machine_is_iq80321() || - machine_is_iq31244()) // all interrupts are inputs to chip - *IOP321_PCIIRSR = 0x0f; - - for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++) - { - set_irq_chip(i, &ext_chip); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - - } -} - diff --git a/arch/arm/mach-iop3xx/iop321-pci.c b/arch/arm/mach-iop3xx/iop321-pci.c deleted file mode 100644 index 8ba6a0e23134..000000000000 --- a/arch/arm/mach-iop3xx/iop321-pci.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop321-pci.c - * - * PCI support for the Intel IOP321 chipset - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -// #define DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif - -/* - * This routine builds either a type0 or type1 configuration command. If the - * bus is on the 80321 then a type0 made, else a type1 is created. - */ -static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where) -{ - struct pci_sys_data *sys = bus->sysdata; - u32 addr; - - if (sys->busnr == bus->number) - addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); - else - addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; - - addr |= PCI_FUNC(devfn) << 8 | (where & ~3); - - return addr; -} - -/* - * This routine checks the status of the last configuration cycle. If an error - * was detected it returns a 1, else it returns a 0. The errors being checked - * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during - * the discovery stage. - */ -static int iop321_pci_status(void) -{ - unsigned int status; - int ret = 0; - - /* - * Check the status registers. - */ - status = *IOP321_ATUSR; - if (status & 0xf900) - { - DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); - *IOP321_ATUSR = status & 0xf900; - ret = 1; - } - status = *IOP321_ATUISR; - if (status & 0x679f) - { - DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); - *IOP321_ATUISR = status & 0x679f; - ret = 1; - } - return ret; -} - -/* - * Simply write the address register and read the configuration - * data. Note that the 4 nop's ensure that we are able to handle - * a delayed abort (in theory.) - */ -static inline u32 iop321_read(unsigned long addr) -{ - u32 val; - - __asm__ __volatile__( - "str %1, [%2]\n\t" - "ldr %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : "=r" (val) - : "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); - - return val; -} - -/* - * The read routines must check the error status of the last configuration - * cycle. If there was an error, the routine returns all hex f's. - */ -static int -iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *value) -{ - unsigned long addr = iop321_cfg_address(bus, devfn, where); - u32 val = iop321_read(addr) >> ((where & 3) * 8); - - if( iop321_pci_status() ) - val = 0xffffffff; - - *value = val; - - return PCIBIOS_SUCCESSFUL; -} - -static int -iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 value) -{ - unsigned long addr = iop321_cfg_address(bus, devfn, where); - u32 val; - - if (size != 4) { - val = iop321_read(addr); - if (!iop321_pci_status() == 0) - return PCIBIOS_SUCCESSFUL; - - where = (where & 3) * 8; - - if (size == 1) - val &= ~(0xff << where); - else - val &= ~(0xffff << where); - - *IOP321_OCCDR = val | value << where; - } else { - asm volatile( - "str %1, [%2]\n\t" - "str %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : - : "r" (value), "r" (addr), - "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); - } - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops iop321_ops = { - .read = iop321_read_config, - .write = iop321_write_config, -}; - -/* - * When a PCI device does not exist during config cycles, the 80200 gets a - * bus error instead of returning 0xffffffff. This handler simply returns. - */ -int -iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -{ - DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", - addr, fsr, regs->ARM_pc, regs->ARM_lr); - - /* - * If it was an imprecise abort, then we need to correct the - * return address to be _after_ the instruction. - */ - if (fsr & (1 << 10)) - regs->ARM_pc += 4; - - return 0; -} - -/* - * Scan an IOP321 PCI bus. sys->bus defines which bus we scan. - */ -struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_bus(sys->busnr, &iop321_ops, sys); -} - -void iop321_init(void) -{ - DBG("PCI: Intel 80321 PCI init code.\n"); - DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD); - DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n", - *IOP321_OMWTVR0, - *IOP321_OIOWTVR); - DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR); - DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", - *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0); - DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0); - DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n", - *IOP321_IABAR1, *IOP321_IALR1); - DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", - *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR); - DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", - *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2); - DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", - *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3); - - hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort"); -} - diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c deleted file mode 100644 index b6d096903c4a..000000000000 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop321-setup.c - * - * Author: Nicolas Pitre - * Copyright (C) 2001 MontaVista Software, Inc. - * Copyright (C) 2004 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IOP321_UART_XTAL 1843200 - -/* - * Standard IO mapping for all IOP321 based systems - */ -static struct map_desc iop321_std_desc[] __initdata = { - { /* mem mapped registers */ - .virtual = IOP321_VIRT_MEM_BASE, - .pfn = __phys_to_pfn(IOP321_PHYS_MEM_BASE), - .length = 0x00002000, - .type = MT_DEVICE - }, { /* PCI IO space */ - .virtual = IOP321_PCI_LOWER_IO_VA, - .pfn = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA), - .length = IOP321_PCI_IO_WINDOW_SIZE, - .type = MT_DEVICE - } -}; - -#ifdef CONFIG_ARCH_IQ80321 -#define UARTBASE IQ80321_UART -#define IRQ_UART IRQ_IQ80321_UART -#endif - -#ifdef CONFIG_ARCH_IQ31244 -#define UARTBASE IQ31244_UART -#define IRQ_UART IRQ_IQ31244_UART -#endif - -static struct uart_port iop321_serial_ports[] = { - { - .membase = (char*)(UARTBASE), - .mapbase = (UARTBASE), - .irq = IRQ_UART, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 0, - .uartclk = IOP321_UART_XTAL, - .line = 0, - .type = PORT_16550A, - .fifosize = 16 - } -}; - -static struct resource iop32x_i2c_0_resources[] = { - [0] = { - .start = 0xfffff680, - .end = 0xfffff698, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP321_I2C_0, - .end = IRQ_IOP321_I2C_0, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop32x_i2c_1_resources[] = { - [0] = { - .start = 0xfffff6a0, - .end = 0xfffff6b8, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP321_I2C_1, - .end = IRQ_IOP321_I2C_1, - .flags = IORESOURCE_IRQ - } -}; - -static struct platform_device iop32x_i2c_0_controller = { - .name = "IOP3xx-I2C", - .id = 0, - .num_resources = 2, - .resource = iop32x_i2c_0_resources -}; - -static struct platform_device iop32x_i2c_1_controller = { - .name = "IOP3xx-I2C", - .id = 1, - .num_resources = 2, - .resource = iop32x_i2c_1_resources -}; - -static struct platform_device *iop32x_devices[] __initdata = { - &iop32x_i2c_0_controller, - &iop32x_i2c_1_controller -}; - -void __init iop32x_init(void) -{ - if(iop_is_321()) - { - platform_add_devices(iop32x_devices, - ARRAY_SIZE(iop32x_devices)); - } -} - -void __init iop321_map_io(void) -{ - iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc)); - early_serial_setup(&iop321_serial_ports[0]); -} - -#ifdef CONFIG_ARCH_IQ80321 -extern void iq80321_map_io(void); -extern struct sys_timer iop321_timer; -extern void iop321_init_time(void); -#endif - -#ifdef CONFIG_ARCH_IQ31244 -extern void iq31244_map_io(void); -extern struct sys_timer iop321_timer; -extern void iop321_init_time(void); -#endif - -#if defined(CONFIG_ARCH_IQ80321) -MACHINE_START(IQ80321, "Intel IQ80321") - /* Maintainer: Intel Corporation */ - .phys_io = IQ80321_UART, - .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, - .map_io = iq80321_map_io, - .init_irq = iop321_init_irq, - .timer = &iop321_timer, - .boot_params = 0xa0000100, - .init_machine = iop32x_init, -MACHINE_END -#elif defined(CONFIG_ARCH_IQ31244) -MACHINE_START(IQ31244, "Intel IQ31244") - /* Maintainer: Intel Corp. */ - .phys_io = IQ31244_UART, - .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, - .map_io = iq31244_map_io, - .init_irq = iop321_init_irq, - .timer = &iop321_timer, - .boot_params = 0xa0000100, - .init_machine = iop32x_init, -MACHINE_END -#else -#error No machine descriptor defined for this IOP3XX implementation -#endif diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c deleted file mode 100644 index 04b1a6f7ebae..000000000000 --- a/arch/arm/mach-iop3xx/iop321-time.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop321-time.c - * - * Timer code for IOP321 based systems - * - * Author: Deepak Saxena - * - * Copyright 2002-2003 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define IOP321_TIME_SYNC 0 - -static inline unsigned long get_elapsed(void) -{ - return LATCH - *IOP321_TU_TCR0; -} - -static unsigned long iop321_gettimeoffset(void) -{ - unsigned long elapsed, usec; - u32 tisr1, tisr2; - - /* - * If an interrupt was pending before we read the timer, - * we've already wrapped. Factor this into the time. - * If an interrupt was pending after we read the timer, - * it may have wrapped between checking the interrupt - * status and reading the timer. Re-read the timer to - * be sure its value is after the wrap. - */ - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); - elapsed = get_elapsed(); - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); - - if(tisr1 & 1) - elapsed += LATCH; - else if (tisr2 & 1) - elapsed = LATCH + get_elapsed(); - - /* - * Now convert them to usec. - */ - usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); - - return usec; -} - -static irqreturn_t -iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - u32 tisr; - - write_seqlock(&xtime_lock); - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); - tisr |= 1; - asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); - - timer_tick(regs); - - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction iop321_timer_irq = { - .name = "IOP321 Timer Tick", - .handler = iop321_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static void __init iop321_timer_init(void) -{ - u32 timer_ctl; - - setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq); - - timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD | - IOP321_TMR_RATIO_1_1; - - asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); - - asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); -} - -struct sys_timer iop321_timer = { - .init = &iop321_timer_init, - .offset = iop321_gettimeoffset, -}; diff --git a/arch/arm/mach-iop3xx/iop331-irq.c b/arch/arm/mach-iop3xx/iop331-irq.c deleted file mode 100644 index cab11722ced2..000000000000 --- a/arch/arm/mach-iop3xx/iop331-irq.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop331-irq.c - * - * Generic IOP331 IRQ handling functionality - * - * Author: Dave Jiang - * Copyright (C) 2003 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * - */ -#include -#include -#include - -#include -#include -#include - -#include - -static u32 iop331_mask0 = 0; -static u32 iop331_mask1 = 0; - -static inline void intctl_write0(u32 val) -{ - // INTCTL0 - asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); -} - -static inline void intctl_write1(u32 val) -{ - // INTCTL1 - asm volatile("mcr p6,0,%0,c1,c0,0"::"r" (val)); -} - -static inline void intstr_write0(u32 val) -{ - // INTSTR0 - asm volatile("mcr p6,0,%0,c2,c0,0"::"r" (val)); -} - -static inline void intstr_write1(u32 val) -{ - // INTSTR1 - asm volatile("mcr p6,0,%0,c3,c0,0"::"r" (val)); -} - -static void -iop331_irq_mask1 (unsigned int irq) -{ - iop331_mask0 &= ~(1 << (irq - IOP331_IRQ_OFS)); - intctl_write0(iop331_mask0); -} - -static void -iop331_irq_mask2 (unsigned int irq) -{ - iop331_mask1 &= ~(1 << (irq - IOP331_IRQ_OFS - 32)); - intctl_write1(iop331_mask1); -} - -static void -iop331_irq_unmask1(unsigned int irq) -{ - iop331_mask0 |= (1 << (irq - IOP331_IRQ_OFS)); - intctl_write0(iop331_mask0); -} - -static void -iop331_irq_unmask2(unsigned int irq) -{ - iop331_mask1 |= (1 << (irq - IOP331_IRQ_OFS - 32)); - intctl_write1(iop331_mask1); -} - -struct irq_chip iop331_irqchip1 = { - .name = "IOP-1", - .ack = iop331_irq_mask1, - .mask = iop331_irq_mask1, - .unmask = iop331_irq_unmask1, -}; - -struct irq_chip iop331_irqchip2 = { - .name = "IOP-2", - .ack = iop331_irq_mask2, - .mask = iop331_irq_mask2, - .unmask = iop331_irq_unmask2, -}; - -void __init iop331_init_irq(void) -{ - unsigned int i, tmp; - - /* Enable access to coprocessor 6 for dealing with IRQs. - * From RMK: - * Basically, the Intel documentation here is poor. It appears that - * you need to set the bit to be able to access the coprocessor from - * SVC mode. Whether that allows access from user space or not is - * unclear. - */ - asm volatile ( - "mrc p15, 0, %0, c15, c1, 0\n\t" - "orr %0, %0, %1\n\t" - "mcr p15, 0, %0, c15, c1, 0\n\t" - /* The action is delayed, so we have to do this: */ - "mrc p15, 0, %0, c15, c1, 0\n\t" - "mov %0, %0\n\t" - "sub pc, pc, #4" - : "=r" (tmp) : "i" (1 << 6) ); - - intctl_write0(0); // disable all interrupts - intctl_write1(0); - intstr_write0(0); // treat all as IRQ - intstr_write1(0); - if(machine_is_iq80331()) // all interrupts are inputs to chip - *IOP331_PCIIRSR = 0x0f; - - for(i = IOP331_IRQ_OFS; i < NR_IOP331_IRQS; i++) - { - set_irq_chip(i, (i < 32) ? &iop331_irqchip1 : &iop331_irqchip2); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } -} - diff --git a/arch/arm/mach-iop3xx/iop331-pci.c b/arch/arm/mach-iop3xx/iop331-pci.c deleted file mode 100644 index 44dd213b48a3..000000000000 --- a/arch/arm/mach-iop3xx/iop331-pci.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop331-pci.c - * - * PCI support for the Intel IOP331 chipset - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright (C) 2003, 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#undef DEBUG -#undef DEBUG1 - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif - -#ifdef DEBUG1 -#define DBG1(x...) printk(x) -#else -#define DBG1(x...) do { } while (0) -#endif - -/* - * This routine builds either a type0 or type1 configuration command. If the - * bus is on the 80331 then a type0 made, else a type1 is created. - */ -static u32 iop331_cfg_address(struct pci_bus *bus, int devfn, int where) -{ - struct pci_sys_data *sys = bus->sysdata; - u32 addr; - - if (sys->busnr == bus->number) - addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); - else - addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; - - addr |= PCI_FUNC(devfn) << 8 | (where & ~3); - - return addr; -} - -/* - * This routine checks the status of the last configuration cycle. If an error - * was detected it returns a 1, else it returns a 0. The errors being checked - * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during - * the discovery stage. - */ -static int iop331_pci_status(void) -{ - unsigned int status; - int ret = 0; - - /* - * Check the status registers. - */ - status = *IOP331_ATUSR; - if (status & 0xf900) - { - DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); - *IOP331_ATUSR = status & 0xf900; - ret = 1; - } - status = *IOP331_ATUISR; - if (status & 0x679f) - { - DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); - *IOP331_ATUISR = status & 0x679f; - ret = 1; - } - return ret; -} - -/* - * Simply write the address register and read the configuration - * data. Note that the 4 nop's ensure that we are able to handle - * a delayed abort (in theory.) - */ -static inline u32 iop331_read(unsigned long addr) -{ - u32 val; - - __asm__ __volatile__( - "str %1, [%2]\n\t" - "ldr %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : "=r" (val) - : "r" (addr), "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); - - return val; -} - -/* - * The read routines must check the error status of the last configuration - * cycle. If there was an error, the routine returns all hex f's. - */ -static int -iop331_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *value) -{ - unsigned long addr = iop331_cfg_address(bus, devfn, where); - u32 val = iop331_read(addr) >> ((where & 3) * 8); - - if( iop331_pci_status() ) - val = 0xffffffff; - - *value = val; - - return PCIBIOS_SUCCESSFUL; -} - -static int -iop331_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 value) -{ - unsigned long addr = iop331_cfg_address(bus, devfn, where); - u32 val; - - if (size != 4) { - val = iop331_read(addr); - if (!iop331_pci_status() == 0) - return PCIBIOS_SUCCESSFUL; - - where = (where & 3) * 8; - - if (size == 1) - val &= ~(0xff << where); - else - val &= ~(0xffff << where); - - *IOP331_OCCDR = val | value << where; - } else { - asm volatile( - "str %1, [%2]\n\t" - "str %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : - : "r" (value), "r" (addr), - "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); - } - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops iop331_ops = { - .read = iop331_read_config, - .write = iop331_write_config, -}; - -/* - * When a PCI device does not exist during config cycles, the XScale gets a - * bus error instead of returning 0xffffffff. This handler simply returns. - */ -int -iop331_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -{ - DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", - addr, fsr, regs->ARM_pc, regs->ARM_lr); - - /* - * If it was an imprecise abort, then we need to correct the - * return address to be _after_ the instruction. - */ - if (fsr & (1 << 10)) - regs->ARM_pc += 4; - - return 0; -} - -/* - * Scan an IOP331 PCI bus. sys->bus defines which bus we scan. - */ -struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_bus(sys->busnr, &iop331_ops, sys); -} - -void iop331_init(void) -{ - DBG1("PCI: Intel 80331 PCI init code.\n"); - DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD); - DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n", - *IOP331_OMWTVR0, - *IOP331_OIOWTVR); - DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1); - DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR); - DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0); - DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1); - DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR); - DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2); - DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3); - - hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort"); -} - diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c deleted file mode 100644 index b2f24931d143..000000000000 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop331-setup.c - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright (C) 2004 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IOP331_UART_XTAL 33334000 - -/* - * Standard IO mapping for all IOP331 based systems - */ -static struct map_desc iop331_std_desc[] __initdata = { - { /* mem mapped registers */ - .virtual = IOP331_VIRT_MEM_BASE, - .pfn = __phys_to_pfn(IOP331_PHYS_MEM_BASE), - .length = 0x00002000, - .type = MT_DEVICE - }, { /* PCI IO space */ - .virtual = IOP331_PCI_LOWER_IO_VA, - .pfn = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA), - .length = IOP331_PCI_IO_WINDOW_SIZE, - .type = MT_DEVICE - } -}; - -static struct resource iop33x_uart0_resources[] = { - [0] = { - .start = IOP331_UART0_PHYS, - .end = IOP331_UART0_PHYS + 0x3f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_UART0, - .end = IRQ_IOP331_UART0, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop33x_uart1_resources[] = { - [0] = { - .start = IOP331_UART1_PHYS, - .end = IOP331_UART1_PHYS + 0x3f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_UART1, - .end = IRQ_IOP331_UART1, - .flags = IORESOURCE_IRQ - } -}; - -static struct plat_serial8250_port iop33x_uart0_data[] = { - { - .membase = (char*)(IOP331_UART0_VIRT), - .mapbase = (IOP331_UART0_PHYS), - .irq = IRQ_IOP331_UART0, - .uartclk = IOP331_UART_XTAL, - .regshift = 2, - .iotype = UPIO_MEM, - .flags = UPF_SKIP_TEST, - }, - { }, -}; - -static struct plat_serial8250_port iop33x_uart1_data[] = { - { - .membase = (char*)(IOP331_UART1_VIRT), - .mapbase = (IOP331_UART1_PHYS), - .irq = IRQ_IOP331_UART1, - .uartclk = IOP331_UART_XTAL, - .regshift = 2, - .iotype = UPIO_MEM, - .flags = UPF_SKIP_TEST, - }, - { }, -}; - -static struct platform_device iop33x_uart0 = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev.platform_data = iop33x_uart0_data, - .num_resources = 2, - .resource = iop33x_uart0_resources, -}; - -static struct platform_device iop33x_uart1 = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM1, - .dev.platform_data = iop33x_uart1_data, - .num_resources = 2, - .resource = iop33x_uart1_resources, -}; - -static struct resource iop33x_i2c_0_resources[] = { - [0] = { - .start = 0xfffff680, - .end = 0xfffff698, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_I2C_0, - .end = IRQ_IOP331_I2C_0, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop33x_i2c_1_resources[] = { - [0] = { - .start = 0xfffff6a0, - .end = 0xfffff6b8, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_I2C_1, - .end = IRQ_IOP331_I2C_1, - .flags = IORESOURCE_IRQ - } -}; - -static struct platform_device iop33x_i2c_0_controller = { - .name = "IOP3xx-I2C", - .id = 0, - .num_resources = 2, - .resource = iop33x_i2c_0_resources -}; - -static struct platform_device iop33x_i2c_1_controller = { - .name = "IOP3xx-I2C", - .id = 1, - .num_resources = 2, - .resource = iop33x_i2c_1_resources -}; - -static struct platform_device *iop33x_devices[] __initdata = { - &iop33x_uart0, - &iop33x_uart1, - &iop33x_i2c_0_controller, - &iop33x_i2c_1_controller -}; - -void __init iop33x_init(void) -{ - if(iop_is_331()) - { - platform_add_devices(iop33x_devices, - ARRAY_SIZE(iop33x_devices)); - } -} - -void __init iop331_map_io(void) -{ - iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc)); -} - -#ifdef CONFIG_ARCH_IOP33X -extern void iop331_init_irq(void); -extern struct sys_timer iop331_timer; -#endif - -#ifdef CONFIG_ARCH_IQ80331 -extern void iq80331_map_io(void); -#endif - -#ifdef CONFIG_MACH_IQ80332 -extern void iq80332_map_io(void); -#endif - -#if defined(CONFIG_ARCH_IQ80331) -MACHINE_START(IQ80331, "Intel IQ80331") - /* Maintainer: Intel Corp. */ - .phys_io = 0xfefff000, - .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical - .map_io = iq80331_map_io, - .init_irq = iop331_init_irq, - .timer = &iop331_timer, - .boot_params = 0x0100, - .init_machine = iop33x_init, -MACHINE_END - -#elif defined(CONFIG_MACH_IQ80332) -MACHINE_START(IQ80332, "Intel IQ80332") - /* Maintainer: Intel Corp. */ - .phys_io = 0xfefff000, - .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical - .map_io = iq80332_map_io, - .init_irq = iop331_init_irq, - .timer = &iop331_timer, - .boot_params = 0x0100, - .init_machine = iop33x_init, -MACHINE_END - -#else -#error No machine descriptor defined for this IOP3XX implementation -#endif - - diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c deleted file mode 100644 index 0c09e74c5740..000000000000 --- a/arch/arm/mach-iop3xx/iop331-time.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop331-time.c - * - * Timer code for IOP331 based systems - * - * Author: Dave Jiang - * - * Copyright 2003 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static inline unsigned long get_elapsed(void) -{ - return LATCH - *IOP331_TU_TCR0; -} - -static unsigned long iop331_gettimeoffset(void) -{ - unsigned long elapsed, usec; - u32 tisr1, tisr2; - - /* - * If an interrupt was pending before we read the timer, - * we've already wrapped. Factor this into the time. - * If an interrupt was pending after we read the timer, - * it may have wrapped between checking the interrupt - * status and reading the timer. Re-read the timer to - * be sure its value is after the wrap. - */ - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); - elapsed = get_elapsed(); - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); - - if(tisr1 & 1) - elapsed += LATCH; - else if (tisr2 & 1) - elapsed = LATCH + get_elapsed(); - - /* - * Now convert them to usec. - */ - usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); - - return usec; -} - -static irqreturn_t -iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - u32 tisr; - - write_seqlock(&xtime_lock); - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); - tisr |= 1; - asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); - - timer_tick(regs); - - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; -} - -static struct irqaction iop331_timer_irq = { - .name = "IOP331 Timer Tick", - .handler = iop331_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static void __init iop331_timer_init(void) -{ - u32 timer_ctl; - - setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq); - - timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD | - IOP331_TMR_RATIO_1_1; - - asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); - - asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); - -} - -struct sys_timer iop331_timer = { - .init = iop331_timer_init, - .offset = iop331_gettimeoffset, -}; diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c deleted file mode 100644 index e874b54eefe3..000000000000 --- a/arch/arm/mach-iop3xx/iq31244-mm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80321 platform - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include - -#include -#include -#include - -#include - - -/* - * IQ80321 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ -static struct map_desc iq31244_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = IQ31244_UART, - .pfn = __phys_to_pfn(IQ31244_UART), - .length = 0x00100000, - .type = MT_DEVICE - } -}; - -void __init iq31244_map_io(void) -{ - iop321_map_io(); - - iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc)); -} diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c deleted file mode 100644 index f3c6413fa5bd..000000000000 --- a/arch/arm/mach-iop3xx/iq31244-pci.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80321-pci.c - * - * PCI support for the Intel IQ80321 reference board - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ31244_INTA -#define INTB IRQ_IQ31244_INTB -#define INTC IRQ_IQ31244_INTC -#define INTD IRQ_IQ31244_INTD - -#define INTE IRQ_IQ31244_I82546 - -static inline int __init -iq31244_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ -#ifdef CONFIG_ARCH_EP80219 - {INTB, INTB, INTB, INTB}, /* CFlash */ - {INTE, INTE, INTE, INTE}, /* 82551 Pro 100 */ - {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ - {INTC, INTC, INTC, INTC}, /* SATA */ -#else - {INTB, INTB, INTB, INTB}, /* CFlash */ - {INTC, INTC, INTC, INTC}, /* SATA */ - {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ - {INTE, INTE, INTE, INTE}, /* 82546 GigE */ -#endif // CONFIG_ARCH_EP80219 - }; - - BUG_ON(pin < 1 || pin > 4); - - return PCI_IRQ_TABLE_LOOKUP(0, 7); -} - -static int iq31244_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP321_PCI_LOWER_IO_VA; - res[0].end = IOP321_PCI_UPPER_IO_VA; - res[0].name = "IQ31244 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP321_PCI_LOWER_MEM_PA; - res[1].end = IOP321_PCI_UPPER_MEM_PA; - res[1].name = "IQ31244 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP321_PCI_MEM_OFFSET; - sys->io_offset = IOP321_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq31244_preinit(void) -{ - iop321_init(); -} - -static struct hw_pci iq31244_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq31244_setup, - .scan = iop321_scan_bus, - .preinit = iq31244_preinit, - .map_irq = iq31244_map_irq -}; - -static int __init iq31244_pci_init(void) -{ - if (machine_is_iq31244()) - pci_common_init(&iq31244_pci); - return 0; -} - -subsys_initcall(iq31244_pci_init); - - - - diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c deleted file mode 100644 index d9cac5e1fc3d..000000000000 --- a/arch/arm/mach-iop3xx/iq80321-mm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80321 platform - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include - -#include -#include -#include - -#include - - -/* - * IQ80321 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ -static struct map_desc iq80321_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = IQ80321_UART, - .pfn = __phys_to_pfn(IQ80321_UART), - .length = 0x00100000, - .type = MT_DEVICE - } -}; - -void __init iq80321_map_io(void) -{ - iop321_map_io(); - - iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc)); -} diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c deleted file mode 100644 index d9758d3f6e7f..000000000000 --- a/arch/arm/mach-iop3xx/iq80321-pci.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80321-pci.c - * - * PCI support for the Intel IQ80321 reference board - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ80321_INTA -#define INTB IRQ_IQ80321_INTB -#define INTC IRQ_IQ80321_INTC -#define INTD IRQ_IQ80321_INTD - -#define INTE IRQ_IQ80321_I82544 - -static inline int __init -iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {INTE, INTE, INTE, INTE}, /* Gig-E */ - {-1, -1, -1, -1}, /* Unused */ - {INTC, INTD, INTA, INTB}, /* PCI-X Slot */ - {-1, -1, -1, -1}, - }; - - BUG_ON(pin < 1 || pin > 4); - -// return PCI_IRQ_TABLE_LOOKUP(4, 7); - return pci_irq_table[idsel%4][pin-1]; -} - -static int iq80321_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP321_PCI_LOWER_IO_VA; - res[0].end = IOP321_PCI_UPPER_IO_VA; - res[0].name = "IQ80321 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP321_PCI_LOWER_MEM_PA; - res[1].end = IOP321_PCI_UPPER_MEM_PA; - res[1].name = "IQ80321 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP321_PCI_MEM_OFFSET; - sys->io_offset = IOP321_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq80321_preinit(void) -{ - iop321_init(); -} - -static struct hw_pci iq80321_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq80321_setup, - .scan = iop321_scan_bus, - .preinit = iq80321_preinit, - .map_irq = iq80321_map_irq -}; - -static int __init iq80321_pci_init(void) -{ - if (machine_is_iq80321()) - pci_common_init(&iq80321_pci); - return 0; -} - -subsys_initcall(iq80321_pci_init); - - - - diff --git a/arch/arm/mach-iop3xx/iq80331-mm.c b/arch/arm/mach-iop3xx/iq80331-mm.c deleted file mode 100644 index 129eb49b0670..000000000000 --- a/arch/arm/mach-iop3xx/iq80331-mm.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80331 platform - * - * Author: Dave Jiang - * Copyright (C) 2003 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include - -#include -#include -#include - -#include - - -/* - * IQ80331 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ - -void __init iq80331_map_io(void) -{ - iop331_map_io(); -} diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c deleted file mode 100644 index 40d861002492..000000000000 --- a/arch/arm/mach-iop3xx/iq80331-pci.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80331-pci.c - * - * PCI support for the Intel IQ80331 reference board - * - * Author: Dave Jiang - * Copyright (C) 2003, 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ80331_INTA -#define INTB IRQ_IQ80331_INTB -#define INTC IRQ_IQ80331_INTC -#define INTD IRQ_IQ80331_INTD - -//#define INTE IRQ_IQ80331_I82544 - -static inline int __init -iq80331_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {INTB, INTC, INTD, INTA}, /* PCI-X Slot */ - {INTC, INTC, INTC, INTC}, /* GigE */ - }; - - BUG_ON(pin < 1 || pin > 4); - - return PCI_IRQ_TABLE_LOOKUP(1, 7); -} - -static int iq80331_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP331_PCI_LOWER_IO_VA; - res[0].end = IOP331_PCI_UPPER_IO_VA; - res[0].name = "IQ80331 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP331_PCI_LOWER_MEM_PA; - res[1].end = IOP331_PCI_UPPER_MEM_PA; - res[1].name = "IQ80331 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP331_PCI_MEM_OFFSET; - sys->io_offset = IOP331_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq80331_preinit(void) -{ - iop331_init(); -} - -static struct hw_pci iq80331_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq80331_setup, - .scan = iop331_scan_bus, - .preinit = iq80331_preinit, - .map_irq = iq80331_map_irq -}; - -static int __init iq80331_pci_init(void) -{ - if (machine_is_iq80331()) - pci_common_init(&iq80331_pci); - return 0; -} - -subsys_initcall(iq80331_pci_init); - - - - diff --git a/arch/arm/mach-iop3xx/iq80332-mm.c b/arch/arm/mach-iop3xx/iq80332-mm.c deleted file mode 100644 index 2feaf7591f53..000000000000 --- a/arch/arm/mach-iop3xx/iq80332-mm.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80332 platform - * - * Author: Dave Jiang - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include - -#include -#include -#include - -#include - - -/* - * IQ80332 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ - -void __init iq80332_map_io(void) -{ - iop331_map_io(); -} diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c deleted file mode 100644 index afc0676318e4..000000000000 --- a/arch/arm/mach-iop3xx/iq80332-pci.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80332-pci.c - * - * PCI support for the Intel IQ80332 reference board - * - * Author: Dave Jiang - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ80332_INTA -#define INTB IRQ_IQ80332_INTB -#define INTC IRQ_IQ80332_INTC -#define INTD IRQ_IQ80332_INTD - -//#define INTE IRQ_IQ80332_I82544 - -static inline int __init -iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][8] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {-1, -1, -1, -1}, - {-1, -1, -1, -1}, - {-1, -1, -1, -1}, - {INTA, INTB, INTC, INTD}, /* PCI-X Slot */ - {-1, -1, -1, -1}, - {INTC, INTC, INTC, INTC}, /* GigE */ - {-1, -1, -1, -1}, - {-1, -1, -1, -1}, - }; - - BUG_ON(pin < 1 || pin > 4); - - return PCI_IRQ_TABLE_LOOKUP(1, 7); -} - -static int iq80332_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP331_PCI_LOWER_IO_VA; - res[0].end = IOP331_PCI_UPPER_IO_VA; - res[0].name = "IQ80332 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP331_PCI_LOWER_MEM_PA; - res[1].end = IOP331_PCI_UPPER_MEM_PA; - res[1].name = "IQ80332 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP331_PCI_MEM_OFFSET; - sys->io_offset = IOP331_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq80332_preinit(void) -{ - iop331_init(); -} - -static struct hw_pci iq80332_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq80332_setup, - .scan = iop331_scan_bus, - .preinit = iq80332_preinit, - .map_irq = iq80332_map_irq -}; - -static int __init iq80332_pci_init(void) -{ - if (machine_is_iq80332()) - pci_common_init(&iq80332_pci); - return 0; -} - -subsys_initcall(iq80332_pci_init); - - - - diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index b4f220dd5eb8..b59c74100a84 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -232,7 +232,7 @@ config CPU_SA1100 # XScale config CPU_XSCALE bool - depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 + depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 default y select CPU_32v5 select CPU_ABRT_EV5T diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 884320e70403..a843d6b10a0c 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -196,7 +196,7 @@ config I2C_IBM_IIC config I2C_IOP3XX tristate "Intel IOP3xx and IXP4xx on-chip I2C interface" - depends on (ARCH_IOP3XX || ARCH_IXP4XX) && I2C + depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX) && I2C help Say Y here if you want to use the IIC bus controller on the Intel IOP3xx I/O Processors or IXP4xx Network Processors. diff --git a/include/asm-arm/arch-iop32x/debug-macro.S b/include/asm-arm/arch-iop32x/debug-macro.S new file mode 100644 index 000000000000..75ab2e0d8c67 --- /dev/null +++ b/include/asm-arm/arch-iop32x/debug-macro.S @@ -0,0 +1,20 @@ +/* linux/include/asm-arm/arch-iop32x/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + + .macro addruart,rx + mov \rx, #0xfe000000 @ physical + orr \rx, \rx, #0x00800000 @ location of the UART + .endm + +#define UART_SHIFT 0 +#include diff --git a/include/asm-arm/arch-iop32x/dma.h b/include/asm-arm/arch-iop32x/dma.h new file mode 100644 index 000000000000..5be36676e58f --- /dev/null +++ b/include/asm-arm/arch-iop32x/dma.h @@ -0,0 +1,9 @@ +/* + * linux/include/asm-arm/arch-iop32x/dma.h + * + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ diff --git a/include/asm-arm/arch-iop32x/entry-macro.S b/include/asm-arm/arch-iop32x/entry-macro.S new file mode 100644 index 000000000000..52d9435c6a34 --- /dev/null +++ b/include/asm-arm/arch-iop32x/entry-macro.S @@ -0,0 +1,28 @@ +/* + * include/asm-arm/arch-iop32x/entry-macro.S + * + * Low-level IRQ helper macros for IOP32x-based platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include + + .macro disable_fiq + .endm + + /* + * Note: only deal with normal interrupts, not FIQ + */ + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + mov \irqnr, #0 + mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC + cmp \irqstat, #0 + beq 1001f + clz \irqnr, \irqstat + mov \base, #31 + subs \irqnr,\base,\irqnr + add \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT +1001: + .endm diff --git a/include/asm-arm/arch-iop32x/hardware.h b/include/asm-arm/arch-iop32x/hardware.h new file mode 100644 index 000000000000..8fb10134a107 --- /dev/null +++ b/include/asm-arm/arch-iop32x/hardware.h @@ -0,0 +1,54 @@ +/* + * linux/include/asm-arm/arch-iop32x/hardware.h + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include + +/* + * Note about PCI IO space mappings + * + * To make IO space accesses efficient, we store virtual addresses in + * the IO resources. + * + * The PCI IO space is located at virtual 0xfe000000 from physical + * 0x90000000. The PCI BARs must be programmed with physical addresses, + * but when we read them, we convert them to virtual addresses. See + * arch/arm/mach-iop3xx/iop3xx-pci.c + */ + +#define pcibios_assign_all_busses() 1 + + +/* + * The min PCI I/O and MEM space are dependent on what specific + * chipset/platform we are running on, so instead of hardcoding with + * #ifdefs, we just fill these in the platform level PCI init code. + */ +#ifndef __ASSEMBLY__ +extern unsigned long iop3xx_pcibios_min_io; +extern unsigned long iop3xx_pcibios_min_mem; + +extern unsigned int processor_id; +#endif + +/* + * We just set these to zero since they are really bogus anyways + */ +#define PCIBIOS_MIN_IO (iop3xx_pcibios_min_io) +#define PCIBIOS_MIN_MEM (iop3xx_pcibios_min_mem) + +/* + * Generic chipset bits + * + */ +#include "iop321.h" + +/* + * Board specific bits + */ +#include "iq80321.h" +#include "iq31244.h" + +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-iop32x/io.h b/include/asm-arm/arch-iop32x/io.h new file mode 100644 index 000000000000..36d05ada12c4 --- /dev/null +++ b/include/asm-arm/arch-iop32x/io.h @@ -0,0 +1,21 @@ +/* + * linux/include/asm-arm/arch-iop32x/io.h + * + * Copyright (C) 2001 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#include + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(p) ((void __iomem *)(p)) +#define __mem_pci(a) (a) + +#endif diff --git a/include/asm-arm/arch-iop32x/iop321.h b/include/asm-arm/arch-iop32x/iop321.h new file mode 100644 index 000000000000..7ba93faf8da4 --- /dev/null +++ b/include/asm-arm/arch-iop32x/iop321.h @@ -0,0 +1,341 @@ +/* + * linux/include/asm/arch-iop32x/iop321.h + * + * Intel IOP321 Chip definitions + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _IOP321_HW_H_ +#define _IOP321_HW_H_ + + +/* + * This is needed for mixed drivers that need to work on all + * IOP3xx variants but behave slightly differently on each. + */ +#ifndef __ASSEMBLY__ +#define iop_is_321() 1 +#endif + +/* + * IOP321 I/O and Mem space regions for PCI autoconfiguration + */ +#define IOP321_PCI_IO_WINDOW_SIZE 0x00010000 +#define IOP321_PCI_LOWER_IO_PA 0x90000000 +#define IOP321_PCI_LOWER_IO_VA 0xfe000000 +#define IOP321_PCI_LOWER_IO_BA (*IOP321_OIOWTVR) +#define IOP321_PCI_UPPER_IO_PA (IOP321_PCI_LOWER_IO_PA + IOP321_PCI_IO_WINDOW_SIZE - 1) +#define IOP321_PCI_UPPER_IO_VA (IOP321_PCI_LOWER_IO_VA + IOP321_PCI_IO_WINDOW_SIZE - 1) +#define IOP321_PCI_UPPER_IO_BA (IOP321_PCI_LOWER_IO_BA + IOP321_PCI_IO_WINDOW_SIZE - 1) +#define IOP321_PCI_IO_OFFSET (IOP321_PCI_LOWER_IO_VA - IOP321_PCI_LOWER_IO_BA) + +/* #define IOP321_PCI_MEM_WINDOW_SIZE (~*IOP321_IALR1 + 1) */ +#define IOP321_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */ +#define IOP321_PCI_LOWER_MEM_PA 0x80000000 +#define IOP321_PCI_LOWER_MEM_BA (*IOP321_OMWTVR0) +#define IOP321_PCI_UPPER_MEM_PA (IOP321_PCI_LOWER_MEM_PA + IOP321_PCI_MEM_WINDOW_SIZE - 1) +#define IOP321_PCI_UPPER_MEM_BA (IOP321_PCI_LOWER_MEM_BA + IOP321_PCI_MEM_WINDOW_SIZE - 1) +#define IOP321_PCI_MEM_OFFSET (IOP321_PCI_LOWER_MEM_PA - IOP321_PCI_LOWER_MEM_BA) + + +/* + * IOP321 chipset registers + */ +#define IOP321_VIRT_MEM_BASE 0xfeffe000 /* chip virtual mem address*/ +#define IOP321_PHYS_MEM_BASE 0xffffe000 /* chip physical memory address */ +#define IOP321_REG_ADDR(reg) (IOP321_VIRT_MEM_BASE | (reg)) + +/* Reserved 0x00000000 through 0x000000FF */ + +/* Address Translation Unit 0x00000100 through 0x000001FF */ +#define IOP321_ATUVID (volatile u16 *)IOP321_REG_ADDR(0x00000100) +#define IOP321_ATUDID (volatile u16 *)IOP321_REG_ADDR(0x00000102) +#define IOP321_ATUCMD (volatile u16 *)IOP321_REG_ADDR(0x00000104) +#define IOP321_ATUSR (volatile u16 *)IOP321_REG_ADDR(0x00000106) +#define IOP321_ATURID (volatile u8 *)IOP321_REG_ADDR(0x00000108) +#define IOP321_ATUCCR (volatile u32 *)IOP321_REG_ADDR(0x00000109) +#define IOP321_ATUCLSR (volatile u8 *)IOP321_REG_ADDR(0x0000010C) +#define IOP321_ATULT (volatile u8 *)IOP321_REG_ADDR(0x0000010D) +#define IOP321_ATUHTR (volatile u8 *)IOP321_REG_ADDR(0x0000010E) +#define IOP321_ATUBIST (volatile u8 *)IOP321_REG_ADDR(0x0000010F) +#define IOP321_IABAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000110) +#define IOP321_IAUBAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000114) +#define IOP321_IABAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000118) +#define IOP321_IAUBAR1 (volatile u32 *)IOP321_REG_ADDR(0x0000011C) +#define IOP321_IABAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000120) +#define IOP321_IAUBAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000124) +#define IOP321_ASVIR (volatile u16 *)IOP321_REG_ADDR(0x0000012C) +#define IOP321_ASIR (volatile u16 *)IOP321_REG_ADDR(0x0000012E) +#define IOP321_ERBAR (volatile u32 *)IOP321_REG_ADDR(0x00000130) +/* Reserved 0x00000134 through 0x0000013B */ +#define IOP321_ATUILR (volatile u8 *)IOP321_REG_ADDR(0x0000013C) +#define IOP321_ATUIPR (volatile u8 *)IOP321_REG_ADDR(0x0000013D) +#define IOP321_ATUMGNT (volatile u8 *)IOP321_REG_ADDR(0x0000013E) +#define IOP321_ATUMLAT (volatile u8 *)IOP321_REG_ADDR(0x0000013F) +#define IOP321_IALR0 (volatile u32 *)IOP321_REG_ADDR(0x00000140) +#define IOP321_IATVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000144) +#define IOP321_ERLR (volatile u32 *)IOP321_REG_ADDR(0x00000148) +#define IOP321_ERTVR (volatile u32 *)IOP321_REG_ADDR(0x0000014C) +#define IOP321_IALR1 (volatile u32 *)IOP321_REG_ADDR(0x00000150) +#define IOP321_IALR2 (volatile u32 *)IOP321_REG_ADDR(0x00000154) +#define IOP321_IATVR2 (volatile u32 *)IOP321_REG_ADDR(0x00000158) +#define IOP321_OIOWTVR (volatile u32 *)IOP321_REG_ADDR(0x0000015C) +#define IOP321_OMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000160) +#define IOP321_OUMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000164) +#define IOP321_OMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x00000168) +#define IOP321_OUMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x0000016C) +/* Reserved 0x00000170 through 0x00000177*/ +#define IOP321_OUDWTVR (volatile u32 *)IOP321_REG_ADDR(0x00000178) +/* Reserved 0x0000017C through 0x0000017F*/ +#define IOP321_ATUCR (volatile u32 *)IOP321_REG_ADDR(0x00000180) +#define IOP321_PCSR (volatile u32 *)IOP321_REG_ADDR(0x00000184) +#define IOP321_ATUISR (volatile u32 *)IOP321_REG_ADDR(0x00000188) +#define IOP321_ATUIMR (volatile u32 *)IOP321_REG_ADDR(0x0000018C) +#define IOP321_IABAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000190) +#define IOP321_IAUBAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000194) +#define IOP321_IALR3 (volatile u32 *)IOP321_REG_ADDR(0x00000198) +#define IOP321_IATVR3 (volatile u32 *)IOP321_REG_ADDR(0x0000019C) +/* Reserved 0x000001A0 through 0x000001A3*/ +#define IOP321_OCCAR (volatile u32 *)IOP321_REG_ADDR(0x000001A4) +/* Reserved 0x000001A8 through 0x000001AB*/ +#define IOP321_OCCDR (volatile u32 *)IOP321_REG_ADDR(0x000001AC) +/* Reserved 0x000001B0 through 0x000001BB*/ +#define IOP321_PDSCR (volatile u32 *)IOP321_REG_ADDR(0x000001BC) +#define IOP321_PMCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001C0) +#define IOP321_PMNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001C1) +#define IOP321_APMCR (volatile u16 *)IOP321_REG_ADDR(0x000001C2) +#define IOP321_APMCSR (volatile u16 *)IOP321_REG_ADDR(0x000001C4) +/* Reserved 0x000001C6 through 0x000001DF */ +#define IOP321_PCIXCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001E0) +#define IOP321_PCIXNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001E1) +#define IOP321_PCIXCMD (volatile u16 *)IOP321_REG_ADDR(0x000001E2) +#define IOP321_PCIXSR (volatile u32 *)IOP321_REG_ADDR(0x000001E4) +#define IOP321_PCIIRSR (volatile u32 *)IOP321_REG_ADDR(0x000001EC) + +/* Messaging Unit 0x00000300 through 0x000003FF */ + +/* Reserved 0x00000300 through 0x0000030c */ +#define IOP321_IMR0 (volatile u32 *)IOP321_REG_ADDR(0x00000310) +#define IOP321_IMR1 (volatile u32 *)IOP321_REG_ADDR(0x00000314) +#define IOP321_OMR0 (volatile u32 *)IOP321_REG_ADDR(0x00000318) +#define IOP321_OMR1 (volatile u32 *)IOP321_REG_ADDR(0x0000031C) +#define IOP321_IDR (volatile u32 *)IOP321_REG_ADDR(0x00000320) +#define IOP321_IISR (volatile u32 *)IOP321_REG_ADDR(0x00000324) +#define IOP321_IIMR (volatile u32 *)IOP321_REG_ADDR(0x00000328) +#define IOP321_ODR (volatile u32 *)IOP321_REG_ADDR(0x0000032C) +#define IOP321_OISR (volatile u32 *)IOP321_REG_ADDR(0x00000330) +#define IOP321_OIMR (volatile u32 *)IOP321_REG_ADDR(0x00000334) +/* Reserved 0x00000338 through 0x0000034F */ +#define IOP321_MUCR (volatile u32 *)IOP321_REG_ADDR(0x00000350) +#define IOP321_QBAR (volatile u32 *)IOP321_REG_ADDR(0x00000354) +/* Reserved 0x00000358 through 0x0000035C */ +#define IOP321_IFHPR (volatile u32 *)IOP321_REG_ADDR(0x00000360) +#define IOP321_IFTPR (volatile u32 *)IOP321_REG_ADDR(0x00000364) +#define IOP321_IPHPR (volatile u32 *)IOP321_REG_ADDR(0x00000368) +#define IOP321_IPTPR (volatile u32 *)IOP321_REG_ADDR(0x0000036C) +#define IOP321_OFHPR (volatile u32 *)IOP321_REG_ADDR(0x00000370) +#define IOP321_OFTPR (volatile u32 *)IOP321_REG_ADDR(0x00000374) +#define IOP321_OPHPR (volatile u32 *)IOP321_REG_ADDR(0x00000378) +#define IOP321_OPTPR (volatile u32 *)IOP321_REG_ADDR(0x0000037C) +#define IOP321_IAR (volatile u32 *)IOP321_REG_ADDR(0x00000380) + +#define IOP321_IIxR_MASK 0x7f /* masks all */ +#define IOP321_IIxR_IRI 0x40 /* RC Index Register Interrupt */ +#define IOP321_IIxR_OFQF 0x20 /* RC Output Free Q Full (ERROR) */ +#define IOP321_IIxR_ipq 0x10 /* RC Inbound Post Q (post) */ +#define IOP321_IIxR_ERRDI 0x08 /* RO Error Doorbell Interrupt */ +#define IOP321_IIxR_IDI 0x04 /* RO Inbound Doorbell Interrupt */ +#define IOP321_IIxR_IM1 0x02 /* RC Inbound Message 1 Interrupt */ +#define IOP321_IIxR_IM0 0x01 /* RC Inbound Message 0 Interrupt */ + +/* Reserved 0x00000384 through 0x000003FF */ + +/* DMA Controller 0x00000400 through 0x000004FF */ +#define IOP321_DMA0_CCR (volatile u32 *)IOP321_REG_ADDR(0x00000400) +#define IOP321_DMA0_CSR (volatile u32 *)IOP321_REG_ADDR(0x00000404) +#define IOP321_DMA0_DAR (volatile u32 *)IOP321_REG_ADDR(0x0000040C) +#define IOP321_DMA0_NDAR (volatile u32 *)IOP321_REG_ADDR(0x00000410) +#define IOP321_DMA0_PADR (volatile u32 *)IOP321_REG_ADDR(0x00000414) +#define IOP321_DMA0_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000418) +#define IOP321_DMA0_LADR (volatile u32 *)IOP321_REG_ADDR(0X0000041C) +#define IOP321_DMA0_BCR (volatile u32 *)IOP321_REG_ADDR(0x00000420) +#define IOP321_DMA0_DCR (volatile u32 *)IOP321_REG_ADDR(0x00000424) +/* Reserved 0x00000428 through 0x0000043C */ +#define IOP321_DMA1_CCR (volatile u32 *)IOP321_REG_ADDR(0x00000440) +#define IOP321_DMA1_CSR (volatile u32 *)IOP321_REG_ADDR(0x00000444) +#define IOP321_DMA1_DAR (volatile u32 *)IOP321_REG_ADDR(0x0000044C) +#define IOP321_DMA1_NDAR (volatile u32 *)IOP321_REG_ADDR(0x00000450) +#define IOP321_DMA1_PADR (volatile u32 *)IOP321_REG_ADDR(0x00000454) +#define IOP321_DMA1_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000458) +#define IOP321_DMA1_LADR (volatile u32 *)IOP321_REG_ADDR(0x0000045C) +#define IOP321_DMA1_BCR (volatile u32 *)IOP321_REG_ADDR(0x00000460) +#define IOP321_DMA1_DCR (volatile u32 *)IOP321_REG_ADDR(0x00000464) +/* Reserved 0x00000468 through 0x000004FF */ + +/* Memory controller 0x00000500 through 0x0005FF */ + +/* Peripheral bus interface unit 0x00000680 through 0x0006FF */ +#define IOP321_PBCR (volatile u32 *)IOP321_REG_ADDR(0x00000680) +#define IOP321_PBISR (volatile u32 *)IOP321_REG_ADDR(0x00000684) +#define IOP321_PBBAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000688) +#define IOP321_PBLR0 (volatile u32 *)IOP321_REG_ADDR(0x0000068C) +#define IOP321_PBBAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000690) +#define IOP321_PBLR1 (volatile u32 *)IOP321_REG_ADDR(0x00000694) +#define IOP321_PBBAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000698) +#define IOP321_PBLR2 (volatile u32 *)IOP321_REG_ADDR(0x0000069C) +#define IOP321_PBBAR3 (volatile u32 *)IOP321_REG_ADDR(0x000006A0) +#define IOP321_PBLR3 (volatile u32 *)IOP321_REG_ADDR(0x000006A4) +#define IOP321_PBBAR4 (volatile u32 *)IOP321_REG_ADDR(0x000006A8) +#define IOP321_PBLR4 (volatile u32 *)IOP321_REG_ADDR(0x000006AC) +#define IOP321_PBBAR5 (volatile u32 *)IOP321_REG_ADDR(0x000006B0) +#define IOP321_PBLR5 (volatile u32 *)IOP321_REG_ADDR(0x000006B4) +#define IOP321_PBDSCR (volatile u32 *)IOP321_REG_ADDR(0x000006B8) +/* Reserved 0x000006BC */ +#define IOP321_PMBR0 (volatile u32 *)IOP321_REG_ADDR(0x000006C0) +/* Reserved 0x000006C4 through 0x000006DC */ +#define IOP321_PMBR1 (volatile u32 *)IOP321_REG_ADDR(0x000006E0) +#define IOP321_PMBR2 (volatile u32 *)IOP321_REG_ADDR(0x000006E4) + +#define IOP321_PBCR_EN 0x1 + +#define IOP321_PBISR_BOOR_ERR 0x1 + +/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */ +#define IOP321_GTMR (volatile u32 *)IOP321_REG_ADDR(0x00000700) +#define IOP321_ESR (volatile u32 *)IOP321_REG_ADDR(0x00000704) +#define IOP321_EMISR (volatile u32 *)IOP321_REG_ADDR(0x00000708) +/* reserved 0x00000070c */ +#define IOP321_GTSR (volatile u32 *)IOP321_REG_ADDR(0x00000710) +/* PERC0 DOESN'T EXIST - index from 1! */ +#define IOP321_PERCR0 (volatile u32 *)IOP321_REG_ADDR(0x00000710) + +#define IOP321_GTMR_NGCE 0x04 /* (Not) Global Counter Enable */ + +/* Internal arbitration unit 0x00000780 through 0x0007BF */ +#define IOP321_IACR (volatile u32 *)IOP321_REG_ADDR(0x00000780) +#define IOP321_MTTR1 (volatile u32 *)IOP321_REG_ADDR(0x00000784) +#define IOP321_MTTR2 (volatile u32 *)IOP321_REG_ADDR(0x00000788) + +/* General Purpose I/O Registers */ +#define IOP321_GPOE (volatile u32 *)IOP321_REG_ADDR(0x000007C4) +#define IOP321_GPID (volatile u32 *)IOP321_REG_ADDR(0x000007C8) +#define IOP321_GPOD (volatile u32 *)IOP321_REG_ADDR(0x000007CC) + +/* Interrupt Controller */ +#define IOP321_INTCTL (volatile u32 *)IOP321_REG_ADDR(0x000007D0) +#define IOP321_INTSTR (volatile u32 *)IOP321_REG_ADDR(0x000007D4) +#define IOP321_IINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007D8) +#define IOP321_FINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007DC) + +/* Timers */ + +#define IOP321_TU_TMR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E0) +#define IOP321_TU_TMR1 (volatile u32 *)IOP321_REG_ADDR(0x000007E4) + +#ifdef CONFIG_ARCH_IQ80321 +#define IOP321_TICK_RATE 200000000 /* 200 MHz clock */ +#elif defined(CONFIG_ARCH_IQ31244) +#define IOP321_TICK_RATE 198000000 /* 33.000 MHz crystal */ +#endif + +#ifdef CONFIG_ARCH_EP80219 +#undef IOP321_TICK_RATE +#define IOP321_TICK_RATE 200000000 /* 33.333333 Mhz crystal */ +#endif + +#define IOP321_TMR_TC 0x01 +#define IOP321_TMR_EN 0x02 +#define IOP321_TMR_RELOAD 0x04 +#define IOP321_TMR_PRIVILEGED 0x09 + +#define IOP321_TMR_RATIO_1_1 0x00 +#define IOP321_TMR_RATIO_4_1 0x10 +#define IOP321_TMR_RATIO_8_1 0x20 +#define IOP321_TMR_RATIO_16_1 0x30 + +#define IOP321_TU_TCR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E8) +#define IOP321_TU_TCR1 (volatile u32 *)IOP321_REG_ADDR(0x000007EC) +#define IOP321_TU_TRR0 (volatile u32 *)IOP321_REG_ADDR(0x000007F0) +#define IOP321_TU_TRR1 (volatile u32 *)IOP321_REG_ADDR(0x000007F4) +#define IOP321_TU_TISR (volatile u32 *)IOP321_REG_ADDR(0x000007F8) +#define IOP321_TU_WDTCR (volatile u32 *)IOP321_REG_ADDR(0x000007FC) + +/* Application accelerator unit 0x00000800 - 0x000008FF */ +#define IOP321_AAU_ACR (volatile u32 *)IOP321_REG_ADDR(0x00000800) +#define IOP321_AAU_ASR (volatile u32 *)IOP321_REG_ADDR(0x00000804) +#define IOP321_AAU_ADAR (volatile u32 *)IOP321_REG_ADDR(0x00000808) +#define IOP321_AAU_ANDAR (volatile u32 *)IOP321_REG_ADDR(0x0000080C) +#define IOP321_AAU_SAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000810) +#define IOP321_AAU_SAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000814) +#define IOP321_AAU_SAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000818) +#define IOP321_AAU_SAR4 (volatile u32 *)IOP321_REG_ADDR(0x0000081C) +#define IOP321_AAU_SAR5 (volatile u32 *)IOP321_REG_ADDR(0x0000082C) +#define IOP321_AAU_SAR6 (volatile u32 *)IOP321_REG_ADDR(0x00000830) +#define IOP321_AAU_SAR7 (volatile u32 *)IOP321_REG_ADDR(0x00000834) +#define IOP321_AAU_SAR8 (volatile u32 *)IOP321_REG_ADDR(0x00000838) +#define IOP321_AAU_SAR9 (volatile u32 *)IOP321_REG_ADDR(0x00000840) +#define IOP321_AAU_SAR10 (volatile u32 *)IOP321_REG_ADDR(0x00000844) +#define IOP321_AAU_SAR11 (volatile u32 *)IOP321_REG_ADDR(0x00000848) +#define IOP321_AAU_SAR12 (volatile u32 *)IOP321_REG_ADDR(0x0000084C) +#define IOP321_AAU_SAR13 (volatile u32 *)IOP321_REG_ADDR(0x00000850) +#define IOP321_AAU_SAR14 (volatile u32 *)IOP321_REG_ADDR(0x00000854) +#define IOP321_AAU_SAR15 (volatile u32 *)IOP321_REG_ADDR(0x00000858) +#define IOP321_AAU_SAR16 (volatile u32 *)IOP321_REG_ADDR(0x0000085C) +#define IOP321_AAU_SAR17 (volatile u32 *)IOP321_REG_ADDR(0x00000864) +#define IOP321_AAU_SAR18 (volatile u32 *)IOP321_REG_ADDR(0x00000868) +#define IOP321_AAU_SAR19 (volatile u32 *)IOP321_REG_ADDR(0x0000086C) +#define IOP321_AAU_SAR20 (volatile u32 *)IOP321_REG_ADDR(0x00000870) +#define IOP321_AAU_SAR21 (volatile u32 *)IOP321_REG_ADDR(0x00000874) +#define IOP321_AAU_SAR22 (volatile u32 *)IOP321_REG_ADDR(0x00000878) +#define IOP321_AAU_SAR23 (volatile u32 *)IOP321_REG_ADDR(0x0000087C) +#define IOP321_AAU_SAR24 (volatile u32 *)IOP321_REG_ADDR(0x00000880) +#define IOP321_AAU_SAR25 (volatile u32 *)IOP321_REG_ADDR(0x00000888) +#define IOP321_AAU_SAR26 (volatile u32 *)IOP321_REG_ADDR(0x0000088C) +#define IOP321_AAU_SAR27 (volatile u32 *)IOP321_REG_ADDR(0x00000890) +#define IOP321_AAU_SAR28 (volatile u32 *)IOP321_REG_ADDR(0x00000894) +#define IOP321_AAU_SAR29 (volatile u32 *)IOP321_REG_ADDR(0x00000898) +#define IOP321_AAU_SAR30 (volatile u32 *)IOP321_REG_ADDR(0x0000089C) +#define IOP321_AAU_SAR31 (volatile u32 *)IOP321_REG_ADDR(0x000008A0) +#define IOP321_AAU_SAR32 (volatile u32 *)IOP321_REG_ADDR(0x000008A4) +#define IOP321_AAU_DAR (volatile u32 *)IOP321_REG_ADDR(0x00000820) +#define IOP321_AAU_ABCR (volatile u32 *)IOP321_REG_ADDR(0x00000824) +#define IOP321_AAU_ADCR (volatile u32 *)IOP321_REG_ADDR(0x00000828) +#define IOP321_AAU_EDCR0 (volatile u32 *)IOP321_REG_ADDR(0x0000083c) +#define IOP321_AAU_EDCR1 (volatile u32 *)IOP321_REG_ADDR(0x00000860) +#define IOP321_AAU_EDCR2 (volatile u32 *)IOP321_REG_ADDR(0x00000884) + + +/* SSP serial port unit 0x00001600 - 0x0000167F */ +/* I2C bus interface unit 0x00001680 - 0x000016FF */ +#define IOP321_ICR0 (volatile u32 *)IOP321_REG_ADDR(0x00001680) +#define IOP321_ISR0 (volatile u32 *)IOP321_REG_ADDR(0x00001684) +#define IOP321_ISAR0 (volatile u32 *)IOP321_REG_ADDR(0x00001688) +#define IOP321_IDBR0 (volatile u32 *)IOP321_REG_ADDR(0x0000168C) +/* Reserved 0x00001690 */ +#define IOP321_IBMR0 (volatile u32 *)IOP321_REG_ADDR(0x00001694) +/* Reserved 0x00001698 */ +/* Reserved 0x0000169C */ +#define IOP321_ICR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A0) +#define IOP321_ISR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A4) +#define IOP321_ISAR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A8) +#define IOP321_IDBR1 (volatile u32 *)IOP321_REG_ADDR(0x000016AC) +#define IOP321_IBMR1 (volatile u32 *)IOP321_REG_ADDR(0x000016B4) +/* Reserved 0x000016B8 through 0x000016FC */ + +/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */ + + +#ifndef __ASSEMBLY__ +extern void iop321_map_io(void); +extern void iop321_init_irq(void); +extern void iop321_time_init(void); +#endif + +#endif // _IOP321_HW_H_ diff --git a/include/asm-arm/arch-iop32x/iq31244.h b/include/asm-arm/arch-iop32x/iq31244.h new file mode 100644 index 000000000000..f490063d2156 --- /dev/null +++ b/include/asm-arm/arch-iop32x/iq31244.h @@ -0,0 +1,24 @@ +/* + * linux/include/asm/arch-iop32x/iq31244.h + * + * Intel IQ31244 evaluation board registers + */ + +#ifndef _IQ31244_H_ +#define _IQ31244_H_ + +#define IQ31244_FLASHBASE 0xf0000000 /* Flash */ +#define IQ31244_FLASHSIZE 0x00800000 +#define IQ31244_FLASHWIDTH 2 + +#define IQ31244_UART 0xfe800000 /* UART #1 */ +#define IQ31244_7SEG_1 0xfe840000 /* 7-Segment MSB */ +#define IQ31244_7SEG_0 0xfe850000 /* 7-Segment LSB (WO) */ +#define IQ31244_ROTARY_SW 0xfe8d0000 /* Rotary Switch */ +#define IQ31244_BATT_STAT 0xfe8f0000 /* Battery Status */ + +#ifndef __ASSEMBLY__ +extern void iq31244_map_io(void); +#endif + +#endif // _IQ31244_H_ diff --git a/include/asm-arm/arch-iop32x/iq80321.h b/include/asm-arm/arch-iop32x/iq80321.h new file mode 100644 index 000000000000..7015a605ab64 --- /dev/null +++ b/include/asm-arm/arch-iop32x/iq80321.h @@ -0,0 +1,24 @@ +/* + * linux/include/asm/arch-iop32x/iq80321.h + * + * Intel IQ80321 evaluation board registers + */ + +#ifndef _IQ80321_H_ +#define _IQ80321_H_ + +#define IQ80321_FLASHBASE 0xf0000000 /* Flash */ +#define IQ80321_FLASHSIZE 0x00800000 +#define IQ80321_FLASHWIDTH 1 + +#define IQ80321_UART 0xfe800000 /* UART #1 */ +#define IQ80321_7SEG_1 0xfe840000 /* 7-Segment MSB */ +#define IQ80321_7SEG_0 0xfe850000 /* 7-Segment LSB (WO) */ +#define IQ80321_ROTARY_SW 0xfe8d0000 /* Rotary Switch */ +#define IQ80321_BATT_STAT 0xfe8f0000 /* Battery Status */ + +#ifndef __ASSEMBLY__ +extern void iq80321_map_io(void); +#endif + +#endif // _IQ80321_H_ diff --git a/include/asm-arm/arch-iop32x/irqs.h b/include/asm-arm/arch-iop32x/irqs.h new file mode 100644 index 000000000000..4b0c82711f96 --- /dev/null +++ b/include/asm-arm/arch-iop32x/irqs.h @@ -0,0 +1,98 @@ +/* + * linux/include/asm-arm/arch-iop32x/irqs.h + * + * Author: Rory Bolt + * Copyright: (C) 2002 Rory Bolt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef _IRQS_H_ +#define _IRQS_H_ + +/* + * IOP80321 chipset interrupts + */ +#define IOP321_IRQ_OFS 0 +#define IOP321_IRQ(x) (IOP321_IRQ_OFS + (x)) + +/* + * On IRQ or FIQ register + */ +#define IRQ_IOP321_DMA0_EOT IOP321_IRQ(0) +#define IRQ_IOP321_DMA0_EOC IOP321_IRQ(1) +#define IRQ_IOP321_DMA1_EOT IOP321_IRQ(2) +#define IRQ_IOP321_DMA1_EOC IOP321_IRQ(3) +#define IRQ_IOP321_RSVD_4 IOP321_IRQ(4) +#define IRQ_IOP321_RSVD_5 IOP321_IRQ(5) +#define IRQ_IOP321_AA_EOT IOP321_IRQ(6) +#define IRQ_IOP321_AA_EOC IOP321_IRQ(7) +#define IRQ_IOP321_CORE_PMON IOP321_IRQ(8) +#define IRQ_IOP321_TIMER0 IOP321_IRQ(9) +#define IRQ_IOP321_TIMER1 IOP321_IRQ(10) +#define IRQ_IOP321_I2C_0 IOP321_IRQ(11) +#define IRQ_IOP321_I2C_1 IOP321_IRQ(12) +#define IRQ_IOP321_MESSAGING IOP321_IRQ(13) +#define IRQ_IOP321_ATU_BIST IOP321_IRQ(14) +#define IRQ_IOP321_PERFMON IOP321_IRQ(15) +#define IRQ_IOP321_CORE_PMU IOP321_IRQ(16) +#define IRQ_IOP321_BIU_ERR IOP321_IRQ(17) +#define IRQ_IOP321_ATU_ERR IOP321_IRQ(18) +#define IRQ_IOP321_MCU_ERR IOP321_IRQ(19) +#define IRQ_IOP321_DMA0_ERR IOP321_IRQ(20) +#define IRQ_IOP321_DMA1_ERR IOP321_IRQ(21) +#define IRQ_IOP321_RSVD_22 IOP321_IRQ(22) +#define IRQ_IOP321_AA_ERR IOP321_IRQ(23) +#define IRQ_IOP321_MSG_ERR IOP321_IRQ(24) +#define IRQ_IOP321_SSP IOP321_IRQ(25) +#define IRQ_IOP321_RSVD_26 IOP321_IRQ(26) +#define IRQ_IOP321_XINT0 IOP321_IRQ(27) +#define IRQ_IOP321_XINT1 IOP321_IRQ(28) +#define IRQ_IOP321_XINT2 IOP321_IRQ(29) +#define IRQ_IOP321_XINT3 IOP321_IRQ(30) +#define IRQ_IOP321_HPI IOP321_IRQ(31) + +#define NR_IRQS (IOP321_IRQ(31) + 1) + + +/* + * Interrupts available on the IQ80321 board + */ + +/* + * On board devices + */ +#define IRQ_IQ80321_I82544 IRQ_IOP321_XINT0 +#define IRQ_IQ80321_UART IRQ_IOP321_XINT1 + +/* + * PCI interrupts + */ +#define IRQ_IQ80321_INTA IRQ_IOP321_XINT0 +#define IRQ_IQ80321_INTB IRQ_IOP321_XINT1 +#define IRQ_IQ80321_INTC IRQ_IOP321_XINT2 +#define IRQ_IQ80321_INTD IRQ_IOP321_XINT3 + +/* + * Interrupts on the IQ31244 board + */ + +/* + * On board devices + */ +#define IRQ_IQ31244_UART IRQ_IOP321_XINT1 +#define IRQ_IQ31244_I82546 IRQ_IOP321_XINT0 +#define IRQ_IQ31244_SATA IRQ_IOP321_XINT2 +#define IRQ_IQ31244_PCIX_SLOT IRQ_IOP321_XINT3 + +/* + * PCI interrupts + */ +#define IRQ_IQ31244_INTA IRQ_IOP321_XINT0 +#define IRQ_IQ31244_INTB IRQ_IOP321_XINT1 +#define IRQ_IQ31244_INTC IRQ_IOP321_XINT2 +#define IRQ_IQ31244_INTD IRQ_IOP321_XINT3 + +#endif // _IRQ_H_ diff --git a/include/asm-arm/arch-iop32x/memory.h b/include/asm-arm/arch-iop32x/memory.h new file mode 100644 index 000000000000..b4073f15b405 --- /dev/null +++ b/include/asm-arm/arch-iop32x/memory.h @@ -0,0 +1,27 @@ +/* + * linux/include/asm-arm/arch-iop32x/memory.h + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#include + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0xa0000000) + +/* + * Virtual view <-> PCI DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ + +#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP321_IATVR2)) | ((*IOP321_IABAR2) & 0xfffffff0)) +#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP321_IALR2)) | ( *IOP321_IATVR2))) + + +#endif diff --git a/include/asm-arm/arch-iop32x/system.h b/include/asm-arm/arch-iop32x/system.h new file mode 100644 index 000000000000..d4c8d691e1b0 --- /dev/null +++ b/include/asm-arm/arch-iop32x/system.h @@ -0,0 +1,29 @@ +/* + * linux/include/asm-arm/arch-iop32x/system.h + * + * Copyright (C) 2001 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + + +static inline void arch_reset(char mode) +{ + *IOP321_PCSR = 0x30; + + if ( 1 && mode == 's') { + /* Jump into ROM at address 0 */ + cpu_reset(0); + } else { + /* No on-chip reset capability */ + cpu_reset(0); + } +} + diff --git a/include/asm-arm/arch-iop32x/timex.h b/include/asm-arm/arch-iop32x/timex.h new file mode 100644 index 000000000000..08badde2e820 --- /dev/null +++ b/include/asm-arm/arch-iop32x/timex.h @@ -0,0 +1,8 @@ +/* + * linux/include/asm-arm/arch-iop32x/timex.h + * + * IOP3xx architecture timex specifications + */ +#include + +#define CLOCK_TICK_RATE IOP321_TICK_RATE diff --git a/include/asm-arm/arch-iop32x/uncompress.h b/include/asm-arm/arch-iop32x/uncompress.h new file mode 100644 index 000000000000..4a85f20c796f --- /dev/null +++ b/include/asm-arm/arch-iop32x/uncompress.h @@ -0,0 +1,38 @@ +/* + * linux/include/asm-arm/arch-iop32x/uncompress.h + */ +#include +#include +#include +#include + +static volatile u8 *uart_base; + +#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE) + +static inline void putc(char c) +{ + while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE) + barrier(); + *uart_base = c; +} + +static inline void flush(void) +{ +} + +static __inline__ void __arch_decomp_setup(unsigned long arch_id) +{ + if (machine_is_iq80321()) + uart_base = (volatile u8 *)IQ80321_UART; + else if (machine_is_iq31244()) + uart_base = (volatile u8 *)IQ31244_UART; + else + uart_base = (volatile u8 *)0xfe800000; +} + +/* + * nothing to do + */ +#define arch_decomp_setup() __arch_decomp_setup(arch_id) +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-iop32x/vmalloc.h b/include/asm-arm/arch-iop32x/vmalloc.h new file mode 100644 index 000000000000..8492e1708a63 --- /dev/null +++ b/include/asm-arm/arch-iop32x/vmalloc.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-iop32x/vmalloc.h + */ + +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +//#define VMALLOC_END (0xe8000000) +/* increase usable physical RAM to ~992M per RMK */ +#define VMALLOC_END (0xfe000000) + diff --git a/include/asm-arm/arch-iop33x/debug-macro.S b/include/asm-arm/arch-iop33x/debug-macro.S new file mode 100644 index 000000000000..b647edff475d --- /dev/null +++ b/include/asm-arm/arch-iop33x/debug-macro.S @@ -0,0 +1,24 @@ +/* linux/include/asm-arm/arch-iop33x/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ mmu enabled? + moveq \rx, #0xff000000 @ physical + movne \rx, #0xfe000000 @ virtual + orr \rx, \rx, #0x00ff0000 + orr \rx, \rx, #0x0000f700 + .endm + +#define UART_SHIFT 2 +#include diff --git a/include/asm-arm/arch-iop33x/dma.h b/include/asm-arm/arch-iop33x/dma.h new file mode 100644 index 000000000000..d577ca59f4b0 --- /dev/null +++ b/include/asm-arm/arch-iop33x/dma.h @@ -0,0 +1,9 @@ +/* + * linux/include/asm-arm/arch-iop33x/dma.h + * + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ diff --git a/include/asm-arm/arch-iop33x/entry-macro.S b/include/asm-arm/arch-iop33x/entry-macro.S new file mode 100644 index 000000000000..980ec9b1ac83 --- /dev/null +++ b/include/asm-arm/arch-iop33x/entry-macro.S @@ -0,0 +1,34 @@ +/* + * include/asm-arm/arch-iop33x/entry-macro.S + * + * Low-level IRQ helper macros for IOP33x-based platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include + + .macro disable_fiq + .endm + + /* + * Note: only deal with normal interrupts, not FIQ + */ + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + mov \irqnr, #0 + mrc p6, 0, \irqstat, c4, c0, 0 @ Read IINTSRC0 + cmp \irqstat, #0 + bne 1002f + mrc p6, 0, \irqstat, c5, c0, 0 @ Read IINTSRC1 + cmp \irqstat, #0 + beq 1001f + clz \irqnr, \irqstat + rsbs \irqnr,\irqnr,#31 @ recommend by RMK + add \irqnr,\irqnr,#IRQ_IOP331_XINT8 + b 1001f +1002: clz \irqnr, \irqstat + rsbs \irqnr,\irqnr,#31 @ recommend by RMK + add \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT +1001: + .endm diff --git a/include/asm-arm/arch-iop33x/hardware.h b/include/asm-arm/arch-iop33x/hardware.h new file mode 100644 index 000000000000..4a457084c5c6 --- /dev/null +++ b/include/asm-arm/arch-iop33x/hardware.h @@ -0,0 +1,54 @@ +/* + * linux/include/asm-arm/arch-iop33x/hardware.h + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include + +/* + * Note about PCI IO space mappings + * + * To make IO space accesses efficient, we store virtual addresses in + * the IO resources. + * + * The PCI IO space is located at virtual 0xfe000000 from physical + * 0x90000000. The PCI BARs must be programmed with physical addresses, + * but when we read them, we convert them to virtual addresses. See + * arch/arm/mach-iop33x/pci.c + */ + +#define pcibios_assign_all_busses() 1 + + +/* + * The min PCI I/O and MEM space are dependent on what specific + * chipset/platform we are running on, so instead of hardcoding with + * #ifdefs, we just fill these in the platform level PCI init code. + */ +#ifndef __ASSEMBLY__ +extern unsigned long iop3xx_pcibios_min_io; +extern unsigned long iop3xx_pcibios_min_mem; + +extern unsigned int processor_id; +#endif + +/* + * We just set these to zero since they are really bogus anyways + */ +#define PCIBIOS_MIN_IO (iop3xx_pcibios_min_io) +#define PCIBIOS_MIN_MEM (iop3xx_pcibios_min_mem) + +/* + * Generic chipset bits + * + */ +#include "iop331.h" + +/* + * Board specific bits + */ +#include "iq80331.h" +#include "iq80332.h" + +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-iop33x/io.h b/include/asm-arm/arch-iop33x/io.h new file mode 100644 index 000000000000..a9949d5d4953 --- /dev/null +++ b/include/asm-arm/arch-iop33x/io.h @@ -0,0 +1,21 @@ +/* + * linux/include/asm-arm/arch-iop33x/io.h + * + * Copyright (C) 2001 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#include + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(p) ((void __iomem *)(p)) +#define __mem_pci(a) (a) + +#endif diff --git a/include/asm-arm/arch-iop33x/iop331.h b/include/asm-arm/arch-iop33x/iop331.h new file mode 100644 index 000000000000..780b707edb1e --- /dev/null +++ b/include/asm-arm/arch-iop33x/iop331.h @@ -0,0 +1,358 @@ +/* + * linux/include/asm/arch-iop33x/iop331.h + * + * Intel IOP331 Chip definitions + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2003, 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _IOP331_HW_H_ +#define _IOP331_HW_H_ + + +/* + * This is needed for mixed drivers that need to work on all + * IOP3xx variants but behave slightly differently on each. + */ +#ifndef __ASSEMBLY__ +#define iop_is_331() 1 +#endif + +/* + * IOP331 I/O and Mem space regions for PCI autoconfiguration + */ +#define IOP331_PCI_IO_WINDOW_SIZE 0x00010000 +#define IOP331_PCI_LOWER_IO_PA 0x90000000 +#define IOP331_PCI_LOWER_IO_VA 0xfe000000 +#define IOP331_PCI_LOWER_IO_BA (*IOP331_OIOWTVR) +#define IOP331_PCI_UPPER_IO_PA (IOP331_PCI_LOWER_IO_PA + IOP331_PCI_IO_WINDOW_SIZE - 1) +#define IOP331_PCI_UPPER_IO_VA (IOP331_PCI_LOWER_IO_VA + IOP331_PCI_IO_WINDOW_SIZE - 1) +#define IOP331_PCI_UPPER_IO_BA (IOP331_PCI_LOWER_IO_BA + IOP331_PCI_IO_WINDOW_SIZE - 1) +#define IOP331_PCI_IO_OFFSET (IOP331_PCI_LOWER_IO_VA - IOP331_PCI_LOWER_IO_BA) + +/* this can be 128M if OMWTVR1 is set */ +#define IOP331_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */ +/* #define IOP331_PCI_MEM_WINDOW_SIZE (~*IOP331_IALR1 + 1) */ +#define IOP331_PCI_LOWER_MEM_PA 0x80000000 +#define IOP331_PCI_LOWER_MEM_BA (*IOP331_OMWTVR0) +#define IOP331_PCI_UPPER_MEM_PA (IOP331_PCI_LOWER_MEM_PA + IOP331_PCI_MEM_WINDOW_SIZE - 1) +#define IOP331_PCI_UPPER_MEM_BA (IOP331_PCI_LOWER_MEM_BA + IOP331_PCI_MEM_WINDOW_SIZE - 1) +#define IOP331_PCI_MEM_OFFSET (IOP331_PCI_LOWER_MEM_PA - IOP331_PCI_LOWER_MEM_BA) + +/* + * IOP331 chipset registers + */ +#define IOP331_VIRT_MEM_BASE 0xfeffe000 /* chip virtual mem address*/ +#define IOP331_PHYS_MEM_BASE 0xffffe000 /* chip physical memory address */ +#define IOP331_REG_ADDR(reg) (IOP331_VIRT_MEM_BASE | (reg)) + +/* Reserved 0x00000000 through 0x000000FF */ + +/* Address Translation Unit 0x00000100 through 0x000001FF */ +#define IOP331_ATUVID (volatile u16 *)IOP331_REG_ADDR(0x00000100) +#define IOP331_ATUDID (volatile u16 *)IOP331_REG_ADDR(0x00000102) +#define IOP331_ATUCMD (volatile u16 *)IOP331_REG_ADDR(0x00000104) +#define IOP331_ATUSR (volatile u16 *)IOP331_REG_ADDR(0x00000106) +#define IOP331_ATURID (volatile u8 *)IOP331_REG_ADDR(0x00000108) +#define IOP331_ATUCCR (volatile u32 *)IOP331_REG_ADDR(0x00000109) +#define IOP331_ATUCLSR (volatile u8 *)IOP331_REG_ADDR(0x0000010C) +#define IOP331_ATULT (volatile u8 *)IOP331_REG_ADDR(0x0000010D) +#define IOP331_ATUHTR (volatile u8 *)IOP331_REG_ADDR(0x0000010E) +#define IOP331_ATUBIST (volatile u8 *)IOP331_REG_ADDR(0x0000010F) +#define IOP331_IABAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000110) +#define IOP331_IAUBAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000114) +#define IOP331_IABAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000118) +#define IOP331_IAUBAR1 (volatile u32 *)IOP331_REG_ADDR(0x0000011C) +#define IOP331_IABAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000120) +#define IOP331_IAUBAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000124) +#define IOP331_ASVIR (volatile u16 *)IOP331_REG_ADDR(0x0000012C) +#define IOP331_ASIR (volatile u16 *)IOP331_REG_ADDR(0x0000012E) +#define IOP331_ERBAR (volatile u32 *)IOP331_REG_ADDR(0x00000130) +#define IOP331_ATU_CAPPTR (volatile u32 *)IOP331_REG_ADDR(0x00000134) +/* Reserved 0x00000138 through 0x0000013B */ +#define IOP331_ATUILR (volatile u8 *)IOP331_REG_ADDR(0x0000013C) +#define IOP331_ATUIPR (volatile u8 *)IOP331_REG_ADDR(0x0000013D) +#define IOP331_ATUMGNT (volatile u8 *)IOP331_REG_ADDR(0x0000013E) +#define IOP331_ATUMLAT (volatile u8 *)IOP331_REG_ADDR(0x0000013F) +#define IOP331_IALR0 (volatile u32 *)IOP331_REG_ADDR(0x00000140) +#define IOP331_IATVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000144) +#define IOP331_ERLR (volatile u32 *)IOP331_REG_ADDR(0x00000148) +#define IOP331_ERTVR (volatile u32 *)IOP331_REG_ADDR(0x0000014C) +#define IOP331_IALR1 (volatile u32 *)IOP331_REG_ADDR(0x00000150) +#define IOP331_IALR2 (volatile u32 *)IOP331_REG_ADDR(0x00000154) +#define IOP331_IATVR2 (volatile u32 *)IOP331_REG_ADDR(0x00000158) +#define IOP331_OIOWTVR (volatile u32 *)IOP331_REG_ADDR(0x0000015C) +#define IOP331_OMWTVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000160) +#define IOP331_OUMWTVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000164) +#define IOP331_OMWTVR1 (volatile u32 *)IOP331_REG_ADDR(0x00000168) +#define IOP331_OUMWTVR1 (volatile u32 *)IOP331_REG_ADDR(0x0000016C) +/* Reserved 0x00000170 through 0x00000177*/ +#define IOP331_OUDWTVR (volatile u32 *)IOP331_REG_ADDR(0x00000178) +/* Reserved 0x0000017C through 0x0000017F*/ +#define IOP331_ATUCR (volatile u32 *)IOP331_REG_ADDR(0x00000180) +#define IOP331_PCSR (volatile u32 *)IOP331_REG_ADDR(0x00000184) +#define IOP331_ATUISR (volatile u32 *)IOP331_REG_ADDR(0x00000188) +#define IOP331_ATUIMR (volatile u32 *)IOP331_REG_ADDR(0x0000018C) +#define IOP331_IABAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000190) +#define IOP331_IAUBAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000194) +#define IOP331_IALR3 (volatile u32 *)IOP331_REG_ADDR(0x00000198) +#define IOP331_IATVR3 (volatile u32 *)IOP331_REG_ADDR(0x0000019C) +/* Reserved 0x000001A0 through 0x000001A3*/ +#define IOP331_OCCAR (volatile u32 *)IOP331_REG_ADDR(0x000001A4) +/* Reserved 0x000001A8 through 0x000001AB*/ +#define IOP331_OCCDR (volatile u32 *)IOP331_REG_ADDR(0x000001AC) +/* Reserved 0x000001B0 through 0x000001BB*/ +#define IOP331_VPDCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001B8) +#define IOP331_VPDNXTP (volatile u8 *)IOP331_REG_ADDR(0x000001B9) +#define IOP331_VPDAR (volatile u16 *)IOP331_REG_ADDR(0x000001BA) +#define IOP331_VPDDR (volatile u32 *)IOP331_REG_ADDR(0x000001BC) +#define IOP331_PMCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001C0) +#define IOP331_PMNEXT (volatile u8 *)IOP331_REG_ADDR(0x000001C1) +#define IOP331_APMCR (volatile u16 *)IOP331_REG_ADDR(0x000001C2) +#define IOP331_APMCSR (volatile u16 *)IOP331_REG_ADDR(0x000001C4) +/* Reserved 0x000001C6 through 0x000001CF */ +#define IOP331_MSICAPID (volatile u8 *)IOP331_REG_ADDR(0x000001D0) +#define IOP331_MSINXTP (volatile u8 *)IOP331_REG_ADDR(0x000001D1) +#define IOP331_MSIMCR (volatile u16 *)IOP331_REG_ADDR(0x000001D2) +#define IOP331_MSIMAR (volatile u32 *)IOP331_REG_ADDR(0x000001D4) +#define IOP331_MSIMUAR (volatile u32 *)IOP331_REG_ADDR(0x000001D8) +#define IOP331_MSIMDR (volatile u32 *)IOP331_REG_ADDR(0x000001DC) +#define IOP331_PCIXCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001E0) +#define IOP331_PCIXNEXT (volatile u8 *)IOP331_REG_ADDR(0x000001E1) +#define IOP331_PCIXCMD (volatile u16 *)IOP331_REG_ADDR(0x000001E2) +#define IOP331_PCIXSR (volatile u32 *)IOP331_REG_ADDR(0x000001E4) +#define IOP331_PCIIRSR (volatile u32 *)IOP331_REG_ADDR(0x000001EC) + +/* Messaging Unit 0x00000300 through 0x000003FF */ + +/* Reserved 0x00000300 through 0x0000030c */ +#define IOP331_IMR0 (volatile u32 *)IOP331_REG_ADDR(0x00000310) +#define IOP331_IMR1 (volatile u32 *)IOP331_REG_ADDR(0x00000314) +#define IOP331_OMR0 (volatile u32 *)IOP331_REG_ADDR(0x00000318) +#define IOP331_OMR1 (volatile u32 *)IOP331_REG_ADDR(0x0000031C) +#define IOP331_IDR (volatile u32 *)IOP331_REG_ADDR(0x00000320) +#define IOP331_IISR (volatile u32 *)IOP331_REG_ADDR(0x00000324) +#define IOP331_IIMR (volatile u32 *)IOP331_REG_ADDR(0x00000328) +#define IOP331_ODR (volatile u32 *)IOP331_REG_ADDR(0x0000032C) +#define IOP331_OISR (volatile u32 *)IOP331_REG_ADDR(0x00000330) +#define IOP331_OIMR (volatile u32 *)IOP331_REG_ADDR(0x00000334) +/* Reserved 0x00000338 through 0x0000034F */ +#define IOP331_MUCR (volatile u32 *)IOP331_REG_ADDR(0x00000350) +#define IOP331_QBAR (volatile u32 *)IOP331_REG_ADDR(0x00000354) +/* Reserved 0x00000358 through 0x0000035C */ +#define IOP331_IFHPR (volatile u32 *)IOP331_REG_ADDR(0x00000360) +#define IOP331_IFTPR (volatile u32 *)IOP331_REG_ADDR(0x00000364) +#define IOP331_IPHPR (volatile u32 *)IOP331_REG_ADDR(0x00000368) +#define IOP331_IPTPR (volatile u32 *)IOP331_REG_ADDR(0x0000036C) +#define IOP331_OFHPR (volatile u32 *)IOP331_REG_ADDR(0x00000370) +#define IOP331_OFTPR (volatile u32 *)IOP331_REG_ADDR(0x00000374) +#define IOP331_OPHPR (volatile u32 *)IOP331_REG_ADDR(0x00000378) +#define IOP331_OPTPR (volatile u32 *)IOP331_REG_ADDR(0x0000037C) +#define IOP331_IAR (volatile u32 *)IOP331_REG_ADDR(0x00000380) +/* Reserved 0x00000384 through 0x000003FF */ + +/* DMA Controller 0x00000400 through 0x000004FF */ +#define IOP331_DMA0_CCR (volatile u32 *)IOP331_REG_ADDR(0x00000400) +#define IOP331_DMA0_CSR (volatile u32 *)IOP331_REG_ADDR(0x00000404) +#define IOP331_DMA0_DAR (volatile u32 *)IOP331_REG_ADDR(0x0000040C) +#define IOP331_DMA0_NDAR (volatile u32 *)IOP331_REG_ADDR(0x00000410) +#define IOP331_DMA0_PADR (volatile u32 *)IOP331_REG_ADDR(0x00000414) +#define IOP331_DMA0_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000418) +#define IOP331_DMA0_LADR (volatile u32 *)IOP331_REG_ADDR(0X0000041C) +#define IOP331_DMA0_BCR (volatile u32 *)IOP331_REG_ADDR(0x00000420) +#define IOP331_DMA0_DCR (volatile u32 *)IOP331_REG_ADDR(0x00000424) +/* Reserved 0x00000428 through 0x0000043C */ +#define IOP331_DMA1_CCR (volatile u32 *)IOP331_REG_ADDR(0x00000440) +#define IOP331_DMA1_CSR (volatile u32 *)IOP331_REG_ADDR(0x00000444) +#define IOP331_DMA1_DAR (volatile u32 *)IOP331_REG_ADDR(0x0000044C) +#define IOP331_DMA1_NDAR (volatile u32 *)IOP331_REG_ADDR(0x00000450) +#define IOP331_DMA1_PADR (volatile u32 *)IOP331_REG_ADDR(0x00000454) +#define IOP331_DMA1_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000458) +#define IOP331_DMA1_LADR (volatile u32 *)IOP331_REG_ADDR(0x0000045C) +#define IOP331_DMA1_BCR (volatile u32 *)IOP331_REG_ADDR(0x00000460) +#define IOP331_DMA1_DCR (volatile u32 *)IOP331_REG_ADDR(0x00000464) +/* Reserved 0x00000468 through 0x000004FF */ + +/* Memory controller 0x00000500 through 0x0005FF */ + +/* Peripheral bus interface unit 0x00000680 through 0x0006FF */ +#define IOP331_PBCR (volatile u32 *)IOP331_REG_ADDR(0x00000680) +#define IOP331_PBISR (volatile u32 *)IOP331_REG_ADDR(0x00000684) +#define IOP331_PBBAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000688) +#define IOP331_PBLR0 (volatile u32 *)IOP331_REG_ADDR(0x0000068C) +#define IOP331_PBBAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000690) +#define IOP331_PBLR1 (volatile u32 *)IOP331_REG_ADDR(0x00000694) +#define IOP331_PBBAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000698) +#define IOP331_PBLR2 (volatile u32 *)IOP331_REG_ADDR(0x0000069C) +#define IOP331_PBBAR3 (volatile u32 *)IOP331_REG_ADDR(0x000006A0) +#define IOP331_PBLR3 (volatile u32 *)IOP331_REG_ADDR(0x000006A4) +#define IOP331_PBBAR4 (volatile u32 *)IOP331_REG_ADDR(0x000006A8) +#define IOP331_PBLR4 (volatile u32 *)IOP331_REG_ADDR(0x000006AC) +#define IOP331_PBBAR5 (volatile u32 *)IOP331_REG_ADDR(0x000006B0) +#define IOP331_PBLR5 (volatile u32 *)IOP331_REG_ADDR(0x000006B4) +#define IOP331_PBDSCR (volatile u32 *)IOP331_REG_ADDR(0x000006B8) +/* Reserved 0x000006BC */ +#define IOP331_PMBR0 (volatile u32 *)IOP331_REG_ADDR(0x000006C0) +/* Reserved 0x000006C4 through 0x000006DC */ +#define IOP331_PMBR1 (volatile u32 *)IOP331_REG_ADDR(0x000006E0) +#define IOP331_PMBR2 (volatile u32 *)IOP331_REG_ADDR(0x000006E4) + +#define IOP331_PBCR_EN 0x1 + +#define IOP331_PBISR_BOOR_ERR 0x1 + + + +/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */ +/* Internal arbitration unit 0x00000780 through 0x0007BF */ + +/* Interrupt Controller */ +#define IOP331_INTCTL0 (volatile u32 *)IOP331_REG_ADDR(0x00000790) +#define IOP331_INTCTL1 (volatile u32 *)IOP331_REG_ADDR(0x00000794) +#define IOP331_INTSTR0 (volatile u32 *)IOP331_REG_ADDR(0x00000798) +#define IOP331_INTSTR1 (volatile u32 *)IOP331_REG_ADDR(0x0000079C) +#define IOP331_IINTSRC0 (volatile u32 *)IOP331_REG_ADDR(0x000007A0) +#define IOP331_IINTSRC1 (volatile u32 *)IOP331_REG_ADDR(0x000007A4) +#define IOP331_FINTSRC0 (volatile u32 *)IOP331_REG_ADDR(0x000007A8) +#define IOP331_FINTSRC1 (volatile u32 *)IOP331_REG_ADDR(0x000007AC) +#define IOP331_IPR0 (volatile u32 *)IOP331_REG_ADDR(0x000007B0) +#define IOP331_IPR1 (volatile u32 *)IOP331_REG_ADDR(0x000007B4) +#define IOP331_IPR2 (volatile u32 *)IOP331_REG_ADDR(0x000007B8) +#define IOP331_IPR3 (volatile u32 *)IOP331_REG_ADDR(0x000007BC) +#define IOP331_INTBASE (volatile u32 *)IOP331_REG_ADDR(0x000007C0) +#define IOP331_INTSIZE (volatile u32 *)IOP331_REG_ADDR(0x000007C4) +#define IOP331_IINTVEC (volatile u32 *)IOP331_REG_ADDR(0x000007C8) +#define IOP331_FINTVEC (volatile u32 *)IOP331_REG_ADDR(0x000007CC) + + +/* Timers */ + +#define IOP331_TU_TMR0 (volatile u32 *)IOP331_REG_ADDR(0x000007D0) +#define IOP331_TU_TMR1 (volatile u32 *)IOP331_REG_ADDR(0x000007D4) + +#define IOP331_TMR_TC 0x01 +#define IOP331_TMR_EN 0x02 +#define IOP331_TMR_RELOAD 0x04 +#define IOP331_TMR_PRIVILEGED 0x09 + +#define IOP331_TMR_RATIO_1_1 0x00 +#define IOP331_TMR_RATIO_4_1 0x10 +#define IOP331_TMR_RATIO_8_1 0x20 +#define IOP331_TMR_RATIO_16_1 0x30 + +#define IOP331_TU_TCR0 (volatile u32 *)IOP331_REG_ADDR(0x000007D8) +#define IOP331_TU_TCR1 (volatile u32 *)IOP331_REG_ADDR(0x000007DC) +#define IOP331_TU_TRR0 (volatile u32 *)IOP331_REG_ADDR(0x000007E0) +#define IOP331_TU_TRR1 (volatile u32 *)IOP331_REG_ADDR(0x000007E4) +#define IOP331_TU_TISR (volatile u32 *)IOP331_REG_ADDR(0x000007E8) +#define IOP331_TU_WDTCR (volatile u32 *)IOP331_REG_ADDR(0x000007EC) + +#if defined(CONFIG_ARCH_IOP33X) +#define IOP331_TICK_RATE 266000000 /* 266 MHz IB clock */ +#endif + +#if defined(CONFIG_IOP331_STEPD) || defined(CONFIG_ARCH_IQ80333) +#undef IOP331_TICK_RATE +#define IOP331_TICK_RATE 333000000 /* 333 Mhz IB clock */ +#endif + +/* Application accelerator unit 0x00000800 - 0x000008FF */ +#define IOP331_AAU_ACR (volatile u32 *)IOP331_REG_ADDR(0x00000800) +#define IOP331_AAU_ASR (volatile u32 *)IOP331_REG_ADDR(0x00000804) +#define IOP331_AAU_ADAR (volatile u32 *)IOP331_REG_ADDR(0x00000808) +#define IOP331_AAU_ANDAR (volatile u32 *)IOP331_REG_ADDR(0x0000080C) +#define IOP331_AAU_SAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000810) +#define IOP331_AAU_SAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000814) +#define IOP331_AAU_SAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000818) +#define IOP331_AAU_SAR4 (volatile u32 *)IOP331_REG_ADDR(0x0000081C) +#define IOP331_AAU_SAR5 (volatile u32 *)IOP331_REG_ADDR(0x0000082C) +#define IOP331_AAU_SAR6 (volatile u32 *)IOP331_REG_ADDR(0x00000830) +#define IOP331_AAU_SAR7 (volatile u32 *)IOP331_REG_ADDR(0x00000834) +#define IOP331_AAU_SAR8 (volatile u32 *)IOP331_REG_ADDR(0x00000838) +#define IOP331_AAU_SAR9 (volatile u32 *)IOP331_REG_ADDR(0x00000840) +#define IOP331_AAU_SAR10 (volatile u32 *)IOP331_REG_ADDR(0x00000844) +#define IOP331_AAU_SAR11 (volatile u32 *)IOP331_REG_ADDR(0x00000848) +#define IOP331_AAU_SAR12 (volatile u32 *)IOP331_REG_ADDR(0x0000084C) +#define IOP331_AAU_SAR13 (volatile u32 *)IOP331_REG_ADDR(0x00000850) +#define IOP331_AAU_SAR14 (volatile u32 *)IOP331_REG_ADDR(0x00000854) +#define IOP331_AAU_SAR15 (volatile u32 *)IOP331_REG_ADDR(0x00000858) +#define IOP331_AAU_SAR16 (volatile u32 *)IOP331_REG_ADDR(0x0000085C) +#define IOP331_AAU_SAR17 (volatile u32 *)IOP331_REG_ADDR(0x00000864) +#define IOP331_AAU_SAR18 (volatile u32 *)IOP331_REG_ADDR(0x00000868) +#define IOP331_AAU_SAR19 (volatile u32 *)IOP331_REG_ADDR(0x0000086C) +#define IOP331_AAU_SAR20 (volatile u32 *)IOP331_REG_ADDR(0x00000870) +#define IOP331_AAU_SAR21 (volatile u32 *)IOP331_REG_ADDR(0x00000874) +#define IOP331_AAU_SAR22 (volatile u32 *)IOP331_REG_ADDR(0x00000878) +#define IOP331_AAU_SAR23 (volatile u32 *)IOP331_REG_ADDR(0x0000087C) +#define IOP331_AAU_SAR24 (volatile u32 *)IOP331_REG_ADDR(0x00000880) +#define IOP331_AAU_SAR25 (volatile u32 *)IOP331_REG_ADDR(0x00000888) +#define IOP331_AAU_SAR26 (volatile u32 *)IOP331_REG_ADDR(0x0000088C) +#define IOP331_AAU_SAR27 (volatile u32 *)IOP331_REG_ADDR(0x00000890) +#define IOP331_AAU_SAR28 (volatile u32 *)IOP331_REG_ADDR(0x00000894) +#define IOP331_AAU_SAR29 (volatile u32 *)IOP331_REG_ADDR(0x00000898) +#define IOP331_AAU_SAR30 (volatile u32 *)IOP331_REG_ADDR(0x0000089C) +#define IOP331_AAU_SAR31 (volatile u32 *)IOP331_REG_ADDR(0x000008A0) +#define IOP331_AAU_SAR32 (volatile u32 *)IOP331_REG_ADDR(0x000008A4) +#define IOP331_AAU_DAR (volatile u32 *)IOP331_REG_ADDR(0x00000820) +#define IOP331_AAU_ABCR (volatile u32 *)IOP331_REG_ADDR(0x00000824) +#define IOP331_AAU_ADCR (volatile u32 *)IOP331_REG_ADDR(0x00000828) +#define IOP331_AAU_EDCR0 (volatile u32 *)IOP331_REG_ADDR(0x0000083c) +#define IOP331_AAU_EDCR1 (volatile u32 *)IOP331_REG_ADDR(0x00000860) +#define IOP331_AAU_EDCR2 (volatile u32 *)IOP331_REG_ADDR(0x00000884) + + +#define IOP331_SPDSCR (volatile u32 *)IOP331_REG_ADDR(0x000015C0) +#define IOP331_PPDSCR (volatile u32 *)IOP331_REG_ADDR(0x000015C8) +/* SSP serial port unit 0x00001600 - 0x0000167F */ + +/* I2C bus interface unit 0x00001680 - 0x000016FF */ +/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */ + +#define IOP331_ICR0 (volatile u32 *)IOP331_REG_ADDR(0x00001680) +#define IOP331_ISR0 (volatile u32 *)IOP331_REG_ADDR(0x00001684) +#define IOP331_ISAR0 (volatile u32 *)IOP331_REG_ADDR(0x00001688) +#define IOP331_IDBR0 (volatile u32 *)IOP331_REG_ADDR(0x0000168C) +/* Reserved 0x00001690 */ +#define IOP331_IBMR0 (volatile u32 *)IOP331_REG_ADDR(0x00001694) +/* Reserved 0x00001698 */ +/* Reserved 0x0000169C */ +#define IOP331_ICR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A0) +#define IOP331_ISR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A4) +#define IOP331_ISAR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A8) +#define IOP331_IDBR1 (volatile u32 *)IOP331_REG_ADDR(0x000016AC) +#define IOP331_IBMR1 (volatile u32 *)IOP331_REG_ADDR(0x000016B4) +/* Reserved 0x000016B8 through 0x000016FF */ + +/* 0x00001700 through 0x0000172C UART 0 */ + +/* Reserved 0x00001730 through 0x0000173F */ + +/* 0x00001740 through 0x0000176C UART 1 */ + +#define IOP331_UART0_PHYS (IOP331_PHYS_MEM_BASE | 0x00001700) /* UART #1 physical */ +#define IOP331_UART1_PHYS (IOP331_PHYS_MEM_BASE | 0x00001740) /* UART #2 physical */ +#define IOP331_UART0_VIRT (IOP331_VIRT_MEM_BASE | 0x00001700) /* UART #1 virtual addr */ +#define IOP331_UART1_VIRT (IOP331_VIRT_MEM_BASE | 0x00001740) /* UART #2 virtual addr */ + +/* Reserved 0x00001770 through 0x0000177F */ + +/* General Purpose I/O Registers */ +#define IOP331_GPOE (volatile u32 *)IOP331_REG_ADDR(0x00001780) +#define IOP331_GPID (volatile u32 *)IOP331_REG_ADDR(0x00001784) +#define IOP331_GPOD (volatile u32 *)IOP331_REG_ADDR(0x00001788) + +/* Reserved 0x0000178c through 0x000019ff */ + + +#ifndef __ASSEMBLY__ +extern void iop331_map_io(void); +extern void iop331_init_irq(void); +extern void iop331_time_init(void); +#endif + +#endif // _IOP331_HW_H_ diff --git a/include/asm-arm/arch-iop33x/iq80331.h b/include/asm-arm/arch-iop33x/iq80331.h new file mode 100644 index 000000000000..bda7ab6d55cf --- /dev/null +++ b/include/asm-arm/arch-iop33x/iq80331.h @@ -0,0 +1,23 @@ +/* + * linux/include/asm/arch-iop33x/iq80331.h + * + * Intel IQ80331 evaluation board registers + */ + +#ifndef _IQ80331_H_ +#define _IQ80331_H_ + +#define IQ80331_FLASHBASE 0xc0000000 /* Flash */ +#define IQ80331_FLASHSIZE 0x00800000 +#define IQ80331_FLASHWIDTH 1 + +#define IQ80331_7SEG_1 0xce840000 /* 7-Segment MSB */ +#define IQ80331_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */ +#define IQ80331_ROTARY_SW 0xce8d0000 /* Rotary Switch */ +#define IQ80331_BATT_STAT 0xce8f0000 /* Battery Status */ + +#ifndef __ASSEMBLY__ +extern void iq80331_map_io(void); +#endif + +#endif // _IQ80331_H_ diff --git a/include/asm-arm/arch-iop33x/iq80332.h b/include/asm-arm/arch-iop33x/iq80332.h new file mode 100644 index 000000000000..f728e04378ab --- /dev/null +++ b/include/asm-arm/arch-iop33x/iq80332.h @@ -0,0 +1,23 @@ +/* + * linux/include/asm/arch-iop33x/iq80332.h + * + * Intel IQ80332 evaluation board registers + */ + +#ifndef _IQ80332_H_ +#define _IQ80332_H_ + +#define IQ80332_FLASHBASE 0xc0000000 /* Flash */ +#define IQ80332_FLASHSIZE 0x00800000 +#define IQ80332_FLASHWIDTH 1 + +#define IQ80332_7SEG_1 0xce840000 /* 7-Segment MSB */ +#define IQ80332_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */ +#define IQ80332_ROTARY_SW 0xce8d0000 /* Rotary Switch */ +#define IQ80332_BATT_STAT 0xce8f0000 /* Battery Status */ + +#ifndef __ASSEMBLY__ +extern void iq80332_map_io(void); +#endif + +#endif // _IQ80332_H_ diff --git a/include/asm-arm/arch-iop33x/irqs.h b/include/asm-arm/arch-iop33x/irqs.h new file mode 100644 index 000000000000..45856a12815a --- /dev/null +++ b/include/asm-arm/arch-iop33x/irqs.h @@ -0,0 +1,130 @@ +/* + * linux/include/asm-arm/arch-iop33x/irqs.h + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright: (C) 2003 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef _IRQS_H_ +#define _IRQS_H_ + +/* + * IOP80331 chipset interrupts + */ +#define IOP331_IRQ_OFS 0 +#define IOP331_IRQ(x) (IOP331_IRQ_OFS + (x)) + +/* + * On IRQ or FIQ register + */ +#define IRQ_IOP331_DMA0_EOT IOP331_IRQ(0) +#define IRQ_IOP331_DMA0_EOC IOP331_IRQ(1) +#define IRQ_IOP331_DMA1_EOT IOP331_IRQ(2) +#define IRQ_IOP331_DMA1_EOC IOP331_IRQ(3) +#define IRQ_IOP331_RSVD_4 IOP331_IRQ(4) +#define IRQ_IOP331_RSVD_5 IOP331_IRQ(5) +#define IRQ_IOP331_AA_EOT IOP331_IRQ(6) +#define IRQ_IOP331_AA_EOC IOP331_IRQ(7) +#define IRQ_IOP331_TIMER0 IOP331_IRQ(8) +#define IRQ_IOP331_TIMER1 IOP331_IRQ(9) +#define IRQ_IOP331_I2C_0 IOP331_IRQ(10) +#define IRQ_IOP331_I2C_1 IOP331_IRQ(11) +#define IRQ_IOP331_MSG IOP331_IRQ(12) +#define IRQ_IOP331_MSGIBQ IOP331_IRQ(13) +#define IRQ_IOP331_ATU_BIST IOP331_IRQ(14) +#define IRQ_IOP331_PERFMON IOP331_IRQ(15) +#define IRQ_IOP331_CORE_PMU IOP331_IRQ(16) +#define IRQ_IOP331_RSVD_17 IOP331_IRQ(17) +#define IRQ_IOP331_RSVD_18 IOP331_IRQ(18) +#define IRQ_IOP331_RSVD_19 IOP331_IRQ(19) +#define IRQ_IOP331_RSVD_20 IOP331_IRQ(20) +#define IRQ_IOP331_RSVD_21 IOP331_IRQ(21) +#define IRQ_IOP331_RSVD_22 IOP331_IRQ(22) +#define IRQ_IOP331_RSVD_23 IOP331_IRQ(23) +#define IRQ_IOP331_XINT0 IOP331_IRQ(24) +#define IRQ_IOP331_XINT1 IOP331_IRQ(25) +#define IRQ_IOP331_XINT2 IOP331_IRQ(26) +#define IRQ_IOP331_XINT3 IOP331_IRQ(27) +#define IRQ_IOP331_RSVD_28 IOP331_IRQ(28) +#define IRQ_IOP331_RSVD_29 IOP331_IRQ(29) +#define IRQ_IOP331_RSVD_30 IOP331_IRQ(30) +#define IRQ_IOP331_RSVD_31 IOP331_IRQ(31) +#define IRQ_IOP331_XINT8 IOP331_IRQ(32) // 0 +#define IRQ_IOP331_XINT9 IOP331_IRQ(33) // 1 +#define IRQ_IOP331_XINT10 IOP331_IRQ(34) // 2 +#define IRQ_IOP331_XINT11 IOP331_IRQ(35) // 3 +#define IRQ_IOP331_XINT12 IOP331_IRQ(36) // 4 +#define IRQ_IOP331_XINT13 IOP331_IRQ(37) // 5 +#define IRQ_IOP331_XINT14 IOP331_IRQ(38) // 6 +#define IRQ_IOP331_XINT15 IOP331_IRQ(39) // 7 +#define IRQ_IOP331_RSVD_40 IOP331_IRQ(40) // 8 +#define IRQ_IOP331_RSVD_41 IOP331_IRQ(41) // 9 +#define IRQ_IOP331_RSVD_42 IOP331_IRQ(42) // 10 +#define IRQ_IOP331_RSVD_43 IOP331_IRQ(43) // 11 +#define IRQ_IOP331_RSVD_44 IOP331_IRQ(44) // 12 +#define IRQ_IOP331_RSVD_45 IOP331_IRQ(45) // 13 +#define IRQ_IOP331_RSVD_46 IOP331_IRQ(46) // 14 +#define IRQ_IOP331_RSVD_47 IOP331_IRQ(47) // 15 +#define IRQ_IOP331_RSVD_48 IOP331_IRQ(48) // 16 +#define IRQ_IOP331_RSVD_49 IOP331_IRQ(49) // 17 +#define IRQ_IOP331_RSVD_50 IOP331_IRQ(50) // 18 +#define IRQ_IOP331_UART0 IOP331_IRQ(51) // 19 +#define IRQ_IOP331_UART1 IOP331_IRQ(52) // 20 +#define IRQ_IOP331_PBIE IOP331_IRQ(53) // 21 +#define IRQ_IOP331_ATU_CRW IOP331_IRQ(54) // 22 +#define IRQ_IOP331_ATU_ERR IOP331_IRQ(55) // 23 +#define IRQ_IOP331_MCU_ERR IOP331_IRQ(56) // 24 +#define IRQ_IOP331_DMA0_ERR IOP331_IRQ(57) // 25 +#define IRQ_IOP331_DMA1_ERR IOP331_IRQ(58) // 26 +#define IRQ_IOP331_RSVD_59 IOP331_IRQ(59) // 27 +#define IRQ_IOP331_AA_ERR IOP331_IRQ(60) // 28 +#define IRQ_IOP331_RSVD_61 IOP331_IRQ(61) // 29 +#define IRQ_IOP331_MSG_ERR IOP331_IRQ(62) // 30 +#define IRQ_IOP331_HPI IOP331_IRQ(63) // 31 + +#define NR_IRQS (IOP331_IRQ(63) + 1) + + +/* + * Interrupts available on the IQ80331 board + */ + +/* + * On board devices + */ +#define IRQ_IQ80331_I82544 IRQ_IOP331_XINT0 +#define IRQ_IQ80331_UART0 IRQ_IOP331_UART0 +#define IRQ_IQ80331_UART1 IRQ_IOP331_UART1 + +/* + * PCI interrupts + */ +#define IRQ_IQ80331_INTA IRQ_IOP331_XINT0 +#define IRQ_IQ80331_INTB IRQ_IOP331_XINT1 +#define IRQ_IQ80331_INTC IRQ_IOP331_XINT2 +#define IRQ_IQ80331_INTD IRQ_IOP331_XINT3 + +/* + * Interrupts available on the IQ80332 board + */ + +/* + * On board devices + */ +#define IRQ_IQ80332_I82544 IRQ_IOP331_XINT0 +#define IRQ_IQ80332_UART0 IRQ_IOP331_UART0 +#define IRQ_IQ80332_UART1 IRQ_IOP331_UART1 + +/* + * PCI interrupts + */ +#define IRQ_IQ80332_INTA IRQ_IOP331_XINT0 +#define IRQ_IQ80332_INTB IRQ_IOP331_XINT1 +#define IRQ_IQ80332_INTC IRQ_IOP331_XINT2 +#define IRQ_IQ80332_INTD IRQ_IOP331_XINT3 + +#endif // _IRQ_H_ diff --git a/include/asm-arm/arch-iop33x/memory.h b/include/asm-arm/arch-iop33x/memory.h new file mode 100644 index 000000000000..5e47164934ce --- /dev/null +++ b/include/asm-arm/arch-iop33x/memory.h @@ -0,0 +1,26 @@ +/* + * linux/include/asm-arm/arch-iop33x/memory.h + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#include + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0x00000000) + +/* + * Virtual view <-> PCI DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP331_IATVR2)) | ((*IOP331_IABAR2) & 0xfffffff0)) +#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP331_IALR2)) | ( *IOP331_IATVR2))) + + +#endif diff --git a/include/asm-arm/arch-iop33x/system.h b/include/asm-arm/arch-iop33x/system.h new file mode 100644 index 000000000000..43cc787ea629 --- /dev/null +++ b/include/asm-arm/arch-iop33x/system.h @@ -0,0 +1,29 @@ +/* + * linux/include/asm-arm/arch-iop33x/system.h + * + * Copyright (C) 2001 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + + +static inline void arch_reset(char mode) +{ + *IOP331_PCSR = 0x30; + + if ( 1 && mode == 's') { + /* Jump into ROM at address 0 */ + cpu_reset(0); + } else { + /* No on-chip reset capability */ + cpu_reset(0); + } +} + diff --git a/include/asm-arm/arch-iop33x/timex.h b/include/asm-arm/arch-iop33x/timex.h new file mode 100644 index 000000000000..cc8085fa2a1e --- /dev/null +++ b/include/asm-arm/arch-iop33x/timex.h @@ -0,0 +1,8 @@ +/* + * linux/include/asm-arm/arch-iop33x/timex.h + * + * IOP3xx architecture timex specifications + */ +#include + +#define CLOCK_TICK_RATE IOP331_TICK_RATE diff --git a/include/asm-arm/arch-iop33x/uncompress.h b/include/asm-arm/arch-iop33x/uncompress.h new file mode 100644 index 000000000000..62904ae3b038 --- /dev/null +++ b/include/asm-arm/arch-iop33x/uncompress.h @@ -0,0 +1,36 @@ +/* + * linux/include/asm-arm/arch-iop33x/uncompress.h + */ +#include +#include +#include +#include + +static volatile u32 *uart_base; + +#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE) + +static inline void putc(char c) +{ + while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE) + barrier(); + *uart_base = c; +} + +static inline void flush(void) +{ +} + +static __inline__ void __arch_decomp_setup(unsigned long arch_id) +{ + if (machine_is_iq80331() || machine_is_iq80332()) + uart_base = (volatile u32 *)IOP331_UART0_PHYS; + else + uart_base = (volatile u32 *)0xfe800000; +} + +/* + * nothing to do + */ +#define arch_decomp_setup() __arch_decomp_setup(arch_id) +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-iop33x/vmalloc.h b/include/asm-arm/arch-iop33x/vmalloc.h new file mode 100644 index 000000000000..b5092027449e --- /dev/null +++ b/include/asm-arm/arch-iop33x/vmalloc.h @@ -0,0 +1,16 @@ +/* + * linux/include/asm-arm/arch-iop33x/vmalloc.h + */ + +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +//#define VMALLOC_END (0xe8000000) +/* increase usable physical RAM to ~992M per RMK */ +#define VMALLOC_END (0xfe000000) + diff --git a/include/asm-arm/arch-iop3xx/debug-macro.S b/include/asm-arm/arch-iop3xx/debug-macro.S deleted file mode 100644 index dcc6856d14ff..000000000000 --- a/include/asm-arm/arch-iop3xx/debug-macro.S +++ /dev/null @@ -1,35 +0,0 @@ -/* linux/include/asm-arm/arch-iop3xx/debug-macro.S - * - * Debugging macro include header - * - * Copyright (C) 1994-1999 Russell King - * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - - .macro addruart,rx - mov \rx, #0xfe000000 @ physical -#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244) - orr \rx, \rx, #0x00800000 @ location of the UART -#elif defined(CONFIG_ARCH_IOP33X) - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 @ MMU enabled? - moveq \rx, #0x000fe000 @ Physical Base - movne \rx, #0 - orr \rx, \rx, #0xfe000000 - orr \rx, \rx, #0x00f00000 @ Virtual Base - orr \rx, \rx, #0x00001700 @ location of the UART -#else -#error Unknown IOP3XX implementation -#endif - .endm - -#if !defined(CONFIG_ARCH_IQ80321) || !defined(CONFIG_ARCH_IQ31244) || !defined(CONFIG_ARCH_IQ80331) -#define FLOW_CONTROL -#endif -#define UART_SHIFT 0 -#include diff --git a/include/asm-arm/arch-iop3xx/dma.h b/include/asm-arm/arch-iop3xx/dma.h deleted file mode 100644 index 1e808db8af2a..000000000000 --- a/include/asm-arm/arch-iop3xx/dma.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/dma.h - * - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ diff --git a/include/asm-arm/arch-iop3xx/entry-macro.S b/include/asm-arm/arch-iop3xx/entry-macro.S deleted file mode 100644 index f3db54637ad3..000000000000 --- a/include/asm-arm/arch-iop3xx/entry-macro.S +++ /dev/null @@ -1,57 +0,0 @@ -/* - * include/asm-arm/arch-iop3xx/entry-macro.S - * - * Low-level IRQ helper macros for IOP3xx-based platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#include - -#if defined(CONFIG_ARCH_IOP32X) - .macro disable_fiq - .endm - - /* - * Note: only deal with normal interrupts, not FIQ - */ - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \irqnr, #0 - mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC - cmp \irqstat, #0 - beq 1001f - clz \irqnr, \irqstat - mov \base, #31 - subs \irqnr,\base,\irqnr - add \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT -1001: - .endm - -#elif defined(CONFIG_ARCH_IOP33X) - .macro disable_fiq - .endm - - /* - * Note: only deal with normal interrupts, not FIQ - */ - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \irqnr, #0 - mrc p6, 0, \irqstat, c4, c0, 0 @ Read IINTSRC0 - cmp \irqstat, #0 - bne 1002f - mrc p6, 0, \irqstat, c5, c0, 0 @ Read IINTSRC1 - cmp \irqstat, #0 - beq 1001f - clz \irqnr, \irqstat - rsbs \irqnr,\irqnr,#31 @ recommend by RMK - add \irqnr,\irqnr,#IRQ_IOP331_XINT8 - b 1001f -1002: clz \irqnr, \irqstat - rsbs \irqnr,\irqnr,#31 @ recommend by RMK - add \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT -1001: - .endm - -#endif - diff --git a/include/asm-arm/arch-iop3xx/hardware.h b/include/asm-arm/arch-iop3xx/hardware.h deleted file mode 100644 index 3b138171d086..000000000000 --- a/include/asm-arm/arch-iop3xx/hardware.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/hardware.h - */ -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#include - -/* - * Note about PCI IO space mappings - * - * To make IO space accesses efficient, we store virtual addresses in - * the IO resources. - * - * The PCI IO space is located at virtual 0xfe000000 from physical - * 0x90000000. The PCI BARs must be programmed with physical addresses, - * but when we read them, we convert them to virtual addresses. See - * arch/arm/mach-iop3xx/iop3xx-pci.c - */ - -#define pcibios_assign_all_busses() 1 - - -/* - * The min PCI I/O and MEM space are dependent on what specific - * chipset/platform we are running on, so instead of hardcoding with - * #ifdefs, we just fill these in the platform level PCI init code. - */ -#ifndef __ASSEMBLY__ -extern unsigned long iop3xx_pcibios_min_io; -extern unsigned long iop3xx_pcibios_min_mem; - -extern unsigned int processor_id; -#endif - -/* - * We just set these to zero since they are really bogus anyways - */ -#define PCIBIOS_MIN_IO (iop3xx_pcibios_min_io) -#define PCIBIOS_MIN_MEM (iop3xx_pcibios_min_mem) - -/* - * Generic chipset bits - * - */ -#include "iop321.h" -#include "iop331.h" - -/* - * Board specific bits - */ -#include "iq80321.h" -#include "iq31244.h" -#include "iq80331.h" -#include "iq80332.h" - -#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-iop3xx/io.h b/include/asm-arm/arch-iop3xx/io.h deleted file mode 100644 index 36adbdf5055a..000000000000 --- a/include/asm-arm/arch-iop3xx/io.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/io.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#include - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(p) ((void __iomem *)(p)) -#define __mem_pci(a) (a) - -#endif diff --git a/include/asm-arm/arch-iop3xx/iop321-irqs.h b/include/asm-arm/arch-iop3xx/iop321-irqs.h deleted file mode 100644 index 2fcc1654cb9d..000000000000 --- a/include/asm-arm/arch-iop3xx/iop321-irqs.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/irqs.h - * - * Author: Rory Bolt - * Copyright: (C) 2002 Rory Bolt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#ifndef _IOP321_IRQS_H_ -#define _IOP321_IRQS_H_ - -/* - * IOP80321 chipset interrupts - */ -#define IOP321_IRQ_OFS 0 -#define IOP321_IRQ(x) (IOP321_IRQ_OFS + (x)) - -/* - * On IRQ or FIQ register - */ -#define IRQ_IOP321_DMA0_EOT IOP321_IRQ(0) -#define IRQ_IOP321_DMA0_EOC IOP321_IRQ(1) -#define IRQ_IOP321_DMA1_EOT IOP321_IRQ(2) -#define IRQ_IOP321_DMA1_EOC IOP321_IRQ(3) -#define IRQ_IOP321_RSVD_4 IOP321_IRQ(4) -#define IRQ_IOP321_RSVD_5 IOP321_IRQ(5) -#define IRQ_IOP321_AA_EOT IOP321_IRQ(6) -#define IRQ_IOP321_AA_EOC IOP321_IRQ(7) -#define IRQ_IOP321_CORE_PMON IOP321_IRQ(8) -#define IRQ_IOP321_TIMER0 IOP321_IRQ(9) -#define IRQ_IOP321_TIMER1 IOP321_IRQ(10) -#define IRQ_IOP321_I2C_0 IOP321_IRQ(11) -#define IRQ_IOP321_I2C_1 IOP321_IRQ(12) -#define IRQ_IOP321_MESSAGING IOP321_IRQ(13) -#define IRQ_IOP321_ATU_BIST IOP321_IRQ(14) -#define IRQ_IOP321_PERFMON IOP321_IRQ(15) -#define IRQ_IOP321_CORE_PMU IOP321_IRQ(16) -#define IRQ_IOP321_BIU_ERR IOP321_IRQ(17) -#define IRQ_IOP321_ATU_ERR IOP321_IRQ(18) -#define IRQ_IOP321_MCU_ERR IOP321_IRQ(19) -#define IRQ_IOP321_DMA0_ERR IOP321_IRQ(20) -#define IRQ_IOP321_DMA1_ERR IOP321_IRQ(21) -#define IRQ_IOP321_RSVD_22 IOP321_IRQ(22) -#define IRQ_IOP321_AA_ERR IOP321_IRQ(23) -#define IRQ_IOP321_MSG_ERR IOP321_IRQ(24) -#define IRQ_IOP321_SSP IOP321_IRQ(25) -#define IRQ_IOP321_RSVD_26 IOP321_IRQ(26) -#define IRQ_IOP321_XINT0 IOP321_IRQ(27) -#define IRQ_IOP321_XINT1 IOP321_IRQ(28) -#define IRQ_IOP321_XINT2 IOP321_IRQ(29) -#define IRQ_IOP321_XINT3 IOP321_IRQ(30) -#define IRQ_IOP321_HPI IOP321_IRQ(31) - -#define NR_IOP321_IRQS (IOP321_IRQ(31) + 1) - -#define NR_IRQS NR_IOP321_IRQS - - -/* - * Interrupts available on the IQ80321 board - */ - -/* - * On board devices - */ -#define IRQ_IQ80321_I82544 IRQ_IOP321_XINT0 -#define IRQ_IQ80321_UART IRQ_IOP321_XINT1 - -/* - * PCI interrupts - */ -#define IRQ_IQ80321_INTA IRQ_IOP321_XINT0 -#define IRQ_IQ80321_INTB IRQ_IOP321_XINT1 -#define IRQ_IQ80321_INTC IRQ_IOP321_XINT2 -#define IRQ_IQ80321_INTD IRQ_IOP321_XINT3 - -/* - * Interrupts on the IQ31244 board - */ - -/* - * On board devices - */ -#define IRQ_IQ31244_UART IRQ_IOP321_XINT1 -#define IRQ_IQ31244_I82546 IRQ_IOP321_XINT0 -#define IRQ_IQ31244_SATA IRQ_IOP321_XINT2 -#define IRQ_IQ31244_PCIX_SLOT IRQ_IOP321_XINT3 - -/* - * PCI interrupts - */ -#define IRQ_IQ31244_INTA IRQ_IOP321_XINT0 -#define IRQ_IQ31244_INTB IRQ_IOP321_XINT1 -#define IRQ_IQ31244_INTC IRQ_IOP321_XINT2 -#define IRQ_IQ31244_INTD IRQ_IOP321_XINT3 - -#endif // _IOP321_IRQ_H_ diff --git a/include/asm-arm/arch-iop3xx/iop321.h b/include/asm-arm/arch-iop3xx/iop321.h deleted file mode 100644 index d198d72a50a4..000000000000 --- a/include/asm-arm/arch-iop3xx/iop321.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iop321.h - * - * Intel IOP321 Chip definitions - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _IOP321_HW_H_ -#define _IOP321_HW_H_ - - -/* - * This is needed for mixed drivers that need to work on all - * IOP3xx variants but behave slightly differently on each. - */ -#ifndef __ASSEMBLY__ -#ifdef CONFIG_ARCH_IOP32X -#define iop_is_321() (((processor_id & 0xfffff5e0) == 0x69052420)) -#else -#define iop_is_321() 0 -#endif -#endif - -/* - * IOP321 I/O and Mem space regions for PCI autoconfiguration - */ -#define IOP321_PCI_IO_WINDOW_SIZE 0x00010000 -#define IOP321_PCI_LOWER_IO_PA 0x90000000 -#define IOP321_PCI_LOWER_IO_VA 0xfe000000 -#define IOP321_PCI_LOWER_IO_BA (*IOP321_OIOWTVR) -#define IOP321_PCI_UPPER_IO_PA (IOP321_PCI_LOWER_IO_PA + IOP321_PCI_IO_WINDOW_SIZE - 1) -#define IOP321_PCI_UPPER_IO_VA (IOP321_PCI_LOWER_IO_VA + IOP321_PCI_IO_WINDOW_SIZE - 1) -#define IOP321_PCI_UPPER_IO_BA (IOP321_PCI_LOWER_IO_BA + IOP321_PCI_IO_WINDOW_SIZE - 1) -#define IOP321_PCI_IO_OFFSET (IOP321_PCI_LOWER_IO_VA - IOP321_PCI_LOWER_IO_BA) - -/* #define IOP321_PCI_MEM_WINDOW_SIZE (~*IOP321_IALR1 + 1) */ -#define IOP321_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */ -#define IOP321_PCI_LOWER_MEM_PA 0x80000000 -#define IOP321_PCI_LOWER_MEM_BA (*IOP321_OMWTVR0) -#define IOP321_PCI_UPPER_MEM_PA (IOP321_PCI_LOWER_MEM_PA + IOP321_PCI_MEM_WINDOW_SIZE - 1) -#define IOP321_PCI_UPPER_MEM_BA (IOP321_PCI_LOWER_MEM_BA + IOP321_PCI_MEM_WINDOW_SIZE - 1) -#define IOP321_PCI_MEM_OFFSET (IOP321_PCI_LOWER_MEM_PA - IOP321_PCI_LOWER_MEM_BA) - - -/* - * IOP321 chipset registers - */ -#define IOP321_VIRT_MEM_BASE 0xfeffe000 /* chip virtual mem address*/ -#define IOP321_PHYS_MEM_BASE 0xffffe000 /* chip physical memory address */ -#define IOP321_REG_ADDR(reg) (IOP321_VIRT_MEM_BASE | (reg)) - -/* Reserved 0x00000000 through 0x000000FF */ - -/* Address Translation Unit 0x00000100 through 0x000001FF */ -#define IOP321_ATUVID (volatile u16 *)IOP321_REG_ADDR(0x00000100) -#define IOP321_ATUDID (volatile u16 *)IOP321_REG_ADDR(0x00000102) -#define IOP321_ATUCMD (volatile u16 *)IOP321_REG_ADDR(0x00000104) -#define IOP321_ATUSR (volatile u16 *)IOP321_REG_ADDR(0x00000106) -#define IOP321_ATURID (volatile u8 *)IOP321_REG_ADDR(0x00000108) -#define IOP321_ATUCCR (volatile u32 *)IOP321_REG_ADDR(0x00000109) -#define IOP321_ATUCLSR (volatile u8 *)IOP321_REG_ADDR(0x0000010C) -#define IOP321_ATULT (volatile u8 *)IOP321_REG_ADDR(0x0000010D) -#define IOP321_ATUHTR (volatile u8 *)IOP321_REG_ADDR(0x0000010E) -#define IOP321_ATUBIST (volatile u8 *)IOP321_REG_ADDR(0x0000010F) -#define IOP321_IABAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000110) -#define IOP321_IAUBAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000114) -#define IOP321_IABAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000118) -#define IOP321_IAUBAR1 (volatile u32 *)IOP321_REG_ADDR(0x0000011C) -#define IOP321_IABAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000120) -#define IOP321_IAUBAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000124) -#define IOP321_ASVIR (volatile u16 *)IOP321_REG_ADDR(0x0000012C) -#define IOP321_ASIR (volatile u16 *)IOP321_REG_ADDR(0x0000012E) -#define IOP321_ERBAR (volatile u32 *)IOP321_REG_ADDR(0x00000130) -/* Reserved 0x00000134 through 0x0000013B */ -#define IOP321_ATUILR (volatile u8 *)IOP321_REG_ADDR(0x0000013C) -#define IOP321_ATUIPR (volatile u8 *)IOP321_REG_ADDR(0x0000013D) -#define IOP321_ATUMGNT (volatile u8 *)IOP321_REG_ADDR(0x0000013E) -#define IOP321_ATUMLAT (volatile u8 *)IOP321_REG_ADDR(0x0000013F) -#define IOP321_IALR0 (volatile u32 *)IOP321_REG_ADDR(0x00000140) -#define IOP321_IATVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000144) -#define IOP321_ERLR (volatile u32 *)IOP321_REG_ADDR(0x00000148) -#define IOP321_ERTVR (volatile u32 *)IOP321_REG_ADDR(0x0000014C) -#define IOP321_IALR1 (volatile u32 *)IOP321_REG_ADDR(0x00000150) -#define IOP321_IALR2 (volatile u32 *)IOP321_REG_ADDR(0x00000154) -#define IOP321_IATVR2 (volatile u32 *)IOP321_REG_ADDR(0x00000158) -#define IOP321_OIOWTVR (volatile u32 *)IOP321_REG_ADDR(0x0000015C) -#define IOP321_OMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000160) -#define IOP321_OUMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000164) -#define IOP321_OMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x00000168) -#define IOP321_OUMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x0000016C) -/* Reserved 0x00000170 through 0x00000177*/ -#define IOP321_OUDWTVR (volatile u32 *)IOP321_REG_ADDR(0x00000178) -/* Reserved 0x0000017C through 0x0000017F*/ -#define IOP321_ATUCR (volatile u32 *)IOP321_REG_ADDR(0x00000180) -#define IOP321_PCSR (volatile u32 *)IOP321_REG_ADDR(0x00000184) -#define IOP321_ATUISR (volatile u32 *)IOP321_REG_ADDR(0x00000188) -#define IOP321_ATUIMR (volatile u32 *)IOP321_REG_ADDR(0x0000018C) -#define IOP321_IABAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000190) -#define IOP321_IAUBAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000194) -#define IOP321_IALR3 (volatile u32 *)IOP321_REG_ADDR(0x00000198) -#define IOP321_IATVR3 (volatile u32 *)IOP321_REG_ADDR(0x0000019C) -/* Reserved 0x000001A0 through 0x000001A3*/ -#define IOP321_OCCAR (volatile u32 *)IOP321_REG_ADDR(0x000001A4) -/* Reserved 0x000001A8 through 0x000001AB*/ -#define IOP321_OCCDR (volatile u32 *)IOP321_REG_ADDR(0x000001AC) -/* Reserved 0x000001B0 through 0x000001BB*/ -#define IOP321_PDSCR (volatile u32 *)IOP321_REG_ADDR(0x000001BC) -#define IOP321_PMCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001C0) -#define IOP321_PMNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001C1) -#define IOP321_APMCR (volatile u16 *)IOP321_REG_ADDR(0x000001C2) -#define IOP321_APMCSR (volatile u16 *)IOP321_REG_ADDR(0x000001C4) -/* Reserved 0x000001C6 through 0x000001DF */ -#define IOP321_PCIXCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001E0) -#define IOP321_PCIXNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001E1) -#define IOP321_PCIXCMD (volatile u16 *)IOP321_REG_ADDR(0x000001E2) -#define IOP321_PCIXSR (volatile u32 *)IOP321_REG_ADDR(0x000001E4) -#define IOP321_PCIIRSR (volatile u32 *)IOP321_REG_ADDR(0x000001EC) - -/* Messaging Unit 0x00000300 through 0x000003FF */ - -/* Reserved 0x00000300 through 0x0000030c */ -#define IOP321_IMR0 (volatile u32 *)IOP321_REG_ADDR(0x00000310) -#define IOP321_IMR1 (volatile u32 *)IOP321_REG_ADDR(0x00000314) -#define IOP321_OMR0 (volatile u32 *)IOP321_REG_ADDR(0x00000318) -#define IOP321_OMR1 (volatile u32 *)IOP321_REG_ADDR(0x0000031C) -#define IOP321_IDR (volatile u32 *)IOP321_REG_ADDR(0x00000320) -#define IOP321_IISR (volatile u32 *)IOP321_REG_ADDR(0x00000324) -#define IOP321_IIMR (volatile u32 *)IOP321_REG_ADDR(0x00000328) -#define IOP321_ODR (volatile u32 *)IOP321_REG_ADDR(0x0000032C) -#define IOP321_OISR (volatile u32 *)IOP321_REG_ADDR(0x00000330) -#define IOP321_OIMR (volatile u32 *)IOP321_REG_ADDR(0x00000334) -/* Reserved 0x00000338 through 0x0000034F */ -#define IOP321_MUCR (volatile u32 *)IOP321_REG_ADDR(0x00000350) -#define IOP321_QBAR (volatile u32 *)IOP321_REG_ADDR(0x00000354) -/* Reserved 0x00000358 through 0x0000035C */ -#define IOP321_IFHPR (volatile u32 *)IOP321_REG_ADDR(0x00000360) -#define IOP321_IFTPR (volatile u32 *)IOP321_REG_ADDR(0x00000364) -#define IOP321_IPHPR (volatile u32 *)IOP321_REG_ADDR(0x00000368) -#define IOP321_IPTPR (volatile u32 *)IOP321_REG_ADDR(0x0000036C) -#define IOP321_OFHPR (volatile u32 *)IOP321_REG_ADDR(0x00000370) -#define IOP321_OFTPR (volatile u32 *)IOP321_REG_ADDR(0x00000374) -#define IOP321_OPHPR (volatile u32 *)IOP321_REG_ADDR(0x00000378) -#define IOP321_OPTPR (volatile u32 *)IOP321_REG_ADDR(0x0000037C) -#define IOP321_IAR (volatile u32 *)IOP321_REG_ADDR(0x00000380) - -#define IOP321_IIxR_MASK 0x7f /* masks all */ -#define IOP321_IIxR_IRI 0x40 /* RC Index Register Interrupt */ -#define IOP321_IIxR_OFQF 0x20 /* RC Output Free Q Full (ERROR) */ -#define IOP321_IIxR_ipq 0x10 /* RC Inbound Post Q (post) */ -#define IOP321_IIxR_ERRDI 0x08 /* RO Error Doorbell Interrupt */ -#define IOP321_IIxR_IDI 0x04 /* RO Inbound Doorbell Interrupt */ -#define IOP321_IIxR_IM1 0x02 /* RC Inbound Message 1 Interrupt */ -#define IOP321_IIxR_IM0 0x01 /* RC Inbound Message 0 Interrupt */ - -/* Reserved 0x00000384 through 0x000003FF */ - -/* DMA Controller 0x00000400 through 0x000004FF */ -#define IOP321_DMA0_CCR (volatile u32 *)IOP321_REG_ADDR(0x00000400) -#define IOP321_DMA0_CSR (volatile u32 *)IOP321_REG_ADDR(0x00000404) -#define IOP321_DMA0_DAR (volatile u32 *)IOP321_REG_ADDR(0x0000040C) -#define IOP321_DMA0_NDAR (volatile u32 *)IOP321_REG_ADDR(0x00000410) -#define IOP321_DMA0_PADR (volatile u32 *)IOP321_REG_ADDR(0x00000414) -#define IOP321_DMA0_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000418) -#define IOP321_DMA0_LADR (volatile u32 *)IOP321_REG_ADDR(0X0000041C) -#define IOP321_DMA0_BCR (volatile u32 *)IOP321_REG_ADDR(0x00000420) -#define IOP321_DMA0_DCR (volatile u32 *)IOP321_REG_ADDR(0x00000424) -/* Reserved 0x00000428 through 0x0000043C */ -#define IOP321_DMA1_CCR (volatile u32 *)IOP321_REG_ADDR(0x00000440) -#define IOP321_DMA1_CSR (volatile u32 *)IOP321_REG_ADDR(0x00000444) -#define IOP321_DMA1_DAR (volatile u32 *)IOP321_REG_ADDR(0x0000044C) -#define IOP321_DMA1_NDAR (volatile u32 *)IOP321_REG_ADDR(0x00000450) -#define IOP321_DMA1_PADR (volatile u32 *)IOP321_REG_ADDR(0x00000454) -#define IOP321_DMA1_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000458) -#define IOP321_DMA1_LADR (volatile u32 *)IOP321_REG_ADDR(0x0000045C) -#define IOP321_DMA1_BCR (volatile u32 *)IOP321_REG_ADDR(0x00000460) -#define IOP321_DMA1_DCR (volatile u32 *)IOP321_REG_ADDR(0x00000464) -/* Reserved 0x00000468 through 0x000004FF */ - -/* Memory controller 0x00000500 through 0x0005FF */ - -/* Peripheral bus interface unit 0x00000680 through 0x0006FF */ -#define IOP321_PBCR (volatile u32 *)IOP321_REG_ADDR(0x00000680) -#define IOP321_PBISR (volatile u32 *)IOP321_REG_ADDR(0x00000684) -#define IOP321_PBBAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000688) -#define IOP321_PBLR0 (volatile u32 *)IOP321_REG_ADDR(0x0000068C) -#define IOP321_PBBAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000690) -#define IOP321_PBLR1 (volatile u32 *)IOP321_REG_ADDR(0x00000694) -#define IOP321_PBBAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000698) -#define IOP321_PBLR2 (volatile u32 *)IOP321_REG_ADDR(0x0000069C) -#define IOP321_PBBAR3 (volatile u32 *)IOP321_REG_ADDR(0x000006A0) -#define IOP321_PBLR3 (volatile u32 *)IOP321_REG_ADDR(0x000006A4) -#define IOP321_PBBAR4 (volatile u32 *)IOP321_REG_ADDR(0x000006A8) -#define IOP321_PBLR4 (volatile u32 *)IOP321_REG_ADDR(0x000006AC) -#define IOP321_PBBAR5 (volatile u32 *)IOP321_REG_ADDR(0x000006B0) -#define IOP321_PBLR5 (volatile u32 *)IOP321_REG_ADDR(0x000006B4) -#define IOP321_PBDSCR (volatile u32 *)IOP321_REG_ADDR(0x000006B8) -/* Reserved 0x000006BC */ -#define IOP321_PMBR0 (volatile u32 *)IOP321_REG_ADDR(0x000006C0) -/* Reserved 0x000006C4 through 0x000006DC */ -#define IOP321_PMBR1 (volatile u32 *)IOP321_REG_ADDR(0x000006E0) -#define IOP321_PMBR2 (volatile u32 *)IOP321_REG_ADDR(0x000006E4) - -#define IOP321_PBCR_EN 0x1 - -#define IOP321_PBISR_BOOR_ERR 0x1 - -/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */ -#define IOP321_GTMR (volatile u32 *)IOP321_REG_ADDR(0x00000700) -#define IOP321_ESR (volatile u32 *)IOP321_REG_ADDR(0x00000704) -#define IOP321_EMISR (volatile u32 *)IOP321_REG_ADDR(0x00000708) -/* reserved 0x00000070c */ -#define IOP321_GTSR (volatile u32 *)IOP321_REG_ADDR(0x00000710) -/* PERC0 DOESN'T EXIST - index from 1! */ -#define IOP321_PERCR0 (volatile u32 *)IOP321_REG_ADDR(0x00000710) - -#define IOP321_GTMR_NGCE 0x04 /* (Not) Global Counter Enable */ - -/* Internal arbitration unit 0x00000780 through 0x0007BF */ -#define IOP321_IACR (volatile u32 *)IOP321_REG_ADDR(0x00000780) -#define IOP321_MTTR1 (volatile u32 *)IOP321_REG_ADDR(0x00000784) -#define IOP321_MTTR2 (volatile u32 *)IOP321_REG_ADDR(0x00000788) - -/* General Purpose I/O Registers */ -#define IOP321_GPOE (volatile u32 *)IOP321_REG_ADDR(0x000007C4) -#define IOP321_GPID (volatile u32 *)IOP321_REG_ADDR(0x000007C8) -#define IOP321_GPOD (volatile u32 *)IOP321_REG_ADDR(0x000007CC) - -/* Interrupt Controller */ -#define IOP321_INTCTL (volatile u32 *)IOP321_REG_ADDR(0x000007D0) -#define IOP321_INTSTR (volatile u32 *)IOP321_REG_ADDR(0x000007D4) -#define IOP321_IINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007D8) -#define IOP321_FINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007DC) - -/* Timers */ - -#define IOP321_TU_TMR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E0) -#define IOP321_TU_TMR1 (volatile u32 *)IOP321_REG_ADDR(0x000007E4) - -#ifdef CONFIG_ARCH_IQ80321 -#define IOP321_TICK_RATE 200000000 /* 200 MHz clock */ -#elif defined(CONFIG_ARCH_IQ31244) -#define IOP321_TICK_RATE 198000000 /* 33.000 MHz crystal */ -#endif - -#ifdef CONFIG_ARCH_EP80219 -#undef IOP321_TICK_RATE -#define IOP321_TICK_RATE 200000000 /* 33.333333 Mhz crystal */ -#endif - -#define IOP321_TMR_TC 0x01 -#define IOP321_TMR_EN 0x02 -#define IOP321_TMR_RELOAD 0x04 -#define IOP321_TMR_PRIVILEGED 0x09 - -#define IOP321_TMR_RATIO_1_1 0x00 -#define IOP321_TMR_RATIO_4_1 0x10 -#define IOP321_TMR_RATIO_8_1 0x20 -#define IOP321_TMR_RATIO_16_1 0x30 - -#define IOP321_TU_TCR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E8) -#define IOP321_TU_TCR1 (volatile u32 *)IOP321_REG_ADDR(0x000007EC) -#define IOP321_TU_TRR0 (volatile u32 *)IOP321_REG_ADDR(0x000007F0) -#define IOP321_TU_TRR1 (volatile u32 *)IOP321_REG_ADDR(0x000007F4) -#define IOP321_TU_TISR (volatile u32 *)IOP321_REG_ADDR(0x000007F8) -#define IOP321_TU_WDTCR (volatile u32 *)IOP321_REG_ADDR(0x000007FC) - -/* Application accelerator unit 0x00000800 - 0x000008FF */ -#define IOP321_AAU_ACR (volatile u32 *)IOP321_REG_ADDR(0x00000800) -#define IOP321_AAU_ASR (volatile u32 *)IOP321_REG_ADDR(0x00000804) -#define IOP321_AAU_ADAR (volatile u32 *)IOP321_REG_ADDR(0x00000808) -#define IOP321_AAU_ANDAR (volatile u32 *)IOP321_REG_ADDR(0x0000080C) -#define IOP321_AAU_SAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000810) -#define IOP321_AAU_SAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000814) -#define IOP321_AAU_SAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000818) -#define IOP321_AAU_SAR4 (volatile u32 *)IOP321_REG_ADDR(0x0000081C) -#define IOP321_AAU_SAR5 (volatile u32 *)IOP321_REG_ADDR(0x0000082C) -#define IOP321_AAU_SAR6 (volatile u32 *)IOP321_REG_ADDR(0x00000830) -#define IOP321_AAU_SAR7 (volatile u32 *)IOP321_REG_ADDR(0x00000834) -#define IOP321_AAU_SAR8 (volatile u32 *)IOP321_REG_ADDR(0x00000838) -#define IOP321_AAU_SAR9 (volatile u32 *)IOP321_REG_ADDR(0x00000840) -#define IOP321_AAU_SAR10 (volatile u32 *)IOP321_REG_ADDR(0x00000844) -#define IOP321_AAU_SAR11 (volatile u32 *)IOP321_REG_ADDR(0x00000848) -#define IOP321_AAU_SAR12 (volatile u32 *)IOP321_REG_ADDR(0x0000084C) -#define IOP321_AAU_SAR13 (volatile u32 *)IOP321_REG_ADDR(0x00000850) -#define IOP321_AAU_SAR14 (volatile u32 *)IOP321_REG_ADDR(0x00000854) -#define IOP321_AAU_SAR15 (volatile u32 *)IOP321_REG_ADDR(0x00000858) -#define IOP321_AAU_SAR16 (volatile u32 *)IOP321_REG_ADDR(0x0000085C) -#define IOP321_AAU_SAR17 (volatile u32 *)IOP321_REG_ADDR(0x00000864) -#define IOP321_AAU_SAR18 (volatile u32 *)IOP321_REG_ADDR(0x00000868) -#define IOP321_AAU_SAR19 (volatile u32 *)IOP321_REG_ADDR(0x0000086C) -#define IOP321_AAU_SAR20 (volatile u32 *)IOP321_REG_ADDR(0x00000870) -#define IOP321_AAU_SAR21 (volatile u32 *)IOP321_REG_ADDR(0x00000874) -#define IOP321_AAU_SAR22 (volatile u32 *)IOP321_REG_ADDR(0x00000878) -#define IOP321_AAU_SAR23 (volatile u32 *)IOP321_REG_ADDR(0x0000087C) -#define IOP321_AAU_SAR24 (volatile u32 *)IOP321_REG_ADDR(0x00000880) -#define IOP321_AAU_SAR25 (volatile u32 *)IOP321_REG_ADDR(0x00000888) -#define IOP321_AAU_SAR26 (volatile u32 *)IOP321_REG_ADDR(0x0000088C) -#define IOP321_AAU_SAR27 (volatile u32 *)IOP321_REG_ADDR(0x00000890) -#define IOP321_AAU_SAR28 (volatile u32 *)IOP321_REG_ADDR(0x00000894) -#define IOP321_AAU_SAR29 (volatile u32 *)IOP321_REG_ADDR(0x00000898) -#define IOP321_AAU_SAR30 (volatile u32 *)IOP321_REG_ADDR(0x0000089C) -#define IOP321_AAU_SAR31 (volatile u32 *)IOP321_REG_ADDR(0x000008A0) -#define IOP321_AAU_SAR32 (volatile u32 *)IOP321_REG_ADDR(0x000008A4) -#define IOP321_AAU_DAR (volatile u32 *)IOP321_REG_ADDR(0x00000820) -#define IOP321_AAU_ABCR (volatile u32 *)IOP321_REG_ADDR(0x00000824) -#define IOP321_AAU_ADCR (volatile u32 *)IOP321_REG_ADDR(0x00000828) -#define IOP321_AAU_EDCR0 (volatile u32 *)IOP321_REG_ADDR(0x0000083c) -#define IOP321_AAU_EDCR1 (volatile u32 *)IOP321_REG_ADDR(0x00000860) -#define IOP321_AAU_EDCR2 (volatile u32 *)IOP321_REG_ADDR(0x00000884) - - -/* SSP serial port unit 0x00001600 - 0x0000167F */ -/* I2C bus interface unit 0x00001680 - 0x000016FF */ -#define IOP321_ICR0 (volatile u32 *)IOP321_REG_ADDR(0x00001680) -#define IOP321_ISR0 (volatile u32 *)IOP321_REG_ADDR(0x00001684) -#define IOP321_ISAR0 (volatile u32 *)IOP321_REG_ADDR(0x00001688) -#define IOP321_IDBR0 (volatile u32 *)IOP321_REG_ADDR(0x0000168C) -/* Reserved 0x00001690 */ -#define IOP321_IBMR0 (volatile u32 *)IOP321_REG_ADDR(0x00001694) -/* Reserved 0x00001698 */ -/* Reserved 0x0000169C */ -#define IOP321_ICR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A0) -#define IOP321_ISR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A4) -#define IOP321_ISAR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A8) -#define IOP321_IDBR1 (volatile u32 *)IOP321_REG_ADDR(0x000016AC) -#define IOP321_IBMR1 (volatile u32 *)IOP321_REG_ADDR(0x000016B4) -/* Reserved 0x000016B8 through 0x000016FC */ - -/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */ - - -#ifndef __ASSEMBLY__ -extern void iop321_map_io(void); -extern void iop321_init_irq(void); -extern void iop321_time_init(void); -#endif - -#endif // _IOP321_HW_H_ diff --git a/include/asm-arm/arch-iop3xx/iop331-irqs.h b/include/asm-arm/arch-iop3xx/iop331-irqs.h deleted file mode 100644 index 7135ad7e335e..000000000000 --- a/include/asm-arm/arch-iop3xx/iop331-irqs.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/irqs.h - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright: (C) 2003 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#ifndef _IOP331_IRQS_H_ -#define _IOP331_IRQS_H_ - -/* - * IOP80331 chipset interrupts - */ -#define IOP331_IRQ_OFS 0 -#define IOP331_IRQ(x) (IOP331_IRQ_OFS + (x)) - -/* - * On IRQ or FIQ register - */ -#define IRQ_IOP331_DMA0_EOT IOP331_IRQ(0) -#define IRQ_IOP331_DMA0_EOC IOP331_IRQ(1) -#define IRQ_IOP331_DMA1_EOT IOP331_IRQ(2) -#define IRQ_IOP331_DMA1_EOC IOP331_IRQ(3) -#define IRQ_IOP331_RSVD_4 IOP331_IRQ(4) -#define IRQ_IOP331_RSVD_5 IOP331_IRQ(5) -#define IRQ_IOP331_AA_EOT IOP331_IRQ(6) -#define IRQ_IOP331_AA_EOC IOP331_IRQ(7) -#define IRQ_IOP331_TIMER0 IOP331_IRQ(8) -#define IRQ_IOP331_TIMER1 IOP331_IRQ(9) -#define IRQ_IOP331_I2C_0 IOP331_IRQ(10) -#define IRQ_IOP331_I2C_1 IOP331_IRQ(11) -#define IRQ_IOP331_MSG IOP331_IRQ(12) -#define IRQ_IOP331_MSGIBQ IOP331_IRQ(13) -#define IRQ_IOP331_ATU_BIST IOP331_IRQ(14) -#define IRQ_IOP331_PERFMON IOP331_IRQ(15) -#define IRQ_IOP331_CORE_PMU IOP331_IRQ(16) -#define IRQ_IOP331_RSVD_17 IOP331_IRQ(17) -#define IRQ_IOP331_RSVD_18 IOP331_IRQ(18) -#define IRQ_IOP331_RSVD_19 IOP331_IRQ(19) -#define IRQ_IOP331_RSVD_20 IOP331_IRQ(20) -#define IRQ_IOP331_RSVD_21 IOP331_IRQ(21) -#define IRQ_IOP331_RSVD_22 IOP331_IRQ(22) -#define IRQ_IOP331_RSVD_23 IOP331_IRQ(23) -#define IRQ_IOP331_XINT0 IOP331_IRQ(24) -#define IRQ_IOP331_XINT1 IOP331_IRQ(25) -#define IRQ_IOP331_XINT2 IOP331_IRQ(26) -#define IRQ_IOP331_XINT3 IOP331_IRQ(27) -#define IRQ_IOP331_RSVD_28 IOP331_IRQ(28) -#define IRQ_IOP331_RSVD_29 IOP331_IRQ(29) -#define IRQ_IOP331_RSVD_30 IOP331_IRQ(30) -#define IRQ_IOP331_RSVD_31 IOP331_IRQ(31) -#define IRQ_IOP331_XINT8 IOP331_IRQ(32) // 0 -#define IRQ_IOP331_XINT9 IOP331_IRQ(33) // 1 -#define IRQ_IOP331_XINT10 IOP331_IRQ(34) // 2 -#define IRQ_IOP331_XINT11 IOP331_IRQ(35) // 3 -#define IRQ_IOP331_XINT12 IOP331_IRQ(36) // 4 -#define IRQ_IOP331_XINT13 IOP331_IRQ(37) // 5 -#define IRQ_IOP331_XINT14 IOP331_IRQ(38) // 6 -#define IRQ_IOP331_XINT15 IOP331_IRQ(39) // 7 -#define IRQ_IOP331_RSVD_40 IOP331_IRQ(40) // 8 -#define IRQ_IOP331_RSVD_41 IOP331_IRQ(41) // 9 -#define IRQ_IOP331_RSVD_42 IOP331_IRQ(42) // 10 -#define IRQ_IOP331_RSVD_43 IOP331_IRQ(43) // 11 -#define IRQ_IOP331_RSVD_44 IOP331_IRQ(44) // 12 -#define IRQ_IOP331_RSVD_45 IOP331_IRQ(45) // 13 -#define IRQ_IOP331_RSVD_46 IOP331_IRQ(46) // 14 -#define IRQ_IOP331_RSVD_47 IOP331_IRQ(47) // 15 -#define IRQ_IOP331_RSVD_48 IOP331_IRQ(48) // 16 -#define IRQ_IOP331_RSVD_49 IOP331_IRQ(49) // 17 -#define IRQ_IOP331_RSVD_50 IOP331_IRQ(50) // 18 -#define IRQ_IOP331_UART0 IOP331_IRQ(51) // 19 -#define IRQ_IOP331_UART1 IOP331_IRQ(52) // 20 -#define IRQ_IOP331_PBIE IOP331_IRQ(53) // 21 -#define IRQ_IOP331_ATU_CRW IOP331_IRQ(54) // 22 -#define IRQ_IOP331_ATU_ERR IOP331_IRQ(55) // 23 -#define IRQ_IOP331_MCU_ERR IOP331_IRQ(56) // 24 -#define IRQ_IOP331_DMA0_ERR IOP331_IRQ(57) // 25 -#define IRQ_IOP331_DMA1_ERR IOP331_IRQ(58) // 26 -#define IRQ_IOP331_RSVD_59 IOP331_IRQ(59) // 27 -#define IRQ_IOP331_AA_ERR IOP331_IRQ(60) // 28 -#define IRQ_IOP331_RSVD_61 IOP331_IRQ(61) // 29 -#define IRQ_IOP331_MSG_ERR IOP331_IRQ(62) // 30 -#define IRQ_IOP331_HPI IOP331_IRQ(63) // 31 - -#define NR_IOP331_IRQS (IOP331_IRQ(63) + 1) - -#define NR_IRQS NR_IOP331_IRQS - - -/* - * Interrupts available on the IQ80331 board - */ - -/* - * On board devices - */ -#define IRQ_IQ80331_I82544 IRQ_IOP331_XINT0 -#define IRQ_IQ80331_UART0 IRQ_IOP331_UART0 -#define IRQ_IQ80331_UART1 IRQ_IOP331_UART1 - -/* - * PCI interrupts - */ -#define IRQ_IQ80331_INTA IRQ_IOP331_XINT0 -#define IRQ_IQ80331_INTB IRQ_IOP331_XINT1 -#define IRQ_IQ80331_INTC IRQ_IOP331_XINT2 -#define IRQ_IQ80331_INTD IRQ_IOP331_XINT3 - -/* - * Interrupts available on the IQ80332 board - */ - -/* - * On board devices - */ -#define IRQ_IQ80332_I82544 IRQ_IOP331_XINT0 -#define IRQ_IQ80332_UART0 IRQ_IOP331_UART0 -#define IRQ_IQ80332_UART1 IRQ_IOP331_UART1 - -/* - * PCI interrupts - */ -#define IRQ_IQ80332_INTA IRQ_IOP331_XINT0 -#define IRQ_IQ80332_INTB IRQ_IOP331_XINT1 -#define IRQ_IQ80332_INTC IRQ_IOP331_XINT2 -#define IRQ_IQ80332_INTD IRQ_IOP331_XINT3 - -#endif // _IOP331_IRQ_H_ diff --git a/include/asm-arm/arch-iop3xx/iop331.h b/include/asm-arm/arch-iop3xx/iop331.h deleted file mode 100644 index 4d7bcc62cb3e..000000000000 --- a/include/asm-arm/arch-iop3xx/iop331.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iop331.h - * - * Intel IOP331 Chip definitions - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright (C) 2003, 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _IOP331_HW_H_ -#define _IOP331_HW_H_ - - -/* - * This is needed for mixed drivers that need to work on all - * IOP3xx variants but behave slightly differently on each. - */ -#ifndef __ASSEMBLY__ -#ifdef CONFIG_ARCH_IOP33X -/*#define iop_is_331() ((processor_id & 0xffffffb0) == 0x69054090) */ -#define iop_is_331() ((processor_id & 0xffffff30) == 0x69054010) -#else -#define iop_is_331() 0 -#endif -#endif - -/* - * IOP331 I/O and Mem space regions for PCI autoconfiguration - */ -#define IOP331_PCI_IO_WINDOW_SIZE 0x00010000 -#define IOP331_PCI_LOWER_IO_PA 0x90000000 -#define IOP331_PCI_LOWER_IO_VA 0xfe000000 -#define IOP331_PCI_LOWER_IO_BA (*IOP331_OIOWTVR) -#define IOP331_PCI_UPPER_IO_PA (IOP331_PCI_LOWER_IO_PA + IOP331_PCI_IO_WINDOW_SIZE - 1) -#define IOP331_PCI_UPPER_IO_VA (IOP331_PCI_LOWER_IO_VA + IOP331_PCI_IO_WINDOW_SIZE - 1) -#define IOP331_PCI_UPPER_IO_BA (IOP331_PCI_LOWER_IO_BA + IOP331_PCI_IO_WINDOW_SIZE - 1) -#define IOP331_PCI_IO_OFFSET (IOP331_PCI_LOWER_IO_VA - IOP331_PCI_LOWER_IO_BA) - -/* this can be 128M if OMWTVR1 is set */ -#define IOP331_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */ -/* #define IOP331_PCI_MEM_WINDOW_SIZE (~*IOP331_IALR1 + 1) */ -#define IOP331_PCI_LOWER_MEM_PA 0x80000000 -#define IOP331_PCI_LOWER_MEM_BA (*IOP331_OMWTVR0) -#define IOP331_PCI_UPPER_MEM_PA (IOP331_PCI_LOWER_MEM_PA + IOP331_PCI_MEM_WINDOW_SIZE - 1) -#define IOP331_PCI_UPPER_MEM_BA (IOP331_PCI_LOWER_MEM_BA + IOP331_PCI_MEM_WINDOW_SIZE - 1) -#define IOP331_PCI_MEM_OFFSET (IOP331_PCI_LOWER_MEM_PA - IOP331_PCI_LOWER_MEM_BA) - -/* - * IOP331 chipset registers - */ -#define IOP331_VIRT_MEM_BASE 0xfeffe000 /* chip virtual mem address*/ -#define IOP331_PHYS_MEM_BASE 0xffffe000 /* chip physical memory address */ -#define IOP331_REG_ADDR(reg) (IOP331_VIRT_MEM_BASE | (reg)) - -/* Reserved 0x00000000 through 0x000000FF */ - -/* Address Translation Unit 0x00000100 through 0x000001FF */ -#define IOP331_ATUVID (volatile u16 *)IOP331_REG_ADDR(0x00000100) -#define IOP331_ATUDID (volatile u16 *)IOP331_REG_ADDR(0x00000102) -#define IOP331_ATUCMD (volatile u16 *)IOP331_REG_ADDR(0x00000104) -#define IOP331_ATUSR (volatile u16 *)IOP331_REG_ADDR(0x00000106) -#define IOP331_ATURID (volatile u8 *)IOP331_REG_ADDR(0x00000108) -#define IOP331_ATUCCR (volatile u32 *)IOP331_REG_ADDR(0x00000109) -#define IOP331_ATUCLSR (volatile u8 *)IOP331_REG_ADDR(0x0000010C) -#define IOP331_ATULT (volatile u8 *)IOP331_REG_ADDR(0x0000010D) -#define IOP331_ATUHTR (volatile u8 *)IOP331_REG_ADDR(0x0000010E) -#define IOP331_ATUBIST (volatile u8 *)IOP331_REG_ADDR(0x0000010F) -#define IOP331_IABAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000110) -#define IOP331_IAUBAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000114) -#define IOP331_IABAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000118) -#define IOP331_IAUBAR1 (volatile u32 *)IOP331_REG_ADDR(0x0000011C) -#define IOP331_IABAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000120) -#define IOP331_IAUBAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000124) -#define IOP331_ASVIR (volatile u16 *)IOP331_REG_ADDR(0x0000012C) -#define IOP331_ASIR (volatile u16 *)IOP331_REG_ADDR(0x0000012E) -#define IOP331_ERBAR (volatile u32 *)IOP331_REG_ADDR(0x00000130) -#define IOP331_ATU_CAPPTR (volatile u32 *)IOP331_REG_ADDR(0x00000134) -/* Reserved 0x00000138 through 0x0000013B */ -#define IOP331_ATUILR (volatile u8 *)IOP331_REG_ADDR(0x0000013C) -#define IOP331_ATUIPR (volatile u8 *)IOP331_REG_ADDR(0x0000013D) -#define IOP331_ATUMGNT (volatile u8 *)IOP331_REG_ADDR(0x0000013E) -#define IOP331_ATUMLAT (volatile u8 *)IOP331_REG_ADDR(0x0000013F) -#define IOP331_IALR0 (volatile u32 *)IOP331_REG_ADDR(0x00000140) -#define IOP331_IATVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000144) -#define IOP331_ERLR (volatile u32 *)IOP331_REG_ADDR(0x00000148) -#define IOP331_ERTVR (volatile u32 *)IOP331_REG_ADDR(0x0000014C) -#define IOP331_IALR1 (volatile u32 *)IOP331_REG_ADDR(0x00000150) -#define IOP331_IALR2 (volatile u32 *)IOP331_REG_ADDR(0x00000154) -#define IOP331_IATVR2 (volatile u32 *)IOP331_REG_ADDR(0x00000158) -#define IOP331_OIOWTVR (volatile u32 *)IOP331_REG_ADDR(0x0000015C) -#define IOP331_OMWTVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000160) -#define IOP331_OUMWTVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000164) -#define IOP331_OMWTVR1 (volatile u32 *)IOP331_REG_ADDR(0x00000168) -#define IOP331_OUMWTVR1 (volatile u32 *)IOP331_REG_ADDR(0x0000016C) -/* Reserved 0x00000170 through 0x00000177*/ -#define IOP331_OUDWTVR (volatile u32 *)IOP331_REG_ADDR(0x00000178) -/* Reserved 0x0000017C through 0x0000017F*/ -#define IOP331_ATUCR (volatile u32 *)IOP331_REG_ADDR(0x00000180) -#define IOP331_PCSR (volatile u32 *)IOP331_REG_ADDR(0x00000184) -#define IOP331_ATUISR (volatile u32 *)IOP331_REG_ADDR(0x00000188) -#define IOP331_ATUIMR (volatile u32 *)IOP331_REG_ADDR(0x0000018C) -#define IOP331_IABAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000190) -#define IOP331_IAUBAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000194) -#define IOP331_IALR3 (volatile u32 *)IOP331_REG_ADDR(0x00000198) -#define IOP331_IATVR3 (volatile u32 *)IOP331_REG_ADDR(0x0000019C) -/* Reserved 0x000001A0 through 0x000001A3*/ -#define IOP331_OCCAR (volatile u32 *)IOP331_REG_ADDR(0x000001A4) -/* Reserved 0x000001A8 through 0x000001AB*/ -#define IOP331_OCCDR (volatile u32 *)IOP331_REG_ADDR(0x000001AC) -/* Reserved 0x000001B0 through 0x000001BB*/ -#define IOP331_VPDCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001B8) -#define IOP331_VPDNXTP (volatile u8 *)IOP331_REG_ADDR(0x000001B9) -#define IOP331_VPDAR (volatile u16 *)IOP331_REG_ADDR(0x000001BA) -#define IOP331_VPDDR (volatile u32 *)IOP331_REG_ADDR(0x000001BC) -#define IOP331_PMCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001C0) -#define IOP331_PMNEXT (volatile u8 *)IOP331_REG_ADDR(0x000001C1) -#define IOP331_APMCR (volatile u16 *)IOP331_REG_ADDR(0x000001C2) -#define IOP331_APMCSR (volatile u16 *)IOP331_REG_ADDR(0x000001C4) -/* Reserved 0x000001C6 through 0x000001CF */ -#define IOP331_MSICAPID (volatile u8 *)IOP331_REG_ADDR(0x000001D0) -#define IOP331_MSINXTP (volatile u8 *)IOP331_REG_ADDR(0x000001D1) -#define IOP331_MSIMCR (volatile u16 *)IOP331_REG_ADDR(0x000001D2) -#define IOP331_MSIMAR (volatile u32 *)IOP331_REG_ADDR(0x000001D4) -#define IOP331_MSIMUAR (volatile u32 *)IOP331_REG_ADDR(0x000001D8) -#define IOP331_MSIMDR (volatile u32 *)IOP331_REG_ADDR(0x000001DC) -#define IOP331_PCIXCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001E0) -#define IOP331_PCIXNEXT (volatile u8 *)IOP331_REG_ADDR(0x000001E1) -#define IOP331_PCIXCMD (volatile u16 *)IOP331_REG_ADDR(0x000001E2) -#define IOP331_PCIXSR (volatile u32 *)IOP331_REG_ADDR(0x000001E4) -#define IOP331_PCIIRSR (volatile u32 *)IOP331_REG_ADDR(0x000001EC) - -/* Messaging Unit 0x00000300 through 0x000003FF */ - -/* Reserved 0x00000300 through 0x0000030c */ -#define IOP331_IMR0 (volatile u32 *)IOP331_REG_ADDR(0x00000310) -#define IOP331_IMR1 (volatile u32 *)IOP331_REG_ADDR(0x00000314) -#define IOP331_OMR0 (volatile u32 *)IOP331_REG_ADDR(0x00000318) -#define IOP331_OMR1 (volatile u32 *)IOP331_REG_ADDR(0x0000031C) -#define IOP331_IDR (volatile u32 *)IOP331_REG_ADDR(0x00000320) -#define IOP331_IISR (volatile u32 *)IOP331_REG_ADDR(0x00000324) -#define IOP331_IIMR (volatile u32 *)IOP331_REG_ADDR(0x00000328) -#define IOP331_ODR (volatile u32 *)IOP331_REG_ADDR(0x0000032C) -#define IOP331_OISR (volatile u32 *)IOP331_REG_ADDR(0x00000330) -#define IOP331_OIMR (volatile u32 *)IOP331_REG_ADDR(0x00000334) -/* Reserved 0x00000338 through 0x0000034F */ -#define IOP331_MUCR (volatile u32 *)IOP331_REG_ADDR(0x00000350) -#define IOP331_QBAR (volatile u32 *)IOP331_REG_ADDR(0x00000354) -/* Reserved 0x00000358 through 0x0000035C */ -#define IOP331_IFHPR (volatile u32 *)IOP331_REG_ADDR(0x00000360) -#define IOP331_IFTPR (volatile u32 *)IOP331_REG_ADDR(0x00000364) -#define IOP331_IPHPR (volatile u32 *)IOP331_REG_ADDR(0x00000368) -#define IOP331_IPTPR (volatile u32 *)IOP331_REG_ADDR(0x0000036C) -#define IOP331_OFHPR (volatile u32 *)IOP331_REG_ADDR(0x00000370) -#define IOP331_OFTPR (volatile u32 *)IOP331_REG_ADDR(0x00000374) -#define IOP331_OPHPR (volatile u32 *)IOP331_REG_ADDR(0x00000378) -#define IOP331_OPTPR (volatile u32 *)IOP331_REG_ADDR(0x0000037C) -#define IOP331_IAR (volatile u32 *)IOP331_REG_ADDR(0x00000380) -/* Reserved 0x00000384 through 0x000003FF */ - -/* DMA Controller 0x00000400 through 0x000004FF */ -#define IOP331_DMA0_CCR (volatile u32 *)IOP331_REG_ADDR(0x00000400) -#define IOP331_DMA0_CSR (volatile u32 *)IOP331_REG_ADDR(0x00000404) -#define IOP331_DMA0_DAR (volatile u32 *)IOP331_REG_ADDR(0x0000040C) -#define IOP331_DMA0_NDAR (volatile u32 *)IOP331_REG_ADDR(0x00000410) -#define IOP331_DMA0_PADR (volatile u32 *)IOP331_REG_ADDR(0x00000414) -#define IOP331_DMA0_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000418) -#define IOP331_DMA0_LADR (volatile u32 *)IOP331_REG_ADDR(0X0000041C) -#define IOP331_DMA0_BCR (volatile u32 *)IOP331_REG_ADDR(0x00000420) -#define IOP331_DMA0_DCR (volatile u32 *)IOP331_REG_ADDR(0x00000424) -/* Reserved 0x00000428 through 0x0000043C */ -#define IOP331_DMA1_CCR (volatile u32 *)IOP331_REG_ADDR(0x00000440) -#define IOP331_DMA1_CSR (volatile u32 *)IOP331_REG_ADDR(0x00000444) -#define IOP331_DMA1_DAR (volatile u32 *)IOP331_REG_ADDR(0x0000044C) -#define IOP331_DMA1_NDAR (volatile u32 *)IOP331_REG_ADDR(0x00000450) -#define IOP331_DMA1_PADR (volatile u32 *)IOP331_REG_ADDR(0x00000454) -#define IOP331_DMA1_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000458) -#define IOP331_DMA1_LADR (volatile u32 *)IOP331_REG_ADDR(0x0000045C) -#define IOP331_DMA1_BCR (volatile u32 *)IOP331_REG_ADDR(0x00000460) -#define IOP331_DMA1_DCR (volatile u32 *)IOP331_REG_ADDR(0x00000464) -/* Reserved 0x00000468 through 0x000004FF */ - -/* Memory controller 0x00000500 through 0x0005FF */ - -/* Peripheral bus interface unit 0x00000680 through 0x0006FF */ -#define IOP331_PBCR (volatile u32 *)IOP331_REG_ADDR(0x00000680) -#define IOP331_PBISR (volatile u32 *)IOP331_REG_ADDR(0x00000684) -#define IOP331_PBBAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000688) -#define IOP331_PBLR0 (volatile u32 *)IOP331_REG_ADDR(0x0000068C) -#define IOP331_PBBAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000690) -#define IOP331_PBLR1 (volatile u32 *)IOP331_REG_ADDR(0x00000694) -#define IOP331_PBBAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000698) -#define IOP331_PBLR2 (volatile u32 *)IOP331_REG_ADDR(0x0000069C) -#define IOP331_PBBAR3 (volatile u32 *)IOP331_REG_ADDR(0x000006A0) -#define IOP331_PBLR3 (volatile u32 *)IOP331_REG_ADDR(0x000006A4) -#define IOP331_PBBAR4 (volatile u32 *)IOP331_REG_ADDR(0x000006A8) -#define IOP331_PBLR4 (volatile u32 *)IOP331_REG_ADDR(0x000006AC) -#define IOP331_PBBAR5 (volatile u32 *)IOP331_REG_ADDR(0x000006B0) -#define IOP331_PBLR5 (volatile u32 *)IOP331_REG_ADDR(0x000006B4) -#define IOP331_PBDSCR (volatile u32 *)IOP331_REG_ADDR(0x000006B8) -/* Reserved 0x000006BC */ -#define IOP331_PMBR0 (volatile u32 *)IOP331_REG_ADDR(0x000006C0) -/* Reserved 0x000006C4 through 0x000006DC */ -#define IOP331_PMBR1 (volatile u32 *)IOP331_REG_ADDR(0x000006E0) -#define IOP331_PMBR2 (volatile u32 *)IOP331_REG_ADDR(0x000006E4) - -#define IOP331_PBCR_EN 0x1 - -#define IOP331_PBISR_BOOR_ERR 0x1 - - - -/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */ -/* Internal arbitration unit 0x00000780 through 0x0007BF */ - -/* Interrupt Controller */ -#define IOP331_INTCTL0 (volatile u32 *)IOP331_REG_ADDR(0x00000790) -#define IOP331_INTCTL1 (volatile u32 *)IOP331_REG_ADDR(0x00000794) -#define IOP331_INTSTR0 (volatile u32 *)IOP331_REG_ADDR(0x00000798) -#define IOP331_INTSTR1 (volatile u32 *)IOP331_REG_ADDR(0x0000079C) -#define IOP331_IINTSRC0 (volatile u32 *)IOP331_REG_ADDR(0x000007A0) -#define IOP331_IINTSRC1 (volatile u32 *)IOP331_REG_ADDR(0x000007A4) -#define IOP331_FINTSRC0 (volatile u32 *)IOP331_REG_ADDR(0x000007A8) -#define IOP331_FINTSRC1 (volatile u32 *)IOP331_REG_ADDR(0x000007AC) -#define IOP331_IPR0 (volatile u32 *)IOP331_REG_ADDR(0x000007B0) -#define IOP331_IPR1 (volatile u32 *)IOP331_REG_ADDR(0x000007B4) -#define IOP331_IPR2 (volatile u32 *)IOP331_REG_ADDR(0x000007B8) -#define IOP331_IPR3 (volatile u32 *)IOP331_REG_ADDR(0x000007BC) -#define IOP331_INTBASE (volatile u32 *)IOP331_REG_ADDR(0x000007C0) -#define IOP331_INTSIZE (volatile u32 *)IOP331_REG_ADDR(0x000007C4) -#define IOP331_IINTVEC (volatile u32 *)IOP331_REG_ADDR(0x000007C8) -#define IOP331_FINTVEC (volatile u32 *)IOP331_REG_ADDR(0x000007CC) - - -/* Timers */ - -#define IOP331_TU_TMR0 (volatile u32 *)IOP331_REG_ADDR(0x000007D0) -#define IOP331_TU_TMR1 (volatile u32 *)IOP331_REG_ADDR(0x000007D4) - -#define IOP331_TMR_TC 0x01 -#define IOP331_TMR_EN 0x02 -#define IOP331_TMR_RELOAD 0x04 -#define IOP331_TMR_PRIVILEGED 0x09 - -#define IOP331_TMR_RATIO_1_1 0x00 -#define IOP331_TMR_RATIO_4_1 0x10 -#define IOP331_TMR_RATIO_8_1 0x20 -#define IOP331_TMR_RATIO_16_1 0x30 - -#define IOP331_TU_TCR0 (volatile u32 *)IOP331_REG_ADDR(0x000007D8) -#define IOP331_TU_TCR1 (volatile u32 *)IOP331_REG_ADDR(0x000007DC) -#define IOP331_TU_TRR0 (volatile u32 *)IOP331_REG_ADDR(0x000007E0) -#define IOP331_TU_TRR1 (volatile u32 *)IOP331_REG_ADDR(0x000007E4) -#define IOP331_TU_TISR (volatile u32 *)IOP331_REG_ADDR(0x000007E8) -#define IOP331_TU_WDTCR (volatile u32 *)IOP331_REG_ADDR(0x000007EC) - -#if defined(CONFIG_ARCH_IOP33X) -#define IOP331_TICK_RATE 266000000 /* 266 MHz IB clock */ -#endif - -#if defined(CONFIG_IOP331_STEPD) || defined(CONFIG_ARCH_IQ80333) -#undef IOP331_TICK_RATE -#define IOP331_TICK_RATE 333000000 /* 333 Mhz IB clock */ -#endif - -/* Application accelerator unit 0x00000800 - 0x000008FF */ -#define IOP331_AAU_ACR (volatile u32 *)IOP331_REG_ADDR(0x00000800) -#define IOP331_AAU_ASR (volatile u32 *)IOP331_REG_ADDR(0x00000804) -#define IOP331_AAU_ADAR (volatile u32 *)IOP331_REG_ADDR(0x00000808) -#define IOP331_AAU_ANDAR (volatile u32 *)IOP331_REG_ADDR(0x0000080C) -#define IOP331_AAU_SAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000810) -#define IOP331_AAU_SAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000814) -#define IOP331_AAU_SAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000818) -#define IOP331_AAU_SAR4 (volatile u32 *)IOP331_REG_ADDR(0x0000081C) -#define IOP331_AAU_SAR5 (volatile u32 *)IOP331_REG_ADDR(0x0000082C) -#define IOP331_AAU_SAR6 (volatile u32 *)IOP331_REG_ADDR(0x00000830) -#define IOP331_AAU_SAR7 (volatile u32 *)IOP331_REG_ADDR(0x00000834) -#define IOP331_AAU_SAR8 (volatile u32 *)IOP331_REG_ADDR(0x00000838) -#define IOP331_AAU_SAR9 (volatile u32 *)IOP331_REG_ADDR(0x00000840) -#define IOP331_AAU_SAR10 (volatile u32 *)IOP331_REG_ADDR(0x00000844) -#define IOP331_AAU_SAR11 (volatile u32 *)IOP331_REG_ADDR(0x00000848) -#define IOP331_AAU_SAR12 (volatile u32 *)IOP331_REG_ADDR(0x0000084C) -#define IOP331_AAU_SAR13 (volatile u32 *)IOP331_REG_ADDR(0x00000850) -#define IOP331_AAU_SAR14 (volatile u32 *)IOP331_REG_ADDR(0x00000854) -#define IOP331_AAU_SAR15 (volatile u32 *)IOP331_REG_ADDR(0x00000858) -#define IOP331_AAU_SAR16 (volatile u32 *)IOP331_REG_ADDR(0x0000085C) -#define IOP331_AAU_SAR17 (volatile u32 *)IOP331_REG_ADDR(0x00000864) -#define IOP331_AAU_SAR18 (volatile u32 *)IOP331_REG_ADDR(0x00000868) -#define IOP331_AAU_SAR19 (volatile u32 *)IOP331_REG_ADDR(0x0000086C) -#define IOP331_AAU_SAR20 (volatile u32 *)IOP331_REG_ADDR(0x00000870) -#define IOP331_AAU_SAR21 (volatile u32 *)IOP331_REG_ADDR(0x00000874) -#define IOP331_AAU_SAR22 (volatile u32 *)IOP331_REG_ADDR(0x00000878) -#define IOP331_AAU_SAR23 (volatile u32 *)IOP331_REG_ADDR(0x0000087C) -#define IOP331_AAU_SAR24 (volatile u32 *)IOP331_REG_ADDR(0x00000880) -#define IOP331_AAU_SAR25 (volatile u32 *)IOP331_REG_ADDR(0x00000888) -#define IOP331_AAU_SAR26 (volatile u32 *)IOP331_REG_ADDR(0x0000088C) -#define IOP331_AAU_SAR27 (volatile u32 *)IOP331_REG_ADDR(0x00000890) -#define IOP331_AAU_SAR28 (volatile u32 *)IOP331_REG_ADDR(0x00000894) -#define IOP331_AAU_SAR29 (volatile u32 *)IOP331_REG_ADDR(0x00000898) -#define IOP331_AAU_SAR30 (volatile u32 *)IOP331_REG_ADDR(0x0000089C) -#define IOP331_AAU_SAR31 (volatile u32 *)IOP331_REG_ADDR(0x000008A0) -#define IOP331_AAU_SAR32 (volatile u32 *)IOP331_REG_ADDR(0x000008A4) -#define IOP331_AAU_DAR (volatile u32 *)IOP331_REG_ADDR(0x00000820) -#define IOP331_AAU_ABCR (volatile u32 *)IOP331_REG_ADDR(0x00000824) -#define IOP331_AAU_ADCR (volatile u32 *)IOP331_REG_ADDR(0x00000828) -#define IOP331_AAU_EDCR0 (volatile u32 *)IOP331_REG_ADDR(0x0000083c) -#define IOP331_AAU_EDCR1 (volatile u32 *)IOP331_REG_ADDR(0x00000860) -#define IOP331_AAU_EDCR2 (volatile u32 *)IOP331_REG_ADDR(0x00000884) - - -#define IOP331_SPDSCR (volatile u32 *)IOP331_REG_ADDR(0x000015C0) -#define IOP331_PPDSCR (volatile u32 *)IOP331_REG_ADDR(0x000015C8) -/* SSP serial port unit 0x00001600 - 0x0000167F */ - -/* I2C bus interface unit 0x00001680 - 0x000016FF */ -/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */ - -#define IOP331_ICR0 (volatile u32 *)IOP331_REG_ADDR(0x00001680) -#define IOP331_ISR0 (volatile u32 *)IOP331_REG_ADDR(0x00001684) -#define IOP331_ISAR0 (volatile u32 *)IOP331_REG_ADDR(0x00001688) -#define IOP331_IDBR0 (volatile u32 *)IOP331_REG_ADDR(0x0000168C) -/* Reserved 0x00001690 */ -#define IOP331_IBMR0 (volatile u32 *)IOP331_REG_ADDR(0x00001694) -/* Reserved 0x00001698 */ -/* Reserved 0x0000169C */ -#define IOP331_ICR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A0) -#define IOP331_ISR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A4) -#define IOP331_ISAR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A8) -#define IOP331_IDBR1 (volatile u32 *)IOP331_REG_ADDR(0x000016AC) -#define IOP331_IBMR1 (volatile u32 *)IOP331_REG_ADDR(0x000016B4) -/* Reserved 0x000016B8 through 0x000016FF */ - -/* 0x00001700 through 0x0000172C UART 0 */ - -/* Reserved 0x00001730 through 0x0000173F */ - -/* 0x00001740 through 0x0000176C UART 1 */ - -#define IOP331_UART0_PHYS (IOP331_PHYS_MEM_BASE | 0x00001700) /* UART #1 physical */ -#define IOP331_UART1_PHYS (IOP331_PHYS_MEM_BASE | 0x00001740) /* UART #2 physical */ -#define IOP331_UART0_VIRT (IOP331_VIRT_MEM_BASE | 0x00001700) /* UART #1 virtual addr */ -#define IOP331_UART1_VIRT (IOP331_VIRT_MEM_BASE | 0x00001740) /* UART #2 virtual addr */ - -/* Reserved 0x00001770 through 0x0000177F */ - -/* General Purpose I/O Registers */ -#define IOP331_GPOE (volatile u32 *)IOP331_REG_ADDR(0x00001780) -#define IOP331_GPID (volatile u32 *)IOP331_REG_ADDR(0x00001784) -#define IOP331_GPOD (volatile u32 *)IOP331_REG_ADDR(0x00001788) - -/* Reserved 0x0000178c through 0x000019ff */ - - -#ifndef __ASSEMBLY__ -extern void iop331_map_io(void); -extern void iop331_init_irq(void); -extern void iop331_time_init(void); -#endif - -#endif // _IOP331_HW_H_ diff --git a/include/asm-arm/arch-iop3xx/iq31244.h b/include/asm-arm/arch-iop3xx/iq31244.h deleted file mode 100644 index 4177cfa8100f..000000000000 --- a/include/asm-arm/arch-iop3xx/iq31244.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iq31244.h - * - * Intel IQ31244 evaluation board registers - */ - -#ifndef _IQ31244_H_ -#define _IQ31244_H_ - -#define IQ31244_FLASHBASE 0xf0000000 /* Flash */ -#define IQ31244_FLASHSIZE 0x00800000 -#define IQ31244_FLASHWIDTH 2 - -#define IQ31244_UART 0xfe800000 /* UART #1 */ -#define IQ31244_7SEG_1 0xfe840000 /* 7-Segment MSB */ -#define IQ31244_7SEG_0 0xfe850000 /* 7-Segment LSB (WO) */ -#define IQ31244_ROTARY_SW 0xfe8d0000 /* Rotary Switch */ -#define IQ31244_BATT_STAT 0xfe8f0000 /* Battery Status */ - -#ifndef __ASSEMBLY__ -extern void iq31244_map_io(void); -#endif - -#endif // _IQ31244_H_ diff --git a/include/asm-arm/arch-iop3xx/iq80321.h b/include/asm-arm/arch-iop3xx/iq80321.h deleted file mode 100644 index cb8725979ffa..000000000000 --- a/include/asm-arm/arch-iop3xx/iq80321.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iq80321.h - * - * Intel IQ80321 evaluation board registers - */ - -#ifndef _IQ80321_H_ -#define _IQ80321_H_ - -#define IQ80321_FLASHBASE 0xf0000000 /* Flash */ -#define IQ80321_FLASHSIZE 0x00800000 -#define IQ80321_FLASHWIDTH 1 - -#define IQ80321_UART 0xfe800000 /* UART #1 */ -#define IQ80321_7SEG_1 0xfe840000 /* 7-Segment MSB */ -#define IQ80321_7SEG_0 0xfe850000 /* 7-Segment LSB (WO) */ -#define IQ80321_ROTARY_SW 0xfe8d0000 /* Rotary Switch */ -#define IQ80321_BATT_STAT 0xfe8f0000 /* Battery Status */ - -#ifndef __ASSEMBLY__ -extern void iq80321_map_io(void); -#endif - -#endif // _IQ80321_H_ diff --git a/include/asm-arm/arch-iop3xx/iq80331.h b/include/asm-arm/arch-iop3xx/iq80331.h deleted file mode 100644 index 0668e78d483e..000000000000 --- a/include/asm-arm/arch-iop3xx/iq80331.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iq80331.h - * - * Intel IQ80331 evaluation board registers - */ - -#ifndef _IQ80331_H_ -#define _IQ80331_H_ - -#define IQ80331_FLASHBASE 0xc0000000 /* Flash */ -#define IQ80331_FLASHSIZE 0x00800000 -#define IQ80331_FLASHWIDTH 1 - -#define IQ80331_7SEG_1 0xce840000 /* 7-Segment MSB */ -#define IQ80331_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */ -#define IQ80331_ROTARY_SW 0xce8d0000 /* Rotary Switch */ -#define IQ80331_BATT_STAT 0xce8f0000 /* Battery Status */ - -#ifndef __ASSEMBLY__ -extern void iq80331_map_io(void); -#endif - -#endif // _IQ80331_H_ diff --git a/include/asm-arm/arch-iop3xx/iq80332.h b/include/asm-arm/arch-iop3xx/iq80332.h deleted file mode 100644 index e5fff1775d1a..000000000000 --- a/include/asm-arm/arch-iop3xx/iq80332.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iq80332.h - * - * Intel IQ80332 evaluation board registers - */ - -#ifndef _IQ80332_H_ -#define _IQ80332_H_ - -#define IQ80332_FLASHBASE 0xc0000000 /* Flash */ -#define IQ80332_FLASHSIZE 0x00800000 -#define IQ80332_FLASHWIDTH 1 - -#define IQ80332_7SEG_1 0xce840000 /* 7-Segment MSB */ -#define IQ80332_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */ -#define IQ80332_ROTARY_SW 0xce8d0000 /* Rotary Switch */ -#define IQ80332_BATT_STAT 0xce8f0000 /* Battery Status */ - -#ifndef __ASSEMBLY__ -extern void iq80332_map_io(void); -#endif - -#endif // _IQ80332_H_ diff --git a/include/asm-arm/arch-iop3xx/irqs.h b/include/asm-arm/arch-iop3xx/irqs.h deleted file mode 100644 index 4f7c7aa87b4a..000000000000 --- a/include/asm-arm/arch-iop3xx/irqs.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/irqs.h - * - * Copyright: (C) 2001-2003 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -/* - * Chipset-specific bits - */ -#ifdef CONFIG_ARCH_IOP32X -#include "iop321-irqs.h" -#endif - -#ifdef CONFIG_ARCH_IOP33X -#include "iop331-irqs.h" -#endif diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h deleted file mode 100644 index 25666184e8fc..000000000000 --- a/include/asm-arm/arch-iop3xx/memory.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/memory.h - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#include - -/* - * Physical DRAM offset. - */ -#ifndef CONFIG_ARCH_IOP33X -#define PHYS_OFFSET UL(0xa0000000) -#else -#define PHYS_OFFSET UL(0x00000000) -#endif - -/* - * Virtual view <-> PCI DMA view memory address translations - * virt_to_bus: Used to translate the virtual address to an - * address suitable to be passed to set_dma_addr - * bus_to_virt: Used to convert an address for DMA operations - * to an address that the kernel can use. - */ -#if defined(CONFIG_ARCH_IOP32X) - -#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP321_IATVR2)) | ((*IOP321_IABAR2) & 0xfffffff0)) -#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP321_IALR2)) | ( *IOP321_IATVR2))) - -#elif defined(CONFIG_ARCH_IOP33X) - -#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP331_IATVR2)) | ((*IOP331_IABAR2) & 0xfffffff0)) -#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP331_IALR2)) | ( *IOP331_IATVR2))) - -#endif - -#endif diff --git a/include/asm-arm/arch-iop3xx/system.h b/include/asm-arm/arch-iop3xx/system.h deleted file mode 100644 index a16cbb77a7f6..000000000000 --- a/include/asm-arm/arch-iop3xx/system.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/system.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - - -static inline void arch_reset(char mode) -{ -#ifdef CONFIG_ARCH_IOP32X - *IOP321_PCSR = 0x30; -#endif - -#ifdef CONFIG_ARCH_IOP33X - *IOP331_PCSR = 0x30; -#endif - - if ( 1 && mode == 's') { - /* Jump into ROM at address 0 */ - cpu_reset(0); - } else { - /* No on-chip reset capability */ - cpu_reset(0); - } -} - diff --git a/include/asm-arm/arch-iop3xx/timex.h b/include/asm-arm/arch-iop3xx/timex.h deleted file mode 100644 index 14ca8d0f7b29..000000000000 --- a/include/asm-arm/arch-iop3xx/timex.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/timex.h - * - * IOP3xx architecture timex specifications - */ -#include - -#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244) - -#define CLOCK_TICK_RATE IOP321_TICK_RATE - -#elif defined(CONFIG_ARCH_IQ80331) || defined(CONFIG_MACH_IQ80332) - -#define CLOCK_TICK_RATE IOP331_TICK_RATE - -#else - -#error "No IOP3xx timex information for this architecture" - -#endif diff --git a/include/asm-arm/arch-iop3xx/uncompress.h b/include/asm-arm/arch-iop3xx/uncompress.h deleted file mode 100644 index 066c16bc1250..000000000000 --- a/include/asm-arm/arch-iop3xx/uncompress.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/uncompress.h - */ -#include -#include -#include -#include - -#ifdef CONFIG_ARCH_IOP32X -#define UTYPE unsigned char * -#elif defined(CONFIG_ARCH_IOP33X) -#define UTYPE u32 * -#else -#error "Missing IOP3xx arch type def" -#endif - -static volatile UTYPE uart_base; - -#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE) - -static inline void putc(char c) -{ - while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE) - barrier(); - *uart_base = c; -} - -static inline void flush(void) -{ -} - -static __inline__ void __arch_decomp_setup(unsigned long arch_id) -{ - if(machine_is_iq80321()) - uart_base = (volatile UTYPE)IQ80321_UART; - else if(machine_is_iq31244()) - uart_base = (volatile UTYPE)IQ31244_UART; - else if(machine_is_iq80331() || machine_is_iq80332()) - uart_base = (volatile UTYPE)IOP331_UART0_PHYS; - else - uart_base = (volatile UTYPE)0xfe800000; -} - -/* - * nothing to do - */ -#define arch_decomp_setup() __arch_decomp_setup(arch_id) -#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-iop3xx/vmalloc.h b/include/asm-arm/arch-iop3xx/vmalloc.h deleted file mode 100644 index 0f2f6847f93c..000000000000 --- a/include/asm-arm/arch-iop3xx/vmalloc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/vmalloc.h - */ - -/* - * Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8MB value just means that there will be a 8MB "hole" after the - * physical memory until the kernel virtual memory starts. That means that - * any out-of-bounds memory accesses will hopefully be caught. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - */ -//#define VMALLOC_END (0xe8000000) -/* increase usable physical RAM to ~992M per RMK */ -#define VMALLOC_END (0xfe000000) - -- cgit v1.2.3-70-g09d2 From a71ebdfa5243765e455a9ec2d6360e1704c6599e Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Thu, 21 Sep 2006 03:57:04 +0100 Subject: [ARM] 3853/1: Fix flush_ptrace_access() thinko for nonaliasing VIPT cache case Fix thinko in the flush_ptrace_access() "if (expr)" for the ARM VIPT non-aliasing cache case. We only need to flush cache when VM_EXEC is set in vma->vm_flags but "if (expr) always evaluates to true on UP systems for the ARM VIPT non-aliasing cache case. Signed-off-by: George G. Davis Signed-off-by: Russell King --- arch/arm/mm/flush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 1efb05c64db3..454205b789d5 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -107,7 +107,7 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, /* VIPT non-aliasing cache */ if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask) && - vma->vm_flags | VM_EXEC) { + vma->vm_flags & VM_EXEC) { unsigned long addr = (unsigned long)kaddr; /* only flushing the kernel mapping on non-aliasing VIPT */ __cpuc_coherent_kern_range(addr, addr + len); -- cgit v1.2.3-70-g09d2 From 4052ebb7a2729bd7c28260cdf8e470c0d81b9c56 Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Fri, 22 Sep 2006 18:36:38 +0100 Subject: [ARM] 3859/1: Fix devicemaps_init() XIP_KERNEL odd 1MiB XIP_PHYS_ADDR translation error The ARM XIP_KERNEL map created in devicemaps_init() is wrong. The map.pfn is rounded down to an even 1MiB section boundary which results in va/pa translations errors when XIP_PHYS_ADDR starts on an odd 1MiB boundary and this causes the kernel to hang. This patch fixes ARM XIP_KERNEL translation errors for the odd 1MiB XIP_PHYS_ADDR boundary case. Signed-off-by: George G. Davis Signed-off-by: Russell King --- arch/arm/mm/init.c | 4 ++-- include/asm-arm/pgtable.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 1099af6d470a..64262bda8e54 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -434,9 +434,9 @@ static void __init devicemaps_init(struct machine_desc *mdesc) * It is always first in the modulearea. */ #ifdef CONFIG_XIP_KERNEL - map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK); + map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); map.virtual = MODULE_START; - map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK; + map.length = ((unsigned long)&_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK; map.type = MT_ROM; create_mapping(&map); #endif diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h index 8d3919c6458c..38b2b55688e2 100644 --- a/include/asm-arm/pgtable.h +++ b/include/asm-arm/pgtable.h @@ -135,6 +135,13 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define FIRST_USER_PGD_NR 1 #define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR) +/* + * section address mask and size definitions. + */ +#define SECTION_SHIFT 20 +#define SECTION_SIZE (1UL << SECTION_SHIFT) +#define SECTION_MASK (~(SECTION_SIZE-1)) + /* * ARMv6 supersection address mask and size definitions. */ -- cgit v1.2.3-70-g09d2 From 456335e2072fb35bf290b45e61d51916c322c145 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Sep 2006 10:00:54 +0100 Subject: [ARM] Separate page table manipulation code from bootmem initialisation nommu does not require the page table manipulation code in the bootmem initialisation paths. Move this into separate inline functions. Signed-off-by: Russell King --- arch/arm/mm/init.c | 73 +++++++++++++++++++++++++++++-------------------- include/asm-arm/setup.h | 12 ++++---- 2 files changed, 51 insertions(+), 34 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 64262bda8e54..83145d1d3389 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -226,6 +226,44 @@ static __init void reserve_node_zero(pg_data_t *pgdat) reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); } +static inline void prepare_page_table(struct meminfo *mi) +{ + unsigned long addr; + + /* + * Clear out all the mappings below the kernel image. + */ + for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + +#ifdef CONFIG_XIP_KERNEL + /* The XIP kernel is mapped in the module area -- skip over it */ + addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; +#endif + for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Clear out all the kernel space mappings, except for the first + * memory bank, up to the end of the vmalloc region. + */ + for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); + addr < VMALLOC_END; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); +} + +static inline void map_memory_bank(struct membank *bank) +{ + struct map_desc map; + + map.pfn = __phys_to_pfn(bank->start); + map.virtual = __phys_to_virt(bank->start); + map.length = bank->size; + map.type = MT_MEMORY; + + create_mapping(&map); +} + static unsigned long __init bootmem_init_node(int node, int initrd_node, struct meminfo *mi) { @@ -242,23 +280,18 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) * Calculate the pfn range, and map the memory banks for this node. */ for_each_nodebank(i, mi, node) { + struct membank *bank = &mi->bank[i]; unsigned long start, end; - struct map_desc map; - start = mi->bank[i].start >> PAGE_SHIFT; - end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT; + start = bank->start >> PAGE_SHIFT; + end = (bank->start + bank->size) >> PAGE_SHIFT; if (start_pfn > start) start_pfn = start; if (end_pfn < end) end_pfn = end; - map.pfn = __phys_to_pfn(mi->bank[i].start); - map.virtual = __phys_to_virt(mi->bank[i].start); - map.length = mi->bank[i].size; - map.type = MT_MEMORY; - - create_mapping(&map); + map_memory_bank(bank); } /* @@ -342,7 +375,7 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) static void __init bootmem_init(struct meminfo *mi) { - unsigned long addr, memend_pfn = 0; + unsigned long memend_pfn = 0; int node, initrd_node, i; /* @@ -354,25 +387,7 @@ static void __init bootmem_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); - /* - * Clear out all the mappings below the kernel image. - */ - for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); -#ifdef CONFIG_XIP_KERNEL - /* The XIP kernel is mapped in the module area -- skip over it */ - addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; -#endif - for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* - * Clear out all the kernel space mappings, except for the first - * memory bank, up to the end of the vmalloc region. - */ - for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); - addr < VMALLOC_END; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); + prepare_page_table(mi); /* * Locate which node contains the ramdisk image, if any. diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h index ea3ed2465233..aa4b5782f0c9 100644 --- a/include/asm-arm/setup.h +++ b/include/asm-arm/setup.h @@ -194,13 +194,15 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn } # define NR_BANKS 8 #endif +struct membank { + unsigned long start; + unsigned long size; + int node; +}; + struct meminfo { int nr_banks; - struct { - unsigned long start; - unsigned long size; - int node; - } bank[NR_BANKS]; + struct membank bank[NR_BANKS]; }; /* -- cgit v1.2.3-70-g09d2 From d111e8f9644aa585c1a7e198d74a4d2682ef1374 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Sep 2006 15:27:33 +0100 Subject: [ARM] Split ARM MM initialisation for !mmu Move the MMU specific code from init.c into mmu.c, and add nommu fixups to nommu.c Signed-off-by: Russell King --- arch/arm/mm/Makefile | 2 +- arch/arm/mm/init.c | 209 +--------------------------------------------- arch/arm/mm/mm.h | 4 + arch/arm/mm/mmu.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/nommu.c | 36 ++++++++ 5 files changed, 274 insertions(+), 206 deletions(-) create mode 100644 arch/arm/mm/mmu.c (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 1a1563f859af..cabaa3b30548 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -6,7 +6,7 @@ obj-y := consistent.o extable.o fault.o init.o \ iomap.o obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ - mm-armv.o + mm-armv.o mmu.o ifneq ($(CONFIG_MMU),y) obj-y += nommu.o diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 83145d1d3389..22217fe2650b 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -27,10 +27,7 @@ #include "mm.h" -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); - -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern void _stext, _text, _etext, __data_start, _end, __init_begin, __init_end; +extern void _text, _etext, __data_start, _end, __init_begin, __init_end; extern unsigned long phys_initrd_start; extern unsigned long phys_initrd_size; @@ -40,17 +37,6 @@ extern unsigned long phys_initrd_size; */ static struct meminfo meminfo __initdata = { 0, }; -/* - * empty_zero_page is a special page that is used for - * zero-initialized data and COW. - */ -struct page *empty_zero_page; - -/* - * The pmd table for the upper-most set of pages. - */ -pmd_t *top_pmd; - void show_mem(void) { int free = 0, total = 0, reserved = 0; @@ -173,87 +159,9 @@ static int __init check_initrd(struct meminfo *mi) return initrd_node; } -/* - * Reserve the various regions of node 0 - */ -static __init void reserve_node_zero(pg_data_t *pgdat) -{ - unsigned long res_size = 0; - - /* - * Register the kernel text and data with bootmem. - * Note that this can only be in node 0. - */ -#ifdef CONFIG_XIP_KERNEL - reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); -#else - reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); -#endif - - /* - * Reserve the page tables. These are already in use, - * and can only be in node 0. - */ - reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), - PTRS_PER_PGD * sizeof(pgd_t)); - - /* - * Hmm... This should go elsewhere, but we really really need to - * stop things allocating the low memory; ideally we need a better - * implementation of GFP_DMA which does not assume that DMA-able - * memory starts at zero. - */ - if (machine_is_integrator() || machine_is_cintegrator()) - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; - - /* - * These should likewise go elsewhere. They pre-reserve the - * screen memory region at the start of main system memory. - */ - if (machine_is_edb7211()) - res_size = 0x00020000; - if (machine_is_p720t()) - res_size = 0x00014000; - -#ifdef CONFIG_SA1111 - /* - * Because of the SA1111 DMA bug, we want to preserve our - * precious DMA-able memory... - */ - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; -#endif - if (res_size) - reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); -} - -static inline void prepare_page_table(struct meminfo *mi) -{ - unsigned long addr; - - /* - * Clear out all the mappings below the kernel image. - */ - for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - -#ifdef CONFIG_XIP_KERNEL - /* The XIP kernel is mapped in the module area -- skip over it */ - addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; -#endif - for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* - * Clear out all the kernel space mappings, except for the first - * memory bank, up to the end of the vmalloc region. - */ - for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); - addr < VMALLOC_END; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); -} - static inline void map_memory_bank(struct membank *bank) { +#ifdef CONFIG_MMU struct map_desc map; map.pfn = __phys_to_pfn(bank->start); @@ -262,6 +170,7 @@ static inline void map_memory_bank(struct membank *bank) map.type = MT_MEMORY; create_mapping(&map); +#endif } static unsigned long __init @@ -373,7 +282,7 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) return end_pfn; } -static void __init bootmem_init(struct meminfo *mi) +void __init bootmem_init(struct meminfo *mi) { unsigned long memend_pfn = 0; int node, initrd_node, i; @@ -387,8 +296,6 @@ static void __init bootmem_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); - prepare_page_table(mi); - /* * Locate which node contains the ramdisk image, if any. */ @@ -422,114 +329,6 @@ static void __init bootmem_init(struct meminfo *mi) max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET; } -/* - * Set up device the mappings. Since we clear out the page tables for all - * mappings above VMALLOC_END, we will remove any debug device mappings. - * This means you have to be careful how you debug this function, or any - * called function. This means you can't use any function or debugging - * method which may touch any device, otherwise the kernel _will_ crash. - */ -static void __init devicemaps_init(struct machine_desc *mdesc) -{ - struct map_desc map; - unsigned long addr; - void *vectors; - - /* - * Allocate the vector page early. - */ - vectors = alloc_bootmem_low_pages(PAGE_SIZE); - BUG_ON(!vectors); - - for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* - * Map the kernel if it is XIP. - * It is always first in the modulearea. - */ -#ifdef CONFIG_XIP_KERNEL - map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); - map.virtual = MODULE_START; - map.length = ((unsigned long)&_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK; - map.type = MT_ROM; - create_mapping(&map); -#endif - - /* - * Map the cache flushing regions. - */ -#ifdef FLUSH_BASE - map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); - map.virtual = FLUSH_BASE; - map.length = SZ_1M; - map.type = MT_CACHECLEAN; - create_mapping(&map); -#endif -#ifdef FLUSH_BASE_MINICACHE - map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); - map.virtual = FLUSH_BASE_MINICACHE; - map.length = SZ_1M; - map.type = MT_MINICLEAN; - create_mapping(&map); -#endif - - /* - * Create a mapping for the machine vectors at the high-vectors - * location (0xffff0000). If we aren't using high-vectors, also - * create a mapping at the low-vectors virtual address. - */ - map.pfn = __phys_to_pfn(virt_to_phys(vectors)); - map.virtual = 0xffff0000; - map.length = PAGE_SIZE; - map.type = MT_HIGH_VECTORS; - create_mapping(&map); - - if (!vectors_high()) { - map.virtual = 0; - map.type = MT_LOW_VECTORS; - create_mapping(&map); - } - - /* - * Ask the machine support to map in the statically mapped devices. - */ - if (mdesc->map_io) - mdesc->map_io(); - - /* - * Finally flush the caches and tlb to ensure that we're in a - * consistent state wrt the writebuffer. This also ensures that - * any write-allocated cache lines in the vector page are written - * back. After this point, we can start to touch devices again. - */ - local_flush_tlb_all(); - flush_cache_all(); -} - -/* - * paging_init() sets up the page tables, initialises the zone memory - * maps, and sets up the zero page, bad page and bad page tables. - */ -void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) -{ - void *zero_page; - - build_mem_type_table(); - bootmem_init(mi); - devicemaps_init(mdesc); - - top_pmd = pmd_off_k(0xffff0000); - - /* - * allocate the zero page. Note that we count on this going ok. - */ - zero_page = alloc_bootmem_low_pages(PAGE_SIZE); - memzero(zero_page, PAGE_SIZE); - empty_zero_page = virt_to_page(zero_page); - flush_dcache_page(empty_zero_page); -} - static inline void free_area(unsigned long addr, unsigned long end, char *s) { unsigned int size = (end - addr) >> 10; diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 8d73ffbce8df..083c51d3903f 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -14,6 +14,10 @@ static inline pmd_t *pmd_off_k(unsigned long virt) } struct map_desc; +struct meminfo; +struct pglist_data; void __init build_mem_type_table(void); void __init create_mapping(struct map_desc *md); +void __init bootmem_init(struct meminfo *mi); +void reserve_node_zero(struct pglist_data *pgdat); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c new file mode 100644 index 000000000000..9648e6800ffe --- /dev/null +++ b/arch/arm/mm/mmu.c @@ -0,0 +1,229 @@ +/* + * linux/arch/arm/mm/mmu.c + * + * Copyright (C) 1995-2005 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "mm.h" + +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); + +extern void _stext, __data_start, _end; +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +/* + * empty_zero_page is a special page that is used for + * zero-initialized data and COW. + */ +struct page *empty_zero_page; + +/* + * The pmd table for the upper-most set of pages. + */ +pmd_t *top_pmd; + +static inline void prepare_page_table(struct meminfo *mi) +{ + unsigned long addr; + + /* + * Clear out all the mappings below the kernel image. + */ + for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + +#ifdef CONFIG_XIP_KERNEL + /* The XIP kernel is mapped in the module area -- skip over it */ + addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; +#endif + for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Clear out all the kernel space mappings, except for the first + * memory bank, up to the end of the vmalloc region. + */ + for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); + addr < VMALLOC_END; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); +} + +/* + * Reserve the various regions of node 0 + */ +void __init reserve_node_zero(pg_data_t *pgdat) +{ + unsigned long res_size = 0; + + /* + * Register the kernel text and data with bootmem. + * Note that this can only be in node 0. + */ +#ifdef CONFIG_XIP_KERNEL + reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); +#else + reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); +#endif + + /* + * Reserve the page tables. These are already in use, + * and can only be in node 0. + */ + reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), + PTRS_PER_PGD * sizeof(pgd_t)); + + /* + * Hmm... This should go elsewhere, but we really really need to + * stop things allocating the low memory; ideally we need a better + * implementation of GFP_DMA which does not assume that DMA-able + * memory starts at zero. + */ + if (machine_is_integrator() || machine_is_cintegrator()) + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + + /* + * These should likewise go elsewhere. They pre-reserve the + * screen memory region at the start of main system memory. + */ + if (machine_is_edb7211()) + res_size = 0x00020000; + if (machine_is_p720t()) + res_size = 0x00014000; + +#ifdef CONFIG_SA1111 + /* + * Because of the SA1111 DMA bug, we want to preserve our + * precious DMA-able memory... + */ + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; +#endif + if (res_size) + reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); +} + +/* + * Set up device the mappings. Since we clear out the page tables for all + * mappings above VMALLOC_END, we will remove any debug device mappings. + * This means you have to be careful how you debug this function, or any + * called function. This means you can't use any function or debugging + * method which may touch any device, otherwise the kernel _will_ crash. + */ +static void __init devicemaps_init(struct machine_desc *mdesc) +{ + struct map_desc map; + unsigned long addr; + void *vectors; + + /* + * Allocate the vector page early. + */ + vectors = alloc_bootmem_low_pages(PAGE_SIZE); + BUG_ON(!vectors); + + for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Map the kernel if it is XIP. + * It is always first in the modulearea. + */ +#ifdef CONFIG_XIP_KERNEL + map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); + map.virtual = MODULE_START; + map.length = ((unsigned long)&_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK; + map.type = MT_ROM; + create_mapping(&map); +#endif + + /* + * Map the cache flushing regions. + */ +#ifdef FLUSH_BASE + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); + map.virtual = FLUSH_BASE; + map.length = SZ_1M; + map.type = MT_CACHECLEAN; + create_mapping(&map); +#endif +#ifdef FLUSH_BASE_MINICACHE + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); + map.virtual = FLUSH_BASE_MINICACHE; + map.length = SZ_1M; + map.type = MT_MINICLEAN; + create_mapping(&map); +#endif + + /* + * Create a mapping for the machine vectors at the high-vectors + * location (0xffff0000). If we aren't using high-vectors, also + * create a mapping at the low-vectors virtual address. + */ + map.pfn = __phys_to_pfn(virt_to_phys(vectors)); + map.virtual = 0xffff0000; + map.length = PAGE_SIZE; + map.type = MT_HIGH_VECTORS; + create_mapping(&map); + + if (!vectors_high()) { + map.virtual = 0; + map.type = MT_LOW_VECTORS; + create_mapping(&map); + } + + /* + * Ask the machine support to map in the statically mapped devices. + */ + if (mdesc->map_io) + mdesc->map_io(); + + /* + * Finally flush the caches and tlb to ensure that we're in a + * consistent state wrt the writebuffer. This also ensures that + * any write-allocated cache lines in the vector page are written + * back. After this point, we can start to touch devices again. + */ + local_flush_tlb_all(); + flush_cache_all(); +} + +/* + * paging_init() sets up the page tables, initialises the zone memory + * maps, and sets up the zero page, bad page and bad page tables. + */ +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) +{ + void *zero_page; + + build_mem_type_table(); + prepare_page_table(mi); + bootmem_init(mi); + devicemaps_init(mdesc); + + top_pmd = pmd_off_k(0xffff0000); + + /* + * allocate the zero page. Note that we count on this going ok. + */ + zero_page = alloc_bootmem_low_pages(PAGE_SIZE); + memzero(zero_page, PAGE_SIZE); + empty_zero_page = virt_to_page(zero_page); + flush_dcache_page(empty_zero_page); +} diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 1464ed817b5d..e369aeb0c25c 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -11,6 +11,42 @@ #include #include +#include "mm.h" + +extern void _stext, __data_start, _end; + +/* + * Reserve the various regions of node 0 + */ +void __init reserve_node_zero(pg_data_t *pgdat) +{ + /* + * Register the kernel text and data with bootmem. + * Note that this can only be in node 0. + */ +#ifdef CONFIG_XIP_KERNEL + reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); +#else + reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); +#endif + + /* + * Register the exception vector page. + * some architectures which the DRAM is the exception vector to trap, + * alloc_page breaks with error, although it is not NULL, but "0." + */ + reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE); +} + +/* + * paging_init() sets up the page tables, initialises the zone memory + * maps, and sets up the zero page, bad page and bad page tables. + */ +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) +{ + bootmem_init(mi); +} + void flush_dcache_page(struct page *page) { __cpuc_flush_dcache_page(page_address(page)); -- cgit v1.2.3-70-g09d2 From ae8f154129e4d965771c2d6adbe36210b3913d72 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Sep 2006 15:38:34 +0100 Subject: [ARM] Move rest of MMU setup code from mm-armv.c to mmu.c If we're going to have mmu.c for code which is specific to the MMU machines, we might as well move the other MMU initialisation specific code from mm-armv.c into this new file. This also allows us to make some functions static. Signed-off-by: Russell King --- arch/arm/mm/mm-armv.c | 550 -------------------------------------------------- arch/arm/mm/mm.h | 1 - arch/arm/mm/mmu.c | 542 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 542 insertions(+), 551 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index ee9647823fad..a35d5f2ee4e0 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -9,137 +9,15 @@ * * Page table sludge for ARM v3 and v4 processor architectures. */ -#include #include -#include -#include #include -#include #include #include -#include #include -#include - #include "mm.h" -#define CPOLICY_UNCACHED 0 -#define CPOLICY_BUFFERED 1 -#define CPOLICY_WRITETHROUGH 2 -#define CPOLICY_WRITEBACK 3 -#define CPOLICY_WRITEALLOC 4 - -static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; -static unsigned int ecc_mask __initdata = 0; -pgprot_t pgprot_kernel; - -EXPORT_SYMBOL(pgprot_kernel); - -struct cachepolicy { - const char policy[16]; - unsigned int cr_mask; - unsigned int pmd; - unsigned int pte; -}; - -static struct cachepolicy cache_policies[] __initdata = { - { - .policy = "uncached", - .cr_mask = CR_W|CR_C, - .pmd = PMD_SECT_UNCACHED, - .pte = 0, - }, { - .policy = "buffered", - .cr_mask = CR_C, - .pmd = PMD_SECT_BUFFERED, - .pte = PTE_BUFFERABLE, - }, { - .policy = "writethrough", - .cr_mask = 0, - .pmd = PMD_SECT_WT, - .pte = PTE_CACHEABLE, - }, { - .policy = "writeback", - .cr_mask = 0, - .pmd = PMD_SECT_WB, - .pte = PTE_BUFFERABLE|PTE_CACHEABLE, - }, { - .policy = "writealloc", - .cr_mask = 0, - .pmd = PMD_SECT_WBWA, - .pte = PTE_BUFFERABLE|PTE_CACHEABLE, - } -}; - -/* - * These are useful for identifing cache coherency - * problems by allowing the cache or the cache and - * writebuffer to be turned off. (Note: the write - * buffer should not be on and the cache off). - */ -static void __init early_cachepolicy(char **p) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(cache_policies); i++) { - int len = strlen(cache_policies[i].policy); - - if (memcmp(*p, cache_policies[i].policy, len) == 0) { - cachepolicy = i; - cr_alignment &= ~cache_policies[i].cr_mask; - cr_no_alignment &= ~cache_policies[i].cr_mask; - *p += len; - break; - } - } - if (i == ARRAY_SIZE(cache_policies)) - printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); - flush_cache_all(); - set_cr(cr_alignment); -} - -static void __init early_nocache(char **__unused) -{ - char *p = "buffered"; - printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); - early_cachepolicy(&p); -} - -static void __init early_nowrite(char **__unused) -{ - char *p = "uncached"; - printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); - early_cachepolicy(&p); -} - -static void __init early_ecc(char **p) -{ - if (memcmp(*p, "on", 2) == 0) { - ecc_mask = PMD_PROTECTION; - *p += 2; - } else if (memcmp(*p, "off", 3) == 0) { - ecc_mask = 0; - *p += 3; - } -} - -__early_param("nocache", early_nocache); -__early_param("nowb", early_nowrite); -__early_param("cachepolicy=", early_cachepolicy); -__early_param("ecc=", early_ecc); - -static int __init noalign_setup(char *__unused) -{ - cr_alignment &= ~CR_A; - cr_no_alignment &= ~CR_A; - set_cr(cr_alignment); - return 1; -} - -__setup("noalign", noalign_setup); - #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) /* @@ -223,431 +101,3 @@ void free_pgd_slow(pgd_t *pgd) free: free_pages((unsigned long) pgd, 2); } - -/* - * Create a SECTION PGD between VIRT and PHYS in domain - * DOMAIN with protection PROT. This operates on half- - * pgdir entry increments. - */ -static inline void -alloc_init_section(unsigned long virt, unsigned long phys, int prot) -{ - pmd_t *pmdp = pmd_off_k(virt); - - if (virt & (1 << 20)) - pmdp++; - - *pmdp = __pmd(phys | prot); - flush_pmd_entry(pmdp); -} - -/* - * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT - */ -static inline void -alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) -{ - int i; - - for (i = 0; i < 16; i += 1) { - alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); - - virt += (PGDIR_SIZE / 2); - } -} - -/* - * Add a PAGE mapping between VIRT and PHYS in domain - * DOMAIN with protection PROT. Note that due to the - * way we map the PTEs, we must allocate two PTE_SIZE'd - * blocks - one for the Linux pte table, and one for - * the hardware pte table. - */ -static inline void -alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) -{ - pmd_t *pmdp = pmd_off_k(virt); - pte_t *ptep; - - if (pmd_none(*pmdp)) { - ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * - sizeof(pte_t)); - - __pmd_populate(pmdp, __pa(ptep) | prot_l1); - } - ptep = pte_offset_kernel(pmdp, virt); - - set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); -} - -struct mem_types { - unsigned int prot_pte; - unsigned int prot_l1; - unsigned int prot_sect; - unsigned int domain; -}; - -static struct mem_types mem_types[] __initdata = { - [MT_DEVICE] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, - }, - [MT_CACHECLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, - .domain = DOMAIN_KERNEL, - }, - [MT_MINICLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, - .domain = DOMAIN_KERNEL, - }, - [MT_LOW_VECTORS] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_EXEC, - .prot_l1 = PMD_TYPE_TABLE, - .domain = DOMAIN_USER, - }, - [MT_HIGH_VECTORS] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_USER | L_PTE_EXEC, - .prot_l1 = PMD_TYPE_TABLE, - .domain = DOMAIN_USER, - }, - [MT_MEMORY] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, - .domain = DOMAIN_KERNEL, - }, - [MT_ROM] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, - .domain = DOMAIN_KERNEL, - }, - [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | - PMD_SECT_TEX(1), - .domain = DOMAIN_IO, - }, - [MT_NONSHARED_DEVICE] = { - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, - } -}; - -/* - * Adjust the PMD section entries according to the CPU in use. - */ -void __init build_mem_type_table(void) -{ - struct cachepolicy *cp; - unsigned int cr = get_cr(); - unsigned int user_pgprot, kern_pgprot; - int cpu_arch = cpu_architecture(); - int i; - -#if defined(CONFIG_CPU_DCACHE_DISABLE) - if (cachepolicy > CPOLICY_BUFFERED) - cachepolicy = CPOLICY_BUFFERED; -#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) - if (cachepolicy > CPOLICY_WRITETHROUGH) - cachepolicy = CPOLICY_WRITETHROUGH; -#endif - if (cpu_arch < CPU_ARCH_ARMv5) { - if (cachepolicy >= CPOLICY_WRITEALLOC) - cachepolicy = CPOLICY_WRITEBACK; - ecc_mask = 0; - } - - /* - * Xscale must not have PMD bit 4 set for section mappings. - */ - if (cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) - mem_types[i].prot_sect &= ~PMD_BIT4; - - /* - * ARMv5 and lower, excluding Xscale, bit 4 must be set for - * page tables. - */ - if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) - if (mem_types[i].prot_l1) - mem_types[i].prot_l1 |= PMD_BIT4; - - cp = &cache_policies[cachepolicy]; - kern_pgprot = user_pgprot = cp->pte; - - /* - * Enable CPU-specific coherency if supported. - * (Only available on XSC3 at the moment.) - */ - if (arch_is_coherent()) { - if (cpu_is_xsc3()) { - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; - } - } - - /* - * ARMv6 and above have extended page tables. - */ - if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { - /* - * bit 4 becomes XN which we must clear for the - * kernel memory mapping. - */ - mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; - mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; - - /* - * Mark cache clean areas and XIP ROM read only - * from SVC mode and no access from userspace. - */ - mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - - /* - * Mark the device area as "shared device" - */ - mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; - mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; - - /* - * User pages need to be mapped with the ASID - * (iow, non-global) - */ - user_pgprot |= L_PTE_ASID; - -#ifdef CONFIG_SMP - /* - * Mark memory with the "shared" attribute for SMP systems - */ - user_pgprot |= L_PTE_SHARED; - kern_pgprot |= L_PTE_SHARED; - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; -#endif - } - - for (i = 0; i < 16; i++) { - unsigned long v = pgprot_val(protection_map[i]); - v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; - protection_map[i] = __pgprot(v); - } - - mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; - mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; - - if (cpu_arch >= CPU_ARCH_ARMv5) { -#ifndef CONFIG_SMP - /* - * Only use write-through for non-SMP systems - */ - mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; - mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; -#endif - } else { - mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); - } - - pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | - L_PTE_DIRTY | L_PTE_WRITE | - L_PTE_EXEC | kern_pgprot); - - mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; - mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; - mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; - mem_types[MT_ROM].prot_sect |= cp->pmd; - - switch (cp->pmd) { - case PMD_SECT_WT: - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; - break; - case PMD_SECT_WB: - case PMD_SECT_WBWA: - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; - break; - } - printk("Memory policy: ECC %sabled, Data cache %s\n", - ecc_mask ? "en" : "dis", cp->policy); -} - -#define vectors_base() (vectors_high() ? 0xffff0000 : 0) - -/* - * Create the page directory entries and any necessary - * page tables for the mapping specified by `md'. We - * are able to cope here with varying sizes and address - * offsets, and we take full advantage of sections and - * supersections. - */ -void __init create_mapping(struct map_desc *md) -{ - unsigned long virt, length; - int prot_sect, prot_l1, domain; - pgprot_t prot_pte; - unsigned long off = (u32)__pfn_to_phys(md->pfn); - - if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { - printk(KERN_WARNING "BUG: not creating mapping for " - "0x%08llx at 0x%08lx in user region\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - - if ((md->type == MT_DEVICE || md->type == MT_ROM) && - md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { - printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " - "overlaps vmalloc space\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - } - - domain = mem_types[md->type].domain; - prot_pte = __pgprot(mem_types[md->type].prot_pte); - prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); - prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); - - /* - * Catch 36-bit addresses - */ - if(md->pfn >= 0x100000) { - if(domain) { - printk(KERN_ERR "MM: invalid domain in supersection " - "mapping for 0x%08llx at 0x%08lx\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - if((md->virtual | md->length | __pfn_to_phys(md->pfn)) - & ~SUPERSECTION_MASK) { - printk(KERN_ERR "MM: cannot create mapping for " - "0x%08llx at 0x%08lx invalid alignment\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - - /* - * Shift bits [35:32] of address into bits [23:20] of PMD - * (See ARMv6 spec). - */ - off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); - } - - virt = md->virtual; - off -= virt; - length = md->length; - - if (mem_types[md->type].prot_l1 == 0 && - (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { - printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " - "be mapped using pages, ignoring.\n", - __pfn_to_phys(md->pfn), md->virtual); - return; - } - - while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); - - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } - - /* N.B. ARMv6 supersections are only defined to work with domain 0. - * Since domain assignments can in fact be arbitrary, the - * 'domain == 0' check below is required to insure that ARMv6 - * supersections are only allocated for domain 0 regardless - * of the actual domain assignments in use. - */ - if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) - && domain == 0) { - /* - * Align to supersection boundary if !high pages. - * High pages have already been checked for proper - * alignment above and they will fail the SUPSERSECTION_MASK - * check because of the way the address is encoded into - * offset. - */ - if (md->pfn <= 0x100000) { - while ((virt & ~SUPERSECTION_MASK || - (virt + off) & ~SUPERSECTION_MASK) && - length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } - } - - while (length >= SUPERSECTION_SIZE) { - alloc_init_supersection(virt, virt + off, prot_sect); - - virt += SUPERSECTION_SIZE; - length -= SUPERSECTION_SIZE; - } - } - - /* - * A section mapping covers half a "pgdir" entry. - */ - while (length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } - - while (length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); - - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } -} - -/* - * In order to soft-boot, we need to insert a 1:1 mapping in place of - * the user-mode pages. This will then ensure that we have predictable - * results when turning the mmu off - */ -void setup_mm_for_reboot(char mode) -{ - unsigned long base_pmdval; - pgd_t *pgd; - int i; - - if (current->mm && current->mm->pgd) - pgd = current->mm->pgd; - else - pgd = init_mm.pgd; - - base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; - if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) - base_pmdval |= PMD_BIT4; - - for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { - unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval; - pmd_t *pmd; - - pmd = pmd_off(pgd, i << PGDIR_SHIFT); - pmd[0] = __pmd(pmdval); - pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); - flush_pmd_entry(pmd); - } -} - -/* - * Create the architecture specific mappings - */ -void __init iotable_init(struct map_desc *io_desc, int nr) -{ - int i; - - for (i = 0; i < nr; i++) - create_mapping(io_desc + i); -} diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 083c51d3903f..bb2bc9ab6bd3 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -17,7 +17,6 @@ struct map_desc; struct meminfo; struct pglist_data; -void __init build_mem_type_table(void); void __init create_mapping(struct map_desc *md); void __init bootmem_init(struct meminfo *mi); void reserve_node_zero(struct pglist_data *pgdat); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9648e6800ffe..e566cbe4b222 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include @@ -40,6 +41,516 @@ struct page *empty_zero_page; */ pmd_t *top_pmd; +#define CPOLICY_UNCACHED 0 +#define CPOLICY_BUFFERED 1 +#define CPOLICY_WRITETHROUGH 2 +#define CPOLICY_WRITEBACK 3 +#define CPOLICY_WRITEALLOC 4 + +static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; +static unsigned int ecc_mask __initdata = 0; +pgprot_t pgprot_kernel; + +EXPORT_SYMBOL(pgprot_kernel); + +struct cachepolicy { + const char policy[16]; + unsigned int cr_mask; + unsigned int pmd; + unsigned int pte; +}; + +static struct cachepolicy cache_policies[] __initdata = { + { + .policy = "uncached", + .cr_mask = CR_W|CR_C, + .pmd = PMD_SECT_UNCACHED, + .pte = 0, + }, { + .policy = "buffered", + .cr_mask = CR_C, + .pmd = PMD_SECT_BUFFERED, + .pte = PTE_BUFFERABLE, + }, { + .policy = "writethrough", + .cr_mask = 0, + .pmd = PMD_SECT_WT, + .pte = PTE_CACHEABLE, + }, { + .policy = "writeback", + .cr_mask = 0, + .pmd = PMD_SECT_WB, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + }, { + .policy = "writealloc", + .cr_mask = 0, + .pmd = PMD_SECT_WBWA, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + } +}; + +/* + * These are useful for identifing cache coherency + * problems by allowing the cache or the cache and + * writebuffer to be turned off. (Note: the write + * buffer should not be on and the cache off). + */ +static void __init early_cachepolicy(char **p) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache_policies); i++) { + int len = strlen(cache_policies[i].policy); + + if (memcmp(*p, cache_policies[i].policy, len) == 0) { + cachepolicy = i; + cr_alignment &= ~cache_policies[i].cr_mask; + cr_no_alignment &= ~cache_policies[i].cr_mask; + *p += len; + break; + } + } + if (i == ARRAY_SIZE(cache_policies)) + printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); + flush_cache_all(); + set_cr(cr_alignment); +} +__early_param("cachepolicy=", early_cachepolicy); + +static void __init early_nocache(char **__unused) +{ + char *p = "buffered"; + printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} +__early_param("nocache", early_nocache); + +static void __init early_nowrite(char **__unused) +{ + char *p = "uncached"; + printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} +__early_param("nowb", early_nowrite); + +static void __init early_ecc(char **p) +{ + if (memcmp(*p, "on", 2) == 0) { + ecc_mask = PMD_PROTECTION; + *p += 2; + } else if (memcmp(*p, "off", 3) == 0) { + ecc_mask = 0; + *p += 3; + } +} +__early_param("ecc=", early_ecc); + +static int __init noalign_setup(char *__unused) +{ + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; + set_cr(cr_alignment); + return 1; +} +__setup("noalign", noalign_setup); + +struct mem_types { + unsigned int prot_pte; + unsigned int prot_l1; + unsigned int prot_sect; + unsigned int domain; +}; + +static struct mem_types mem_types[] __initdata = { + [MT_DEVICE] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + }, + [MT_CACHECLEAN] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .domain = DOMAIN_KERNEL, + }, + [MT_MINICLEAN] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, + .domain = DOMAIN_KERNEL, + }, + [MT_LOW_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_HIGH_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_MEMORY] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, + .domain = DOMAIN_KERNEL, + }, + [MT_ROM] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .domain = DOMAIN_KERNEL, + }, + [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | + PMD_SECT_TEX(1), + .domain = DOMAIN_IO, + }, + [MT_NONSHARED_DEVICE] = { + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + } +}; + +/* + * Adjust the PMD section entries according to the CPU in use. + */ +static void __init build_mem_type_table(void) +{ + struct cachepolicy *cp; + unsigned int cr = get_cr(); + unsigned int user_pgprot, kern_pgprot; + int cpu_arch = cpu_architecture(); + int i; + +#if defined(CONFIG_CPU_DCACHE_DISABLE) + if (cachepolicy > CPOLICY_BUFFERED) + cachepolicy = CPOLICY_BUFFERED; +#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) + if (cachepolicy > CPOLICY_WRITETHROUGH) + cachepolicy = CPOLICY_WRITETHROUGH; +#endif + if (cpu_arch < CPU_ARCH_ARMv5) { + if (cachepolicy >= CPOLICY_WRITEALLOC) + cachepolicy = CPOLICY_WRITEBACK; + ecc_mask = 0; + } + + /* + * Xscale must not have PMD bit 4 set for section mappings. + */ + if (cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) + mem_types[i].prot_sect &= ~PMD_BIT4; + + /* + * ARMv5 and lower, excluding Xscale, bit 4 must be set for + * page tables. + */ + if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) + if (mem_types[i].prot_l1) + mem_types[i].prot_l1 |= PMD_BIT4; + + cp = &cache_policies[cachepolicy]; + kern_pgprot = user_pgprot = cp->pte; + + /* + * Enable CPU-specific coherency if supported. + * (Only available on XSC3 at the moment.) + */ + if (arch_is_coherent()) { + if (cpu_is_xsc3()) { + mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; + } + } + + /* + * ARMv6 and above have extended page tables. + */ + if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { + /* + * bit 4 becomes XN which we must clear for the + * kernel memory mapping. + */ + mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; + mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; + + /* + * Mark cache clean areas and XIP ROM read only + * from SVC mode and no access from userspace. + */ + mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + + /* + * Mark the device area as "shared device" + */ + mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; + mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; + + /* + * User pages need to be mapped with the ASID + * (iow, non-global) + */ + user_pgprot |= L_PTE_ASID; + +#ifdef CONFIG_SMP + /* + * Mark memory with the "shared" attribute for SMP systems + */ + user_pgprot |= L_PTE_SHARED; + kern_pgprot |= L_PTE_SHARED; + mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; +#endif + } + + for (i = 0; i < 16; i++) { + unsigned long v = pgprot_val(protection_map[i]); + v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; + protection_map[i] = __pgprot(v); + } + + mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; + mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; + + if (cpu_arch >= CPU_ARCH_ARMv5) { +#ifndef CONFIG_SMP + /* + * Only use write-through for non-SMP systems + */ + mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; + mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; +#endif + } else { + mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); + } + + pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | + L_PTE_DIRTY | L_PTE_WRITE | + L_PTE_EXEC | kern_pgprot); + + mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; + mem_types[MT_ROM].prot_sect |= cp->pmd; + + switch (cp->pmd) { + case PMD_SECT_WT: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; + break; + case PMD_SECT_WB: + case PMD_SECT_WBWA: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; + break; + } + printk("Memory policy: ECC %sabled, Data cache %s\n", + ecc_mask ? "en" : "dis", cp->policy); +} + +#define vectors_base() (vectors_high() ? 0xffff0000 : 0) + +/* + * Create a SECTION PGD between VIRT and PHYS in domain + * DOMAIN with protection PROT. This operates on half- + * pgdir entry increments. + */ +static inline void +alloc_init_section(unsigned long virt, unsigned long phys, int prot) +{ + pmd_t *pmdp = pmd_off_k(virt); + + if (virt & (1 << 20)) + pmdp++; + + *pmdp = __pmd(phys | prot); + flush_pmd_entry(pmdp); +} + +/* + * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT + */ +static inline void +alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) +{ + int i; + + for (i = 0; i < 16; i += 1) { + alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); + + virt += (PGDIR_SIZE / 2); + } +} + +/* + * Add a PAGE mapping between VIRT and PHYS in domain + * DOMAIN with protection PROT. Note that due to the + * way we map the PTEs, we must allocate two PTE_SIZE'd + * blocks - one for the Linux pte table, and one for + * the hardware pte table. + */ +static inline void +alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) +{ + pmd_t *pmdp = pmd_off_k(virt); + pte_t *ptep; + + if (pmd_none(*pmdp)) { + ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * + sizeof(pte_t)); + + __pmd_populate(pmdp, __pa(ptep) | prot_l1); + } + ptep = pte_offset_kernel(pmdp, virt); + + set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); +} + +/* + * Create the page directory entries and any necessary + * page tables for the mapping specified by `md'. We + * are able to cope here with varying sizes and address + * offsets, and we take full advantage of sections and + * supersections. + */ +void __init create_mapping(struct map_desc *md) +{ + unsigned long virt, length; + int prot_sect, prot_l1, domain; + pgprot_t prot_pte; + unsigned long off = (u32)__pfn_to_phys(md->pfn); + + if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { + printk(KERN_WARNING "BUG: not creating mapping for " + "0x%08llx at 0x%08lx in user region\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + if ((md->type == MT_DEVICE || md->type == MT_ROM) && + md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { + printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " + "overlaps vmalloc space\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + } + + domain = mem_types[md->type].domain; + prot_pte = __pgprot(mem_types[md->type].prot_pte); + prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); + prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); + + /* + * Catch 36-bit addresses + */ + if(md->pfn >= 0x100000) { + if(domain) { + printk(KERN_ERR "MM: invalid domain in supersection " + "mapping for 0x%08llx at 0x%08lx\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + if((md->virtual | md->length | __pfn_to_phys(md->pfn)) + & ~SUPERSECTION_MASK) { + printk(KERN_ERR "MM: cannot create mapping for " + "0x%08llx at 0x%08lx invalid alignment\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + /* + * Shift bits [35:32] of address into bits [23:20] of PMD + * (See ARMv6 spec). + */ + off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); + } + + virt = md->virtual; + off -= virt; + length = md->length; + + if (mem_types[md->type].prot_l1 == 0 && + (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { + printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " + "be mapped using pages, ignoring.\n", + __pfn_to_phys(md->pfn), md->virtual); + return; + } + + while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } + + /* N.B. ARMv6 supersections are only defined to work with domain 0. + * Since domain assignments can in fact be arbitrary, the + * 'domain == 0' check below is required to insure that ARMv6 + * supersections are only allocated for domain 0 regardless + * of the actual domain assignments in use. + */ + if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) + && domain == 0) { + /* + * Align to supersection boundary if !high pages. + * High pages have already been checked for proper + * alignment above and they will fail the SUPSERSECTION_MASK + * check because of the way the address is encoded into + * offset. + */ + if (md->pfn <= 0x100000) { + while ((virt & ~SUPERSECTION_MASK || + (virt + off) & ~SUPERSECTION_MASK) && + length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + } + + while (length >= SUPERSECTION_SIZE) { + alloc_init_supersection(virt, virt + off, prot_sect); + + virt += SUPERSECTION_SIZE; + length -= SUPERSECTION_SIZE; + } + } + + /* + * A section mapping covers half a "pgdir" entry. + */ + while (length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + + while (length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } +} + +/* + * Create the architecture specific mappings + */ +void __init iotable_init(struct map_desc *io_desc, int nr) +{ + int i; + + for (i = 0; i < nr; i++) + create_mapping(io_desc + i); +} + static inline void prepare_page_table(struct meminfo *mi) { unsigned long addr; @@ -227,3 +738,34 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) empty_zero_page = virt_to_page(zero_page); flush_dcache_page(empty_zero_page); } + +/* + * In order to soft-boot, we need to insert a 1:1 mapping in place of + * the user-mode pages. This will then ensure that we have predictable + * results when turning the mmu off + */ +void setup_mm_for_reboot(char mode) +{ + unsigned long base_pmdval; + pgd_t *pgd; + int i; + + if (current->mm && current->mm->pgd) + pgd = current->mm->pgd; + else + pgd = init_mm.pgd; + + base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; + if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) + base_pmdval |= PMD_BIT4; + + for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { + unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval; + pmd_t *pmd; + + pmd = pmd_off(pgd, i << PGDIR_SHIFT); + pmd[0] = __pmd(pmdval); + pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); + flush_pmd_entry(pmd); + } +} -- cgit v1.2.3-70-g09d2 From 0c668984ddff94f800b37f244d7b21074b04b971 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Sep 2006 15:40:28 +0100 Subject: [ARM] Rename mm-armv.c to pgd.c mm-armv.c now only contains the pgd allocation/freeing code, so rename it to have a more sensible filename. Signed-off-by: Russell King --- arch/arm/mm/Makefile | 2 +- arch/arm/mm/mm-armv.c | 103 -------------------------------------------------- arch/arm/mm/pgd.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 104 deletions(-) delete mode 100644 arch/arm/mm/mm-armv.c create mode 100644 arch/arm/mm/pgd.c (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index cabaa3b30548..2d0ab19db496 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -6,7 +6,7 @@ obj-y := consistent.o extable.o fault.o init.o \ iomap.o obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ - mm-armv.o mmu.o + pgd.o mmu.o ifneq ($(CONFIG_MMU),y) obj-y += nommu.o diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c deleted file mode 100644 index a35d5f2ee4e0..000000000000 --- a/arch/arm/mm/mm-armv.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * linux/arch/arm/mm/mm-armv.c - * - * Copyright (C) 1998-2005 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Page table sludge for ARM v3 and v4 processor architectures. - */ -#include -#include - -#include -#include -#include - -#include "mm.h" - -#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) - -/* - * need to get a 16k page for level 1 - */ -pgd_t *get_pgd_slow(struct mm_struct *mm) -{ - pgd_t *new_pgd, *init_pgd; - pmd_t *new_pmd, *init_pmd; - pte_t *new_pte, *init_pte; - - new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); - if (!new_pgd) - goto no_pgd; - - memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); - - /* - * Copy over the kernel and IO PGD entries - */ - init_pgd = pgd_offset_k(0); - memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, - (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); - - clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); - - if (!vectors_high()) { - /* - * On ARM, first page must always be allocated since it - * contains the machine vectors. - */ - new_pmd = pmd_alloc(mm, new_pgd, 0); - if (!new_pmd) - goto no_pmd; - - new_pte = pte_alloc_map(mm, new_pmd, 0); - if (!new_pte) - goto no_pte; - - init_pmd = pmd_offset(init_pgd, 0); - init_pte = pte_offset_map_nested(init_pmd, 0); - set_pte(new_pte, *init_pte); - pte_unmap_nested(init_pte); - pte_unmap(new_pte); - } - - return new_pgd; - -no_pte: - pmd_free(new_pmd); -no_pmd: - free_pages((unsigned long)new_pgd, 2); -no_pgd: - return NULL; -} - -void free_pgd_slow(pgd_t *pgd) -{ - pmd_t *pmd; - struct page *pte; - - if (!pgd) - return; - - /* pgd is always present and good */ - pmd = pmd_off(pgd, 0); - if (pmd_none(*pmd)) - goto free; - if (pmd_bad(*pmd)) { - pmd_ERROR(*pmd); - pmd_clear(pmd); - goto free; - } - - pte = pmd_page(*pmd); - pmd_clear(pmd); - dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); - pte_lock_deinit(pte); - pte_free(pte); - pmd_free(pmd); -free: - free_pages((unsigned long) pgd, 2); -} diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c new file mode 100644 index 000000000000..20c1b0df75f2 --- /dev/null +++ b/arch/arm/mm/pgd.c @@ -0,0 +1,101 @@ +/* + * linux/arch/arm/mm/pgd.c + * + * Copyright (C) 1998-2005 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include + +#include +#include +#include + +#include "mm.h" + +#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) + +/* + * need to get a 16k page for level 1 + */ +pgd_t *get_pgd_slow(struct mm_struct *mm) +{ + pgd_t *new_pgd, *init_pgd; + pmd_t *new_pmd, *init_pmd; + pte_t *new_pte, *init_pte; + + new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); + if (!new_pgd) + goto no_pgd; + + memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); + + /* + * Copy over the kernel and IO PGD entries + */ + init_pgd = pgd_offset_k(0); + memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + + clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); + + if (!vectors_high()) { + /* + * On ARM, first page must always be allocated since it + * contains the machine vectors. + */ + new_pmd = pmd_alloc(mm, new_pgd, 0); + if (!new_pmd) + goto no_pmd; + + new_pte = pte_alloc_map(mm, new_pmd, 0); + if (!new_pte) + goto no_pte; + + init_pmd = pmd_offset(init_pgd, 0); + init_pte = pte_offset_map_nested(init_pmd, 0); + set_pte(new_pte, *init_pte); + pte_unmap_nested(init_pte); + pte_unmap(new_pte); + } + + return new_pgd; + +no_pte: + pmd_free(new_pmd); +no_pmd: + free_pages((unsigned long)new_pgd, 2); +no_pgd: + return NULL; +} + +void free_pgd_slow(pgd_t *pgd) +{ + pmd_t *pmd; + struct page *pte; + + if (!pgd) + return; + + /* pgd is always present and good */ + pmd = pmd_off(pgd, 0); + if (pmd_none(*pmd)) + goto free; + if (pmd_bad(*pmd)) { + pmd_ERROR(*pmd); + pmd_clear(pmd); + goto free; + } + + pte = pmd_page(*pmd); + pmd_clear(pmd); + dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); + pte_lock_deinit(pte); + pte_free(pte); + pmd_free(pmd); +free: + free_pages((unsigned long) pgd, 2); +} -- cgit v1.2.3-70-g09d2 From 80878d6c4ab8611a0edf139a7f8a7a64860b87c9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Sep 2006 15:43:47 +0100 Subject: [ARM] Add setup_mm_for_reboot() for nommu Add an empty setup_mm_for_reboot() function for nommu machines. Signed-off-by: Russell King --- arch/arm/mm/nommu.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index e369aeb0c25c..d0e66424a597 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -47,6 +47,13 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) bootmem_init(mi); } +/* + * We don't need to do anything here for nommu machines. + */ +void setup_mm_for_reboot(char mode) +{ +} + void flush_dcache_page(struct page *page) { __cpuc_flush_dcache_page(page_address(page)); -- cgit v1.2.3-70-g09d2 From e5beac371af0af47bcbd6819f4c2a0a2721a1735 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Sep 2006 16:13:48 +0100 Subject: [ARM] do_bad_area() always takes current and current->active_mm Since do_bad_area() always takes the currently active task and (supposed to) take the currently active MM, there's no point passing them to this function. Instead, obtain references to them inside do_bad_area(). Signed-off-by: Russell King --- arch/arm/mm/alignment.c | 2 +- arch/arm/mm/fault.c | 15 ++++++--------- arch/arm/mm/fault.h | 5 +---- 3 files changed, 8 insertions(+), 14 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index e0d21bbbe7d7..aa109f074dd9 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -735,7 +735,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) /* * We got a fault - fix it up, or die. */ - do_bad_area(current, current->mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; swp: diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index c5e0622c7765..f0943d160ffe 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -131,10 +131,11 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, force_sig_info(sig, &si, tsk); } -void -do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr, - unsigned int fsr, struct pt_regs *regs) +void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->active_mm; + /* * If we are in kernel mode at this point, we * have no context to handle this fault with. @@ -319,7 +320,6 @@ static int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - struct task_struct *tsk; unsigned int index; pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; @@ -351,9 +351,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr, return 0; bad_area: - tsk = current; - - do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; } @@ -364,8 +362,7 @@ bad_area: static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - struct task_struct *tsk = current; - do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; } diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h index 73b59e83227f..49e9e3804de4 100644 --- a/arch/arm/mm/fault.h +++ b/arch/arm/mm/fault.h @@ -1,6 +1,3 @@ -void do_bad_area(struct task_struct *tsk, struct mm_struct *mm, - unsigned long addr, unsigned int fsr, struct pt_regs *regs); - -void show_pte(struct mm_struct *mm, unsigned long addr); +void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs); unsigned long search_exception_table(unsigned long addr); -- cgit v1.2.3-70-g09d2 From fefdaa06ccdde394be865ed76509be82813e425b Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Tue, 26 Sep 2006 17:36:37 +0900 Subject: [ARM] nommu: defines CPU_CP15, CPU_CP15_MMU and CPU_CP15_MPU By merging of uClinux/ARM, we need to treat various CPU cores which have MMU, MPU or even none for memory management. The memory management coprocessors are controlled by CP15 register set and the ARM core family can be categorized by 5 groups by the register ; G-a. CP15 is MMU : 610, 710, 720, 920, 922, 925, 926, 1020, 1020e, 1022, v6 and the derivations sa1100, sa110, xscale, xsc3. G-b. CP15 is MPU : 740, 940, 946, 996, 1156. G-c. CP15 is MPU or MMU : 1026 (selectable by schematic design) G-d. CP15 is exist, but nothing for memory managemnt : 966, 968. G-e. no-CP15 : 7tdmi, 9tdmi, 9e, 9ej This patch defines CPU_CP15, CPU_CP15_MMU and CPU_CP15_MPU. Thus the family can be defined as : - CPU_CP15 only : G-d - CPU_CP15_MMU(implies CPU_CP15) : G-a, G-c(selectable) - CPU_CP15_MPU(implies CPU_CP15) : G-b, G-c(selectable) - !CPU_CP15 : G-e Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index b59c74100a84..c7fb835c148c 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -15,6 +15,7 @@ config CPU_ARM610 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V3 if MMU select CPU_TLB_V3 if MMU help @@ -31,6 +32,7 @@ config CPU_ARM710 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V3 if MMU select CPU_TLB_V3 if MMU help @@ -50,6 +52,7 @@ config CPU_ARM720T select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WT if MMU select CPU_TLB_V4WT if MMU help @@ -68,6 +71,7 @@ config CPU_ARM920T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -89,6 +93,7 @@ config CPU_ARM922T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -108,6 +113,7 @@ config CPU_ARM925T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -126,6 +132,7 @@ config CPU_ARM926T select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -144,6 +151,7 @@ config CPU_ARM1020 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -161,6 +169,7 @@ config CPU_ARM1020E select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU depends on n @@ -172,6 +181,7 @@ config CPU_ARM1022 select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better select CPU_TLB_V4WBI if MMU help @@ -189,6 +199,7 @@ config CPU_ARM1026 select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better select CPU_TLB_V4WBI if MMU help @@ -207,6 +218,7 @@ config CPU_SA110 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WB if MMU help @@ -227,6 +239,7 @@ config CPU_SA1100 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_TLB_V4WB if MMU # XScale @@ -237,6 +250,7 @@ config CPU_XSCALE select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_TLB_V4WBI if MMU # XScale Core Version 3 @@ -247,6 +261,7 @@ config CPU_XSC3 select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_TLB_V4WBI if MMU select IO_36 @@ -258,6 +273,7 @@ config CPU_V6 select CPU_ABRT_EV6 select CPU_CACHE_V6 select CPU_CACHE_VIPT + select CPU_CP15_MMU select CPU_COPY_V6 if MMU select CPU_TLB_V6 if MMU @@ -380,6 +396,23 @@ config CPU_TLB_V6 endif +config CPU_CP15 + bool + help + Processor has the CP15 register. + +config CPU_CP15_MMU + bool + select CPU_CP15 + help + Processor has the CP15 register, which has MMU related registers. + +config CPU_CP15_MPU + bool + select CPU_CP15 + help + Processor has the CP15 register, which has MPU related registers. + # # CPU supports 36-bit I/O # -- cgit v1.2.3-70-g09d2 From f12d0d7c7786af39435ef6ae9defe47fb58f6091 Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Tue, 26 Sep 2006 17:36:37 +0900 Subject: [ARM] nommu: manage the CP15 things All the current CP15 access codes in ARM arch can be categorized and conditioned by the defines as follows: Related operation Safe condition a. any CP15 access !CPU_CP15 b. alignment trap CPU_CP15_MMU c. D-cache(C-bit) CPU_CP15 d. I-cache CPU_CP15 && !( CPU_ARM610 || CPU_ARM710 || CPU_ARM720 || CPU_ARM740 || CPU_XSCALE || CPU_XSC3 ) e. alternate vector CPU_CP15 && !CPU_ARM740 f. TTB CPU_CP15_MMU g. Domain CPU_CP15_MMU h. FSR/FAR CPU_CP15_MMU For example, alternate vector is supported if and only if "CPU_CP15 && !CPU_ARM740" is satisfied. Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/Kconfig | 3 ++- arch/arm/Kconfig-nommu | 8 ++++++++ arch/arm/boot/compressed/Makefile | 4 ++++ arch/arm/boot/compressed/head.S | 6 ++++++ arch/arm/kernel/head-nommu.S | 7 ++++++- arch/arm/kernel/process.c | 22 ++++++++++++++++------ arch/arm/mm/Kconfig | 8 ++++---- arch/arm/mm/cache-v4.S | 10 ++++++++++ include/asm-arm/system.h | 4 ++++ 9 files changed, 60 insertions(+), 12 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0810d27c039e..2673fee3281c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -621,6 +621,7 @@ config LEDS_CPU config ALIGNMENT_TRAP bool + depends on CPU_CP15_MMU default y if !ARCH_EBSA110 help ARM processors can not fetch/store information which is not @@ -852,7 +853,7 @@ source "drivers/base/Kconfig" source "drivers/connector/Kconfig" -if ALIGNMENT_TRAP +if ALIGNMENT_TRAP || !CPU_CP15_MMU source "drivers/mtd/Kconfig" endif diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu index e1574be2ded6..f087376748d1 100644 --- a/arch/arm/Kconfig-nommu +++ b/arch/arm/Kconfig-nommu @@ -25,6 +25,14 @@ config FLASH_SIZE hex 'FLASH Size' if SET_MEM_PARAM default 0x00400000 +config PROCESSOR_ID + hex + default 0x00007700 + depends on !CPU_CP15 + help + If processor has no CP15 register, this processor ID is + used instead of the auto-probing which utilizes the register. + config REMAP_VECTORS_TO_RAM bool 'Install vectors to the begining of RAM' if DRAM_BASE depends on DRAM_BASE diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 2adc1527e0eb..adddc7131685 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -51,7 +51,11 @@ OBJS += head-at91rm9200.o endif ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) +ifeq ($(CONFIG_CPU_CP15),y) OBJS += big-endian.o +else +# The endian should be set by h/w design. +endif endif # diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 75df1f764a10..e5ab51b9cceb 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -82,9 +82,11 @@ kphex r6, 8 /* processor id */ kputc #':' kphex r7, 8 /* architecture id */ +#ifdef CONFIG_CPU_CP15 kputc #':' mrc p15, 0, r0, c1, c0 kphex r0, 8 /* control reg */ +#endif kputc #'\n' kphex r5, 8 /* decompressed kernel start */ kputc #'-' @@ -507,7 +509,11 @@ call_kernel: bl cache_clean_flush */ call_cache_fn: adr r12, proc_types +#ifdef CONFIG_CPU_CP15 mrc p15, 0, r6, c0, c0 @ get processor ID +#else + ldr r6, =CONFIG_PROCESSOR_ID +#endif 1: ldr r1, [r12, #0] @ get value ldr r2, [r12, #4] @ get mask eor r1, r1, r6 @ (real ^ match) diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index ac9eb3d30518..698a537915dd 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -9,7 +9,6 @@ * published by the Free Software Foundation. * * Common kernel startup code (non-paged MM) - * for 32-bit CPUs which has a process ID register(CP15). * */ #include @@ -40,7 +39,11 @@ ENTRY(stext) msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode @ and irqs disabled +#ifndef CONFIG_CPU_CP15 + ldr r9, =CONFIG_PROCESSOR_ID +#else mrc p15, 0, r9, c0, c0 @ get processor id +#endif bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? beq __error_p @ yes, error 'p' @@ -58,6 +61,7 @@ ENTRY(stext) */ .type __after_proc_init, %function __after_proc_init: +#ifdef CONFIG_CPU_CP15 mrc p15, 0, r0, c1, c0, 0 @ read control reg #ifdef CONFIG_ALIGNMENT_TRAP orr r0, r0, #CR_A @@ -74,6 +78,7 @@ __after_proc_init: bic r0, r0, #CR_I #endif mcr p15, 0, r0, c1, c0, 0 @ write control reg +#endif /* CONFIG_CPU_CP15 */ mov pc, r13 @ clear the BSS and jump @ to start_kernel diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 3079535afccd..bf35c178a877 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -221,16 +221,26 @@ void __show_regs(struct pt_regs *regs) processor_modes[processor_mode(regs)], thumb_mode(regs) ? " (T)" : "", get_fs() == get_ds() ? "kernel" : "user"); +#if CONFIG_CPU_CP15 { - unsigned int ctrl, transbase, dac; + unsigned int ctrl; __asm__ ( " mrc p15, 0, %0, c1, c0\n" - " mrc p15, 0, %1, c2, c0\n" - " mrc p15, 0, %2, c3, c0\n" - : "=r" (ctrl), "=r" (transbase), "=r" (dac)); - printk("Control: %04X Table: %08X DAC: %08X\n", - ctrl, transbase, dac); + : "=r" (ctrl)); + printk("Control: %04X\n", ctrl); } +#ifdef CONFIG_CPU_CP15_MMU + { + unsigned int transbase, dac; + __asm__ ( + " mrc p15, 0, %0, c2, c0\n" + " mrc p15, 0, %1, c3, c0\n" + : "=r" (transbase), "=r" (dac)); + printk("Table: %08X DAC: %08X\n", + transbase, dac); + } +#endif +#endif } void show_regs(struct pt_regs * regs) diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c7fb835c148c..0ac11ea84508 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -445,15 +445,15 @@ config CPU_BIG_ENDIAN of your chipset/board/processor. config CPU_ICACHE_DISABLE - bool "Disable I-Cache" - depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 + bool "Disable I-Cache (I-bit)" + depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) help Say Y here to disable the processor instruction cache. Unless you have a reason not to or are unsure, say N. config CPU_DCACHE_DISABLE - bool "Disable D-Cache" - depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 + bool "Disable D-Cache (C-bit)" + depends on CPU_CP15 help Say Y here to disable the processor data cache. Unless you have a reason not to or are unsure, say N. diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index b8ad5d58ebe2..b2908063ed6a 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S @@ -29,9 +29,13 @@ ENTRY(v4_flush_user_cache_all) * Clean and invalidate the entire cache. */ ENTRY(v4_flush_kern_cache_all) +#ifdef CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache mov pc, lr +#else + /* FALLTHROUGH */ +#endif /* * flush_user_cache_range(start, end, flags) @@ -44,9 +48,13 @@ ENTRY(v4_flush_kern_cache_all) * - flags - vma_area_struct flags describing address space */ ENTRY(v4_flush_user_cache_range) +#ifdef CPU_CP15 mov ip, #0 mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache mov pc, lr +#else + /* FALLTHROUGH */ +#endif /* * coherent_kern_range(start, end) @@ -108,8 +116,10 @@ ENTRY(v4_dma_inv_range) * - end - virtual end address */ ENTRY(v4_dma_flush_range) +#ifdef CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache +#endif /* FALLTHROUGH */ /* diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index c19c5b009f71..f05fbe31576c 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -46,6 +46,7 @@ #define CPUID_TCM 2 #define CPUID_TLBTYPE 3 +#ifdef CONFIG_CPU_CP15 #define read_cpuid(reg) \ ({ \ unsigned int __val; \ @@ -55,6 +56,9 @@ : "cc"); \ __val; \ }) +#else +#define read_cpuid(reg) (processor_id) +#endif /* * This is used to ensure the compiler did actually allocate the register we -- cgit v1.2.3-70-g09d2 From 07e0da78abdc679714a12e7a60137d950c346681 Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Tue, 26 Sep 2006 17:37:36 +0900 Subject: [ARM] nommu: add ARM7TDMI core support This patch adds ARM7TDMI core support which has no cache and no CP15 register(no memory control unit). Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/Makefile | 1 + arch/arm/mm/Kconfig | 13 +++ arch/arm/mm/Makefile | 1 + arch/arm/mm/proc-arm7tdmi.S | 249 +++++++++++++++++++++++++++++++++++++++++++ include/asm-arm/cacheflush.h | 2 +- include/asm-arm/proc-fns.h | 8 ++ 6 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mm/proc-arm7tdmi.S (limited to 'arch/arm/mm') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 80cee786500c..282333fe0a74 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -55,6 +55,7 @@ arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 # This selects how we optimise for the processor. tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 +tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 0ac11ea84508..9f860aa9c908 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -25,6 +25,19 @@ config CPU_ARM610 Say Y if you want support for the ARM610 processor. Otherwise, say N. +# ARM7TDMI +config CPU_ARM7TDMI + bool "Support ARM7TDMI processor" + select CPU_32v4T + select CPU_ABRT_LV4T + select CPU_CACHE_V4 + help + A 32-bit RISC microprocessor based on the ARM7 processor core + which has no memory control unit and cache. + + Say Y if you want support for the ARM7TDMI processor. + Otherwise, say N. + # ARM710 config CPU_ARM710 bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 2d0ab19db496..908f6d437174 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o +obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S new file mode 100644 index 000000000000..22d7e3100ea6 --- /dev/null +++ b/arch/arm/mm/proc-arm7tdmi.S @@ -0,0 +1,249 @@ +/* + * linux/arch/arm/mm/proc-arm7tdmi.S: utility functions for ARM7TDMI + * + * Copyright (C) 2003-2006 Hyok S. Choi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + + .text +/* + * cpu_arm7tdmi_proc_init() + * cpu_arm7tdmi_do_idle() + * cpu_arm7tdmi_dcache_clean_area() + * cpu_arm7tdmi_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm7tdmi_proc_init) +ENTRY(cpu_arm7tdmi_do_idle) +ENTRY(cpu_arm7tdmi_dcache_clean_area) +ENTRY(cpu_arm7tdmi_switch_mm) + mov pc, lr + +/* + * cpu_arm7tdmi_proc_fin() + */ +ENTRY(cpu_arm7tdmi_proc_fin) + mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, r0 + mov pc, lr + +/* + * Function: cpu_arm7tdmi_reset(loc) + * Params : loc(r0) address to jump to + * Purpose : Sets up everything for a reset and jump to the location for soft reset. + */ +ENTRY(cpu_arm7tdmi_reset) + mov pc, r0 + + __INIT + + .type __arm7tdmi_setup, #function +__arm7tdmi_setup: + mov pc, lr + .size __arm7tdmi_setup, . - __arm7tdmi_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm7tdmi_processor_functions, #object +ENTRY(arm7tdmi_processor_functions) + .word v4t_late_abort + .word cpu_arm7tdmi_proc_init + .word cpu_arm7tdmi_proc_fin + .word cpu_arm7tdmi_reset + .word cpu_arm7tdmi_do_idle + .word cpu_arm7tdmi_dcache_clean_area + .word cpu_arm7tdmi_switch_mm + .word 0 @ cpu_*_set_pte + .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm7tdmi_name, #object +cpu_arm7tdmi_name: + .asciz "ARM7TDMI" + .size cpu_arm7tdmi_name, . - cpu_arm7tdmi_name + + .type cpu_triscenda7_name, #object +cpu_triscenda7_name: + .asciz "Triscend-A7x" + .size cpu_triscenda7_name, . - cpu_triscenda7_name + + .type cpu_at91_name, #object +cpu_at91_name: + .asciz "Atmel-AT91M40xxx" + .size cpu_at91_name, . - cpu_at91_name + + .type cpu_s3c3410_name, #object +cpu_s3c3410_name: + .asciz "Samsung-S3C3410" + .size cpu_s3c3410_name, . - cpu_s3c3410_name + + .type cpu_s3c44b0x_name, #object +cpu_s3c44b0x_name: + .asciz "Samsung-S3C44B0x" + .size cpu_s3c44b0x_name, . - cpu_s3c44b0x_name + + .type cpu_s3c4510b, #object +cpu_s3c4510b_name: + .asciz "Samsung-S3C4510B" + .size cpu_s3c4510b_name, . - cpu_s3c4510b_name + + .type cpu_s3c4530_name, #object +cpu_s3c4530_name: + .asciz "Samsung-S3C4530" + .size cpu_s3c4530_name, . - cpu_s3c4530_name + + .type cpu_netarm_name, #object +cpu_netarm_name: + .asciz "NETARM" + .size cpu_netarm_name, . - cpu_netarm_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + + .type __arm7tdmi_proc_info, #object +__arm7tdmi_proc_info: + .long 0x41007700 + .long 0xfff8ff00 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_26BIT + .long cpu_arm7tdmi_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __arm7tdmi_proc_info, . - __arm7dmi_proc_info + + .type __triscenda7_proc_info, #object +__triscenda7_proc_info: + .long 0x0001d2ff + .long 0x0001ffff + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_triscenda7_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __triscenda7_proc_info, . - __triscenda7_proc_info + + .type __at91_proc_info, #object +__at91_proc_info: + .long 0x14000040 + .long 0xfff000e0 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_at91_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __at91_proc_info, . - __at91_proc_info + + .type __s3c4510b_proc_info, #object +__s3c4510b_proc_info: + .long 0x36365000 + .long 0xfffff000 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c4510b_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c4510b_proc_info, . - __s3c4510b_proc_info + + .type __s3c4530_proc_info, #object +__s3c4530_proc_info: + .long 0x4c000000 + .long 0xfff000e0 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c4530_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c4530_proc_info, . - __s3c4530_proc_info + + .type __s3c3410_proc_info, #object +__s3c3410_proc_info: + .long 0x34100000 + .long 0xffff0000 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c3410_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c3410_proc_info, . - __s3c3410_proc_info + + .type __s3c44b0x_proc_info, #object +__s3c44b0x_proc_info: + .long 0x44b00000 + .long 0xffff0000 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c44b0x_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index e4a2569c636c..e7bfff298e46 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -33,7 +33,7 @@ # endif #endif -#if defined(CONFIG_CPU_ARM720T) +#if defined(CONFIG_CPU_ARM720T) || defined(CONFIG_CPU_ARM7TDMI) # ifdef _CACHE # define MULTI_CACHE 1 # else diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index 1bde92cdaebd..3e8c057e66b5 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -33,6 +33,14 @@ # define CPU_NAME cpu_arm6 # endif # endif +# ifdef CONFIG_CPU_ARM7TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm7tdmi +# endif +# endif # ifdef CONFIG_CPU_ARM710 # ifdef CPU_NAME # undef MULTI_CPU -- cgit v1.2.3-70-g09d2 From b731c3118d87f26c8bf3f358ffbbc24450af50a6 Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Tue, 26 Sep 2006 17:37:50 +0900 Subject: [ARM] nommu: add ARM740T core support This patch adds ARM740T core support which has a MPU and 4KB or 8KB cache. Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/Makefile | 1 + arch/arm/mm/Kconfig | 19 ++++- arch/arm/mm/Makefile | 1 + arch/arm/mm/proc-arm740.S | 174 +++++++++++++++++++++++++++++++++++++++++++ include/asm-arm/cacheflush.h | 3 +- include/asm-arm/proc-fns.h | 8 ++ 6 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mm/proc-arm740.S (limited to 'arch/arm/mm') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 282333fe0a74..8ec4b46d2cbb 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -57,6 +57,7 @@ tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi +tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 9f860aa9c908..87f9fece9606 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -75,6 +75,21 @@ config CPU_ARM720T Say Y if you want support for the ARM720T processor. Otherwise, say N. +# ARM740T +config CPU_ARM740T + bool "Support ARM740T processor" if ARCH_INTEGRATOR + select CPU_32v4T + select CPU_ABRT_LV4T + select CPU_CACHE_V3 # although the core is v4t + select CPU_CP15_MPU + help + A 32-bit RISC processor with 8KB cache or 4KB variants, + write buffer and MPU(Protection Unit) built around + an ARM7TDMI core. + + Say Y if you want support for the ARM740T processor. + Otherwise, say N. + # ARM920T config CPU_ARM920T bool "Support ARM920T processor" @@ -436,7 +451,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 default y help Say Y if you want to include kernel support for running user space @@ -473,7 +488,7 @@ config CPU_DCACHE_DISABLE config CPU_DCACHE_WRITETHROUGH bool "Force write through D-cache" - depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE + depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE default y if CPU_ARM925T help Say Y here to use the data cache in writethrough mode. Unless you diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 908f6d437174..d10db822d3b8 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o +obj-$(CONFIG_CPU_ARM740T) += proc-arm740.o obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S new file mode 100644 index 000000000000..40713818a87b --- /dev/null +++ b/arch/arm/mm/proc-arm740.S @@ -0,0 +1,174 @@ +/* + * linux/arch/arm/mm/arm740.S: utility functions for ARM740 + * + * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + + .text +/* + * cpu_arm740_proc_init() + * cpu_arm740_do_idle() + * cpu_arm740_dcache_clean_area() + * cpu_arm740_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm740_proc_init) +ENTRY(cpu_arm740_do_idle) +ENTRY(cpu_arm740_dcache_clean_area) +ENTRY(cpu_arm740_switch_mm) + mov pc, lr + +/* + * cpu_arm740_proc_fin() + */ +ENTRY(cpu_arm740_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x3f000000 @ bank/f/lock/s + bic r0, r0, #0x0000000c @ w-buffer/cache + mcr p15, 0, r0, c1, c0, 0 @ disable caches + mcr p15, 0, r0, c7, c0, 0 @ invalidate cache + ldmfd sp!, {pc} + +/* + * cpu_arm740_reset(loc) + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm740_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c0, 0 @ invalidate cache + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x0000000c @ ............wc.. + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + + __INIT + + .type __arm740_setup, #function +__arm740_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate caches + + mcr p15, 0, r0, c6, c3 @ disable area 3~7 + mcr p15, 0, r0, c6, c4 + mcr p15, 0, r0, c6, c5 + mcr p15, 0, r0, c6, c6 + mcr p15, 0, r0, c6, c7 + + mov r0, #0x0000003F @ base = 0, size = 4GB + mcr p15, 0, r0, c6, c0 @ set area 0, default + + ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c1 @ set area 1, RAM + + ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH + + mov r0, #0x06 + mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #0x00 @ disable whole write buffer +#else + mov r0, #0x02 @ Region 1 write bufferred +#endif + mcr p15, 0, r0, c3, c0 + + mov r0, #0x10000 + sub r0, r0, #1 @ r0 = 0xffff + mcr p15, 0, r0, c5, c0 @ all read/write access + + mrc p15, 0, r0, c1, c0 @ get control register + bic r0, r0, #0x3F000000 @ set to standard caching mode + @ need some benchmark + orr r0, r0, #0x0000000d @ MPU/Cache/WB + + mov pc, lr + + .size __arm740_setup, . - __arm740_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm740_processor_functions, #object +ENTRY(arm740_processor_functions) + .word v4t_late_abort + .word cpu_arm740_proc_init + .word cpu_arm740_proc_fin + .word cpu_arm740_reset + .word cpu_arm740_do_idle + .word cpu_arm740_dcache_clean_area + .word cpu_arm740_switch_mm + .word 0 @ cpu_*_set_pte + .size arm740_processor_functions, . - arm740_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm740_name, #object +cpu_arm740_name: + .ascii "ARM740T" + .size cpu_arm740_name, . - cpu_arm740_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + .type __arm740_proc_info,#object +__arm740_proc_info: + .long 0x41807400 + .long 0xfffffff0 + .long 0 + b __arm740_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_arm740_name + .long arm740_processor_functions + .long 0 + .long 0 + .long v3_cache_fns @ cache model + .size __arm740_proc_info, . - __arm740_proc_info + + diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index e7bfff298e46..24924e64f883 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -25,7 +25,8 @@ #undef _CACHE #undef MULTI_CACHE -#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) +#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) || \ + defined(CONFIG_CPU_ARM740T) # ifdef _CACHE # define MULTI_CACHE 1 # else diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index 3e8c057e66b5..17dfc0de9658 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -57,6 +57,14 @@ # define CPU_NAME cpu_arm720 # endif # endif +# ifdef CONFIG_CPU_ARM740T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm740 +# endif +# endif # ifdef CONFIG_CPU_ARM920T # ifdef CPU_NAME # undef MULTI_CPU -- cgit v1.2.3-70-g09d2 From 43f5f0146ef5c3a3421ea53a0708fd37edcb8905 Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Tue, 26 Sep 2006 17:38:05 +0900 Subject: [ARM] nommu: add ARM9TDMI core support This patch adds ARM9TDMI core support which has no cache and no CP15 register(no memory control unit). Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/Makefile | 1 + arch/arm/mm/Kconfig | 13 +++++ arch/arm/mm/Makefile | 1 + arch/arm/mm/proc-arm9tdmi.S | 134 +++++++++++++++++++++++++++++++++++++++++++ include/asm-arm/cacheflush.h | 3 +- include/asm-arm/proc-fns.h | 8 +++ 6 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mm/proc-arm9tdmi.S (limited to 'arch/arm/mm') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 8ec4b46d2cbb..a29e64175f8f 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -58,6 +58,7 @@ tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi +tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 87f9fece9606..ed9d32c2469e 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -90,6 +90,19 @@ config CPU_ARM740T Say Y if you want support for the ARM740T processor. Otherwise, say N. +# ARM9TDMI +config CPU_ARM9TDMI + bool "Support ARM9TDMI processor" + select CPU_32v4T + select CPU_ABRT_EV4T + select CPU_CACHE_V4 + help + A 32-bit RISC microprocessor based on the ARM9 processor core + which has no memory control unit and cache. + + Say Y if you want support for the ARM9TDMI processor. + Otherwise, say N. + # ARM920T config CPU_ARM920T bool "Support ARM920T processor" diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index d10db822d3b8..053957eebe24 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o obj-$(CONFIG_CPU_ARM740T) += proc-arm740.o +obj-$(CONFIG_CPU_ARM9TDMI) += proc-arm9tdmi.o obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S new file mode 100644 index 000000000000..95c90f13caa8 --- /dev/null +++ b/arch/arm/mm/proc-arm9tdmi.S @@ -0,0 +1,134 @@ +/* + * linux/arch/arm/mm/proc-arm9tdmi.S: utility functions for ARM9TDMI + * + * Copyright (C) 2003-2006 Hyok S. Choi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + + .text +/* + * cpu_arm9tdmi_proc_init() + * cpu_arm9tdmi_do_idle() + * cpu_arm9tdmi_dcache_clean_area() + * cpu_arm9tdmi_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm9tdmi_proc_init) +ENTRY(cpu_arm9tdmi_do_idle) +ENTRY(cpu_arm9tdmi_dcache_clean_area) +ENTRY(cpu_arm9tdmi_switch_mm) + mov pc, lr + +/* + * cpu_arm9tdmi_proc_fin() + */ +ENTRY(cpu_arm9tdmi_proc_fin) + mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, r0 + mov pc, lr + +/* + * Function: cpu_arm9tdmi_reset(loc) + * Params : loc(r0) address to jump to + * Purpose : Sets up everything for a reset and jump to the location for soft reset. + */ +ENTRY(cpu_arm9tdmi_reset) + mov pc, r0 + + __INIT + + .type __arm9tdmi_setup, #function +__arm9tdmi_setup: + mov pc, lr + .size __arm9tdmi_setup, . - __arm9tdmi_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm9tdmi_processor_functions, #object +ENTRY(arm9tdmi_processor_functions) + .word v4t_early_abort + .word cpu_arm9tdmi_proc_init + .word cpu_arm9tdmi_proc_fin + .word cpu_arm9tdmi_reset + .word cpu_arm9tdmi_do_idle + .word cpu_arm9tdmi_dcache_clean_area + .word cpu_arm9tdmi_switch_mm + .word 0 @ cpu_*_set_pte + .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm9tdmi_name, #object +cpu_arm9tdmi_name: + .asciz "ARM9TDMI" + .size cpu_arm9tdmi_name, . - cpu_arm9tdmi_name + + .type cpu_p2001_name, #object +cpu_p2001_name: + .asciz "P2001" + .size cpu_p2001_name, . - cpu_p2001_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + + .type __arm9tdmi_proc_info, #object +__arm9tdmi_proc_info: + .long 0x41009900 + .long 0xfff8ff00 + .long 0 + .long 0 + b __arm9tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_arm9tdmi_name + .long arm9tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __arm9tdmi_proc_info, . - __arm9dmi_proc_info + + .type __p2001_proc_info, #object +__p2001_proc_info: + .long 0x41029000 + .long 0xffffffff + .long 0 + .long 0 + b __arm9tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_p2001_name + .long arm9tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __p2001_proc_info, . - __p2001_proc_info diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 24924e64f883..77ff6fe86dbd 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -34,7 +34,8 @@ # endif #endif -#if defined(CONFIG_CPU_ARM720T) || defined(CONFIG_CPU_ARM7TDMI) +#if defined(CONFIG_CPU_ARM720T) || defined(CONFIG_CPU_ARM7TDMI) || \ + defined(CONFIG_CPU_ARM9TDMI) # ifdef _CACHE # define MULTI_CACHE 1 # else diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index 17dfc0de9658..7bb9dab310f5 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -65,6 +65,14 @@ # define CPU_NAME cpu_arm740 # endif # endif +# ifdef CONFIG_CPU_ARM9TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm9tdmi +# endif +# endif # ifdef CONFIG_CPU_ARM920T # ifdef CPU_NAME # undef MULTI_CPU -- cgit v1.2.3-70-g09d2 From d60674eb5d961b2421db16cc373dc163f38cc105 Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Tue, 26 Sep 2006 17:38:18 +0900 Subject: [ARM] nommu: add ARM940T core support This patch adds ARM940T core support which has 4KB D-cache, 4KB I-cache and a MPU. Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/Makefile | 1 + arch/arm/mm/Kconfig | 20 ++- arch/arm/mm/Makefile | 1 + arch/arm/mm/proc-arm940.S | 369 +++++++++++++++++++++++++++++++++++++++++++ include/asm-arm/cacheflush.h | 8 + include/asm-arm/proc-fns.h | 8 + 6 files changed, 405 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mm/proc-arm940.S (limited to 'arch/arm/mm') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index a29e64175f8f..4c424c95dd3a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -59,6 +59,7 @@ tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index ed9d32c2469e..34d00738293f 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -184,6 +184,22 @@ config CPU_ARM926T Say Y if you want support for the ARM926T processor. Otherwise, say N. +# ARM940T +config CPU_ARM940T + bool "Support ARM940T processor" if ARCH_INTEGRATOR + select CPU_32v4T + select CPU_ABRT_EV4T + select CPU_CACHE_VIVT + select CPU_CP15_MPU + help + ARM940T is a member of the ARM9TDMI family of general- + purpose microprocessors with MPU and seperate 4KB + instruction and 4KB data cases, each with a 4-word line + length. + + Say Y if you want support for the ARM940T processor. + Otherwise, say N. + # ARM1020 - needs validating config CPU_ARM1020 bool "Support ARM1020T (rev 0) processor" @@ -464,7 +480,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 default y help Say Y if you want to include kernel support for running user space @@ -501,7 +517,7 @@ config CPU_DCACHE_DISABLE config CPU_DCACHE_WRITETHROUGH bool "Force write through D-cache" - depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE + depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE default y if CPU_ARM925T help Say Y here to use the data cache in writethrough mode. Unless you diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 053957eebe24..f89fe1b2a4ad 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o +obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S new file mode 100644 index 000000000000..14846ac2d0e6 --- /dev/null +++ b/arch/arm/mm/proc-arm940.S @@ -0,0 +1,369 @@ +/* + * linux/arch/arm/mm/arm940.S: utility functions for ARM940T + * + * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +/* ARM940T has a 4KB DCache comprising 256 lines of 4 words */ +#define CACHE_DLINESIZE 16 +#define CACHE_DSEGMENTS 4 +#define CACHE_DENTRIES 64 + + .text +/* + * cpu_arm940_proc_init() + * cpu_arm940_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm940_proc_init) +ENTRY(cpu_arm940_switch_mm) + mov pc, lr + +/* + * cpu_arm940_proc_fin() + */ +ENTRY(cpu_arm940_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm940_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x00001000 @ i-cache + bic r0, r0, #0x00000004 @ d-cache + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm940_reset(loc) + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm940_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ flush I cache + mcr p15, 0, ip, c7, c6, 0 @ flush D cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x00000005 @ .............c.p + bic ip, ip, #0x00001000 @ i-cache + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm940_do_idle() + */ + .align 5 +ENTRY(cpu_arm940_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* + * flush_user_cache_all() + */ +ENTRY(arm940_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm940_flush_kern_cache_all) + mov r2, #VM_EXEC + /* FALLTHROUGH */ + +/* + * flush_user_cache_range(start, end, flags) + * + * There is no efficient way to flush a range of cache entries + * in the specified address range. Thus, flushes all. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + */ +ENTRY(arm940_flush_user_cache_range) + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ flush D cache +#else + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 3 to 0 +#endif + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_coherent_user_range) + /* FALLTHROUGH */ + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(arm940_flush_kern_dcache_page) + mov ip, #0 + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * There is no efficient way to invalidate a specifid virtual + * address range. Thus, invalidates all. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_dma_inv_range) + mov ip, #0 + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c6, 2 @ flush D entry + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * There is no efficient way to clean a specifid virtual + * address range. Thus, cleans all. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_dma_clean_range) +ENTRY(cpu_arm940_dcache_clean_area) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c10, 2 @ clean D entry + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * There is no efficient way to clean and invalidate a specifid + * virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_dma_flush_range) + mov ip, #0 + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r3, c7, c14, 2 @ clean/flush D entry +#else + mcr p15, 0, r3, c7, c10, 2 @ clean D entry +#endif + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm940_cache_fns) + .long arm940_flush_kern_cache_all + .long arm940_flush_user_cache_all + .long arm940_flush_user_cache_range + .long arm940_coherent_kern_range + .long arm940_coherent_user_range + .long arm940_flush_kern_dcache_page + .long arm940_dma_inv_range + .long arm940_dma_clean_range + .long arm940_dma_flush_range + + __INIT + + .type __arm940_setup, #function +__arm940_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + + mcr p15, 0, r0, c6, c3, 0 @ disable data area 3~7 + mcr p15, 0, r0, c6, c4, 0 + mcr p15, 0, r0, c6, c5, 0 + mcr p15, 0, r0, c6, c6, 0 + mcr p15, 0, r0, c6, c7, 0 + + mcr p15, 0, r0, c6, c3, 1 @ disable instruction area 3~7 + mcr p15, 0, r0, c6, c4, 1 + mcr p15, 0, r0, c6, c5, 1 + mcr p15, 0, r0, c6, c6, 1 + mcr p15, 0, r0, c6, c7, 1 + + mov r0, #0x0000003F @ base = 0, size = 4GB + mcr p15, 0, r0, c6, c0, 0 @ set area 0, default + mcr p15, 0, r0, c6, c0, 1 + + ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c1, 0 @ set area 1, RAM + mcr p15, 0, r0, c6, c1, 1 + + ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c2, 0 @ set area 2, ROM/FLASH + mcr p15, 0, r0, c6, c2, 1 + + mov r0, #0x06 + mcr p15, 0, r0, c2, c0, 0 @ Region 1&2 cacheable + mcr p15, 0, r0, c2, c0, 1 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #0x00 @ disable whole write buffer +#else + mov r0, #0x02 @ Region 1 write bufferred +#endif + mcr p15, 0, r0, c3, c0, 0 + + mov r0, #0x10000 + sub r0, r0, #1 @ r0 = 0xffff + mcr p15, 0, r0, c5, c0, 0 @ all read/write access + mcr p15, 0, r0, c5, c0, 1 + + mrc p15, 0, r0, c1, c0 @ get control register + orr r0, r0, #0x00001000 @ I-cache + orr r0, r0, #0x00000005 @ MPU/D-cache + + mov pc, lr + + .size __arm940_setup, . - __arm940_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm940_processor_functions, #object +ENTRY(arm940_processor_functions) + .word v4t_early_abort + .word cpu_arm940_proc_init + .word cpu_arm940_proc_fin + .word cpu_arm940_reset + .word cpu_arm940_do_idle + .word cpu_arm940_dcache_clean_area + .word cpu_arm940_switch_mm + .word 0 @ cpu_*_set_pte + .size arm940_processor_functions, . - arm940_processor_functions + + .section ".rodata" + +.type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm940_name, #object +cpu_arm940_name: + .ascii "ARM940T" + .size cpu_arm940_name, . - cpu_arm940_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + + .type __arm940_proc_info,#object +__arm940_proc_info: + .long 0x41009400 + .long 0xff00fff0 + .long 0 + b __arm940_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm940_name + .long arm940_processor_functions + .long 0 + .long 0 + .long arm940_cache_fns + .size __arm940_proc_info, . - __arm940_proc_info + diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 77ff6fe86dbd..b0a8603400be 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -56,6 +56,14 @@ # endif #endif +#if defined(CONFIG_CPU_ARM940T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm940 +# endif +#endif + #if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) # ifdef _CACHE # define MULTI_CACHE 1 diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index 7bb9dab310f5..87f3ea97f48c 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -105,6 +105,14 @@ # define CPU_NAME cpu_arm926 # endif # endif +# ifdef CONFIG_CPU_ARM940T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm940 +# endif +# endif # ifdef CONFIG_CPU_SA110 # ifdef CPU_NAME # undef MULTI_CPU -- cgit v1.2.3-70-g09d2 From f37f46eb1c0bd0b11c34ef06c7365658be989d80 Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Tue, 26 Sep 2006 17:38:32 +0900 Subject: [ARM] nommu: add ARM946E-S core support This patch adds ARM946E-S core support which has typically 8KB I&D cache. It has a MPU and supports ARMv5TE instruction set. Because the ARM946E-S core can be synthesizable with various cache size, CONFIG_CPU_DCACHE_SIZE is defined for vendor specific configurations. Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/Makefile | 1 + arch/arm/mm/Kconfig | 34 +++- arch/arm/mm/Makefile | 1 + arch/arm/mm/proc-arm946.S | 424 +++++++++++++++++++++++++++++++++++++++++++ include/asm-arm/cacheflush.h | 8 + include/asm-arm/proc-fns.h | 8 + 6 files changed, 473 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mm/proc-arm946.S (limited to 'arch/arm/mm') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4c424c95dd3a..2a0b2c8a1fe0 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -60,6 +60,7 @@ tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_ARM946T) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 34d00738293f..893d3fc8078f 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -200,6 +200,21 @@ config CPU_ARM940T Say Y if you want support for the ARM940T processor. Otherwise, say N. +# ARM946E-S +config CPU_ARM946E + bool "Support ARM946E-S processor" if ARCH_INTEGRATOR + select CPU_32v5 + select CPU_ABRT_EV5T + select CPU_CACHE_VIVT + select CPU_CP15_MPU + help + ARM946E-S is a member of the ARM9E-S family of high- + performance, 32-bit system-on-chip processor solutions. + The TCM and ARMv5TE 32-bit instruction set is supported. + + Say Y if you want support for the ARM946E-S processor. + Otherwise, say N. + # ARM1020 - needs validating config CPU_ARM1020 bool "Support ARM1020T (rev 0) processor" @@ -480,7 +495,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 default y help Say Y if you want to include kernel support for running user space @@ -515,9 +530,22 @@ config CPU_DCACHE_DISABLE Say Y here to disable the processor data cache. Unless you have a reason not to or are unsure, say N. +config CPU_DCACHE_SIZE + hex + depends on CPU_ARM740T || CPU_ARM946E + default 0x00001000 if CPU_ARM740T + default 0x00002000 # default size for ARM946E-S + help + Some cores are synthesizable to have various sized cache. For + ARM946E-S case, it can vary from 0KB to 1MB. + To support such cache operations, it is efficient to know the size + before compile time. + If your SoC is configured to have a different size, define the value + here with proper conditions. + config CPU_DCACHE_WRITETHROUGH bool "Force write through D-cache" - depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE + depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE default y if CPU_ARM925T help Say Y here to use the data cache in writethrough mode. Unless you @@ -525,7 +553,7 @@ config CPU_DCACHE_WRITETHROUGH config CPU_CACHE_ROUND_ROBIN bool "Round robin I and D cache replacement algorithm" - depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) + depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) help Say Y here to use the predictable round-robin cache replacement policy. Unless you specifically require this or are unsure, say N. diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index f89fe1b2a4ad..ed81b9ef10cb 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o +obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S new file mode 100644 index 000000000000..6dc7942c4cfe --- /dev/null +++ b/arch/arm/mm/proc-arm946.S @@ -0,0 +1,424 @@ +/* + * linux/arch/arm/mm/arm946.S: utility functions for ARM946E-S + * + * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com) + * + * (Many of cache codes are from proc-arm926.S) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +/* + * ARM946E-S is synthesizable to have 0KB to 1MB sized D-Cache, + * comprising 256 lines of 32 bytes (8 words). + */ +#define CACHE_DSIZE (CONFIG_CPU_DCACHE_SIZE) /* typically 8KB. */ +#define CACHE_DLINESIZE 32 /* fixed */ +#define CACHE_DSEGMENTS 4 /* fixed */ +#define CACHE_DENTRIES (CACHE_DSIZE / CACHE_DSEGMENTS / CACHE_DLINESIZE) +#define CACHE_DLIMIT (CACHE_DSIZE * 4) /* benchmark needed */ + + .text +/* + * cpu_arm946_proc_init() + * cpu_arm946_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm946_proc_init) +ENTRY(cpu_arm946_switch_mm) + mov pc, lr + +/* + * cpu_arm946_proc_fin() + */ +ENTRY(cpu_arm946_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm946_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x00001000 @ i-cache + bic r0, r0, #0x00000004 @ d-cache + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm946_reset(loc) + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm946_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ flush I cache + mcr p15, 0, ip, c7, c6, 0 @ flush D cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x00000005 @ .............c.p + bic ip, ip, #0x00001000 @ i-cache + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm946_do_idle() + */ + .align 5 +ENTRY(cpu_arm946_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* + * flush_user_cache_all() + */ +ENTRY(arm946_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm946_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ flush D cache +#else + mov r1, #(CACHE_DSEGMENTS - 1) << 29 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 4 @ n entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index + subs r3, r3, #1 << 4 + bcs 2b @ entries n to 0 + subs r1, r1, #1 << 29 + bcs 1b @ segments 3 to 0 +#endif + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ flush I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address range. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + * (same as arm926) + */ +ENTRY(arm946_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +1: tst r2, #VM_EXEC +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#else + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#endif + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm946_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + * (same as arm926) + */ +ENTRY(arm946_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + * (same as arm926) + */ +ENTRY(arm946_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * (same as arm926) + */ +ENTRY(arm946_dma_inv_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + tst r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +#endif + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as arm926) + */ +ENTRY(arm946_dma_clean_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as arm926) + */ +ENTRY(arm946_dma_flush_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry +#else + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm946_cache_fns) + .long arm946_flush_kern_cache_all + .long arm946_flush_user_cache_all + .long arm946_flush_user_cache_range + .long arm946_coherent_kern_range + .long arm946_coherent_user_range + .long arm946_flush_kern_dcache_page + .long arm946_dma_inv_range + .long arm946_dma_clean_range + .long arm946_dma_flush_range + + +ENTRY(cpu_arm946_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __arm946_setup, #function +__arm946_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + + mcr p15, 0, r0, c6, c3, 0 @ disable memory region 3~7 + mcr p15, 0, r0, c6, c4, 0 + mcr p15, 0, r0, c6, c5, 0 + mcr p15, 0, r0, c6, c6, 0 + mcr p15, 0, r0, c6, c7, 0 + + mov r0, #0x0000003F @ base = 0, size = 4GB + mcr p15, 0, r0, c6, c0, 0 @ set region 0, default + + ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the region register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c1, 0 @ set region 1, RAM + + ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the region register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c2, 0 @ set region 2, ROM/FLASH + + mov r0, #0x06 + mcr p15, 0, r0, c2, c0, 0 @ region 1,2 d-cacheable + mcr p15, 0, r0, c2, c0, 1 @ region 1,2 i-cacheable +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #0x00 @ disable whole write buffer +#else + mov r0, #0x02 @ region 1 write bufferred +#endif + mcr p15, 0, r0, c3, c0, 0 + +/* + * Access Permission Settings for future permission control by PU. + * + * priv. user + * region 0 (whole) rw -- : b0001 + * region 1 (RAM) rw rw : b0011 + * region 2 (FLASH) rw r- : b0010 + * region 3~7 (none) -- -- : b0000 + */ + mov r0, #0x00000031 + orr r0, r0, #0x00000200 + mcr p15, 0, r0, c5, c0, 2 @ set data access permission + mcr p15, 0, r0, c5, c0, 3 @ set inst. access permission + + mrc p15, 0, r0, c1, c0 @ get control register + orr r0, r0, #0x00001000 @ I-cache + orr r0, r0, #0x00000005 @ MPU/D-cache +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x00004000 @ .1.. .... .... .... +#endif + mov pc, lr + + .size __arm946_setup, . - __arm946_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm946_processor_functions, #object +ENTRY(arm946_processor_functions) + .word v5t_early_abort + .word cpu_arm946_proc_init + .word cpu_arm946_proc_fin + .word cpu_arm946_reset + .word cpu_arm946_do_idle + + .word cpu_arm946_dcache_clean_area + .word cpu_arm946_switch_mm + .word 0 @ cpu_*_set_pte + .size arm946_processor_functions, . - arm946_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5te" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5t" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm946_name, #object +cpu_arm946_name: + .ascii "ARM946E-S" + .size cpu_arm946_name, . - cpu_arm946_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + .type __arm946_proc_info,#object +__arm946_proc_info: + .long 0x41009460 + .long 0xff00fff0 + .long 0 + b __arm946_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm946_name + .long arm946_processor_functions + .long 0 + .long 0 + .long arm940_cache_fns + .size __arm946_proc_info, . - __arm946_proc_info + diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index b0a8603400be..b611a8ea0bb2 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -64,6 +64,14 @@ # endif #endif +#if defined(CONFIG_CPU_ARM946E) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm946 +# endif +#endif + #if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) # ifdef _CACHE # define MULTI_CACHE 1 diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index 87f3ea97f48c..ea7e54c319be 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -113,6 +113,14 @@ # define CPU_NAME cpu_arm940 # endif # endif +# ifdef CONFIG_CPU_ARM946E +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm946 +# endif +# endif # ifdef CONFIG_CPU_SA110 # ifdef CPU_NAME # undef MULTI_CPU -- cgit v1.2.3-70-g09d2 From 6b237a355afd342509f1471e0c338637bcd958bc Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Sep 2006 17:44:39 +0100 Subject: [ARM] Make !MMU CPUs depend on !MMU Don't offer non-MMU based CPUs for selection when CONFIG_MMU is set. Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 893d3fc8078f..ae427de27ce0 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -28,6 +28,7 @@ config CPU_ARM610 # ARM7TDMI config CPU_ARM7TDMI bool "Support ARM7TDMI processor" + depends on !MMU select CPU_32v4T select CPU_ABRT_LV4T select CPU_CACHE_V4 @@ -78,6 +79,7 @@ config CPU_ARM720T # ARM740T config CPU_ARM740T bool "Support ARM740T processor" if ARCH_INTEGRATOR + depends on !MMU select CPU_32v4T select CPU_ABRT_LV4T select CPU_CACHE_V3 # although the core is v4t @@ -93,6 +95,7 @@ config CPU_ARM740T # ARM9TDMI config CPU_ARM9TDMI bool "Support ARM9TDMI processor" + depends on !MMU select CPU_32v4T select CPU_ABRT_EV4T select CPU_CACHE_V4 @@ -187,6 +190,7 @@ config CPU_ARM926T # ARM940T config CPU_ARM940T bool "Support ARM940T processor" if ARCH_INTEGRATOR + depends on !MMU select CPU_32v4T select CPU_ABRT_EV4T select CPU_CACHE_VIVT @@ -203,6 +207,7 @@ config CPU_ARM940T # ARM946E-S config CPU_ARM946E bool "Support ARM946E-S processor" if ARCH_INTEGRATOR + depends on !MMU select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT -- cgit v1.2.3-70-g09d2 From 0f45d7f36b766cb668cebfb5d4d2f67b4a8676ba Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Thu, 28 Sep 2006 21:46:16 +0900 Subject: [ARM] nommu: abort handler fixup for !CPU_CP15_MMU cores. There is no FSR/FAR register on no-CP15 or MPU cores. This patch adds a dummy abort handler which returns zero for the base restored Data Abort model !CPU_CP15_MMU cores. The abort-lv4t.S is still used with the fix-up for the base updated Data Abort model cores. Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 9 ++++++--- arch/arm/mm/Makefile | 1 + arch/arm/mm/abort-lv4t.S | 7 ++++++- arch/arm/mm/abort-nommu.S | 19 +++++++++++++++++++ arch/arm/mm/proc-arm940.S | 2 +- arch/arm/mm/proc-arm946.S | 2 +- arch/arm/mm/proc-arm9tdmi.S | 2 +- 7 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 arch/arm/mm/abort-nommu.S (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index ae427de27ce0..6c1bd424ea61 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -97,7 +97,7 @@ config CPU_ARM9TDMI bool "Support ARM9TDMI processor" depends on !MMU select CPU_32v4T - select CPU_ABRT_EV4T + select CPU_ABRT_NOMMU select CPU_CACHE_V4 help A 32-bit RISC microprocessor based on the ARM9 processor core @@ -192,7 +192,7 @@ config CPU_ARM940T bool "Support ARM940T processor" if ARCH_INTEGRATOR depends on !MMU select CPU_32v4T - select CPU_ABRT_EV4T + select CPU_ABRT_NOMMU select CPU_CACHE_VIVT select CPU_CP15_MPU help @@ -209,7 +209,7 @@ config CPU_ARM946E bool "Support ARM946E-S processor" if ARCH_INTEGRATOR depends on !MMU select CPU_32v5 - select CPU_ABRT_EV5T + select CPU_ABRT_NOMMU select CPU_CACHE_VIVT select CPU_CP15_MPU help @@ -392,6 +392,9 @@ config CPU_32v6 bool # The abort model +config CPU_ABRT_NOMMU + bool + config CPU_ABRT_EV4 bool diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index ed81b9ef10cb..d2f5672ecf62 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o +obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o obj-$(CONFIG_CPU_ABRT_EV4T) += abort-ev4t.o obj-$(CONFIG_CPU_ABRT_LV4T) += abort-lv4t.o diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index db743e510214..9fb7b0e25ea1 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S @@ -19,11 +19,16 @@ */ ENTRY(v4t_late_abort) tst r3, #PSR_T_BIT @ check for thumb mode +#ifdef CONFIG_CPU_CP15_MMU mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR +#else + mov r0, #0 @ clear r0, r1 (no FSR/FAR) + mov r1, #0 +#endif bne .data_thumb_abort ldr r8, [r2] @ read arm instruction - bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR tst r8, #1 << 20 @ L = 1 -> write? orreq r1, r1, #1 << 11 @ yes. and r7, r8, #15 << 24 diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S new file mode 100644 index 000000000000..a7cc7f9ee45d --- /dev/null +++ b/arch/arm/mm/abort-nommu.S @@ -0,0 +1,19 @@ +#include +#include +/* + * Function: nommu_early_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = 0 (abort address) + * : r1 = 0 (FSR) + * + * Note: There is no FSR/FAR on !CPU_CP15_MMU cores. + * Just fill zero into the registers. + */ + .align 5 +ENTRY(nommu_early_abort) + mov r0, #0 @ clear r0, r1 (no FSR/FAR) + mov r1, #0 + mov pc, lr diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S index 14846ac2d0e6..2397f4b6e151 100644 --- a/arch/arm/mm/proc-arm940.S +++ b/arch/arm/mm/proc-arm940.S @@ -320,7 +320,7 @@ __arm940_setup: */ .type arm940_processor_functions, #object ENTRY(arm940_processor_functions) - .word v4t_early_abort + .word nommu_early_abort .word cpu_arm940_proc_init .word cpu_arm940_proc_fin .word cpu_arm940_reset diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S index 6dc7942c4cfe..e18617564421 100644 --- a/arch/arm/mm/proc-arm946.S +++ b/arch/arm/mm/proc-arm946.S @@ -375,7 +375,7 @@ __arm946_setup: */ .type arm946_processor_functions, #object ENTRY(arm946_processor_functions) - .word v5t_early_abort + .word nommu_early_abort .word cpu_arm946_proc_init .word cpu_arm946_proc_fin .word cpu_arm946_reset diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S index 95c90f13caa8..918ebf65d4f6 100644 --- a/arch/arm/mm/proc-arm9tdmi.S +++ b/arch/arm/mm/proc-arm9tdmi.S @@ -63,7 +63,7 @@ __arm9tdmi_setup: */ .type arm9tdmi_processor_functions, #object ENTRY(arm9tdmi_processor_functions) - .word v4t_early_abort + .word nommu_early_abort .word cpu_arm9tdmi_proc_init .word cpu_arm9tdmi_proc_fin .word cpu_arm9tdmi_reset -- cgit v1.2.3-70-g09d2 From 6afd6fae1d5f7e7129a10c4f3e32018966eeac1c Mon Sep 17 00:00:00 2001 From: "Hyok S. Choi" Date: Thu, 28 Sep 2006 21:46:34 +0900 Subject: [ARM] nommu: confirms the CR_V bit in nommu mode In nommu mode, the exception vector location depends on the platforms. Some of the implementations may have some special exception control forwarding method in their ROM/flash and for some of them has its own re-mapping mechanism by the h/w. This patch introduces a special configuration CONFIG_CPU_HIGH_VECTOR which turns on the CR_V bit in nommu mode. The CR_V bit is turned off by default. This feature depends on CP15 and does not supported by ARM740. Signed-off-by: Hyok S. Choi Signed-off-by: Russell King --- arch/arm/Kconfig | 2 +- arch/arm/kernel/head-nommu.S | 5 +++++ arch/arm/mm/Kconfig | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2673fee3281c..ea7640af0f1e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -95,7 +95,7 @@ config ARCH_MTD_XIP config VECTORS_BASE hex - default 0xffff0000 if MMU + default 0xffff0000 if MMU || CPU_HIGH_VECTOR default DRAM_BASE if REMAP_VECTORS_TO_RAM default 0x00000000 help diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 698a537915dd..f359a189dcf2 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -76,6 +76,11 @@ __after_proc_init: #endif #ifdef CONFIG_CPU_ICACHE_DISABLE bic r0, r0, #CR_I +#endif +#ifdef CONFIG_CPU_HIGH_VECTOR + orr r0, r0, #CR_V +#else + bic r0, r0, #CR_V #endif mcr p15, 0, r0, c1, c0, 0 @ write control reg #endif /* CONFIG_CPU_CP15 */ diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 6c1bd424ea61..c0bfb8212b77 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -524,6 +524,18 @@ config CPU_BIG_ENDIAN port must properly enable any big-endian related features of your chipset/board/processor. +config CPU_HIGH_VECTOR + depends !MMU && CPU_CP15 && !CPU_ARM740T + bool "Select the High exception vector" + default n + help + Say Y here to select high exception vector(0xFFFF0000~). + The exception vector can be vary depending on the platform + design in nommu mode. If your platform needs to select + high exception vector, say Y. + Otherwise or if you are unsure, say N, and the low exception + vector (0x00000000~) will be used. + config CPU_ICACHE_DISABLE bool "Disable I-Cache (I-bit)" depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) -- cgit v1.2.3-70-g09d2