aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/arm/Kconfig25
-rw-r--r--arch/arm/Kconfig.debug14
-rw-r--r--arch/arm/Makefile9
-rw-r--r--arch/arm/include/asm/elf.h4
-rw-r--r--arch/arm/include/asm/io.h1
-rw-r--r--arch/arm/include/asm/mmu_context.h29
-rw-r--r--arch/arm/include/asm/seccomp.h11
-rw-r--r--arch/arm/include/asm/thread_info.h2
-rw-r--r--arch/arm/kernel/entry-common.S15
-rw-r--r--arch/arm/kernel/process.c21
-rw-r--r--arch/arm/mach-aaec2000/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-bcmring/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-clps711x/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-ebsa110/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-footbridge/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-h720x/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-integrator/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-msm/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-mx5/cpu.c19
-rw-r--r--arch/arm/mach-netx/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-omap1/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-omap2/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-pnx4008/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-rpc/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-shark/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-tcc8k/Kconfig11
-rw-r--r--arch/arm/mach-tcc8k/Makefile9
-rw-r--r--arch/arm/mach-tcc8k/Makefile.boot3
-rw-r--r--arch/arm/mach-tcc8k/board-tcc8000-sdk.c64
-rw-r--r--arch/arm/mach-tcc8k/clock.c567
-rw-r--r--arch/arm/mach-tcc8k/common.h15
-rw-r--r--arch/arm/mach-tcc8k/devices.c239
-rw-r--r--arch/arm/mach-tcc8k/io.c62
-rw-r--r--arch/arm/mach-tcc8k/irq.c111
-rw-r--r--arch/arm/mach-tcc8k/time.c149
-rw-r--r--arch/arm/mach-versatile/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mm/mmap.c22
-rw-r--r--arch/arm/plat-tcc/Kconfig20
-rw-r--r--arch/arm/plat-tcc/Makefile3
-rw-r--r--arch/arm/plat-tcc/clock.c179
-rw-r--r--arch/arm/plat-tcc/include/mach/clkdev.h7
-rw-r--r--arch/arm/plat-tcc/include/mach/clock.h48
-rw-r--r--arch/arm/plat-tcc/include/mach/debug-macro.S33
-rw-r--r--arch/arm/plat-tcc/include/mach/entry-macro.S68
-rw-r--r--arch/arm/plat-tcc/include/mach/hardware.h43
-rw-r--r--arch/arm/plat-tcc/include/mach/io.h23
-rw-r--r--arch/arm/plat-tcc/include/mach/irqs.h83
-rw-r--r--arch/arm/plat-tcc/include/mach/memory.h18
-rw-r--r--arch/arm/plat-tcc/include/mach/system.h31
-rw-r--r--arch/arm/plat-tcc/include/mach/tcc8k-regs.h807
-rw-r--r--arch/arm/plat-tcc/include/mach/timex.h5
-rw-r--r--arch/arm/plat-tcc/include/mach/uncompress.h34
-rw-r--r--arch/arm/plat-tcc/include/mach/vmalloc.h10
-rw-r--r--arch/arm/plat-tcc/system.c25
55 files changed, 2855 insertions, 21 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index f46d8e66333f..0c737460f7e9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -980,6 +980,13 @@ S: Supported
980F: arch/arm/mach-shmobile/ 980F: arch/arm/mach-shmobile/
981F: drivers/sh/ 981F: drivers/sh/
982 982
983ARM/TELECHIPS ARM ARCHITECTURE
984M: "Hans J. Koch" <hjk@linutronix.de>
985L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
986S: Maintained
987F: arch/arm/plat-tcc/
988F: arch/arm/mach-tcc8k/
989
983ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT 990ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
984M: Lennert Buytenhek <kernel@wantstofly.org> 991M: Lennert Buytenhek <kernel@wantstofly.org>
985L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 992L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 88c97bc7a6f5..ca5aa5aa39e0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -747,6 +747,15 @@ config ARCH_SHARK
747 Support for the StrongARM based Digital DNARD machine, also known 747 Support for the StrongARM based Digital DNARD machine, also known
748 as "Shark" (<http://www.shark-linux.de/shark.html>). 748 as "Shark" (<http://www.shark-linux.de/shark.html>).
749 749
750config ARCH_TCC_926
751 bool "Telechips TCC ARM926-based systems"
752 select CPU_ARM926T
753 select HAVE_CLK
754 select COMMON_CLKDEV
755 select GENERIC_CLOCKEVENTS
756 help
757 Support for Telechips TCC ARM926-based systems.
758
750config ARCH_LH7A40X 759config ARCH_LH7A40X
751 bool "Sharp LH7A40X" 760 bool "Sharp LH7A40X"
752 select CPU_ARM922T 761 select CPU_ARM922T
@@ -915,6 +924,8 @@ source "arch/arm/plat-s5p/Kconfig"
915 924
916source "arch/arm/plat-spear/Kconfig" 925source "arch/arm/plat-spear/Kconfig"
917 926
927source "arch/arm/plat-tcc/Kconfig"
928
918if ARCH_S3C2410 929if ARCH_S3C2410
919source "arch/arm/mach-s3c2400/Kconfig" 930source "arch/arm/mach-s3c2400/Kconfig"
920source "arch/arm/mach-s3c2410/Kconfig" 931source "arch/arm/mach-s3c2410/Kconfig"
@@ -1463,6 +1474,20 @@ config UACCESS_WITH_MEMCPY
1463 However, if the CPU data cache is using a write-allocate mode, 1474 However, if the CPU data cache is using a write-allocate mode,
1464 this option is unlikely to provide any performance gain. 1475 this option is unlikely to provide any performance gain.
1465 1476
1477config SECCOMP
1478 bool
1479 prompt "Enable seccomp to safely compute untrusted bytecode"
1480 ---help---
1481 This kernel feature is useful for number crunching applications
1482 that may need to compute untrusted bytecode during their
1483 execution. By using pipes or other transports made available to
1484 the process as file descriptors supporting the read/write
1485 syscalls, it's possible to isolate those applications in
1486 their own address space using seccomp. Once seccomp is
1487 enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
1488 and the task is only allowed to execute a few safe syscalls
1489 defined by each seccomp mode.
1490
1466config CC_STACKPROTECTOR 1491config CC_STACKPROTECTOR
1467 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" 1492 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
1468 help 1493 help
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 91344af75f39..c29fb382aeee 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -2,6 +2,20 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config STRICT_DEVMEM
6 bool "Filter access to /dev/mem"
7 depends on MMU
8 ---help---
9 If this option is disabled, you allow userspace (root) access to all
10 of memory, including kernel and userspace memory. Accidental
11 access to this is obviously disastrous, but specific access can
12 be used by people debugging the kernel.
13
14 If this option is switched on, the /dev/mem file only allows
15 userspace access to memory mapped peripherals.
16
17 If in doubt, say Y.
18
5# RMK wants arm kernels compiled with frame pointers or stack unwinding. 19# RMK wants arm kernels compiled with frame pointers or stack unwinding.
6# If you know what you are doing and are willing to live without stack 20# If you know what you are doing and are willing to live without stack
7# traces, you can get a slightly smaller kernel by setting this option to 21# traces, you can get a slightly smaller kernel by setting this option to
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 59c1ce858fc8..502255905c4e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -183,6 +183,7 @@ machine-$(CONFIG_ARCH_SHARK) := shark
183machine-$(CONFIG_ARCH_SHMOBILE) := shmobile 183machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
184machine-$(CONFIG_ARCH_STMP378X) := stmp378x 184machine-$(CONFIG_ARCH_STMP378X) := stmp378x
185machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx 185machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
186machine-$(CONFIG_ARCH_TCC8K) := tcc8k
186machine-$(CONFIG_ARCH_TEGRA) := tegra 187machine-$(CONFIG_ARCH_TEGRA) := tegra
187machine-$(CONFIG_ARCH_U300) := u300 188machine-$(CONFIG_ARCH_U300) := u300
188machine-$(CONFIG_ARCH_U8500) := ux500 189machine-$(CONFIG_ARCH_U8500) := ux500
@@ -202,6 +203,7 @@ plat-$(CONFIG_ARCH_MXC) := mxc
202plat-$(CONFIG_ARCH_OMAP) := omap 203plat-$(CONFIG_ARCH_OMAP) := omap
203plat-$(CONFIG_ARCH_S3C64XX) := samsung 204plat-$(CONFIG_ARCH_S3C64XX) := samsung
204plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx 205plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
206plat-$(CONFIG_ARCH_TCC_926) := tcc
205plat-$(CONFIG_PLAT_IOP) := iop 207plat-$(CONFIG_PLAT_IOP) := iop
206plat-$(CONFIG_PLAT_NOMADIK) := nomadik 208plat-$(CONFIG_PLAT_NOMADIK) := nomadik
207plat-$(CONFIG_PLAT_ORION) := orion 209plat-$(CONFIG_PLAT_ORION) := orion
@@ -245,13 +247,14 @@ ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
245FASTFPE_OBJ :=$(FASTFPE)/ 247FASTFPE_OBJ :=$(FASTFPE)/
246endif 248endif
247 249
248# If we have a machine-specific directory, then include it in the build.
249core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
250core-y += $(machdirs) $(platdirs)
251core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ 250core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
252core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) 251core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
253core-$(CONFIG_VFP) += arch/arm/vfp/ 252core-$(CONFIG_VFP) += arch/arm/vfp/
254 253
254# If we have a machine-specific directory, then include it in the build.
255core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
256core-y += $(machdirs) $(platdirs)
257
255drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ 258drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
256 259
257libs-y := arch/arm/lib/ $(libs-y) 260libs-y := arch/arm/lib/ $(libs-y)
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 5747a8baa413..8bb66bca2e3e 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -127,4 +127,8 @@ struct mm_struct;
127extern unsigned long arch_randomize_brk(struct mm_struct *mm); 127extern unsigned long arch_randomize_brk(struct mm_struct *mm);
128#define arch_randomize_brk arch_randomize_brk 128#define arch_randomize_brk arch_randomize_brk
129 129
130extern int vectors_user_mapping(void);
131#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
132#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
133
130#endif 134#endif
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1261b1f928d9..815efa2d4e07 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -294,6 +294,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
294#define ARCH_HAS_VALID_PHYS_ADDR_RANGE 294#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
295extern int valid_phys_addr_range(unsigned long addr, size_t size); 295extern int valid_phys_addr_range(unsigned long addr, size_t size);
296extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); 296extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
297extern int devmem_is_allowed(unsigned long pfn);
297#endif 298#endif
298 299
299/* 300/*
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index a0b3cac0547c..71605d9f8e42 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -18,7 +18,6 @@
18#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
19#include <asm/cachetype.h> 19#include <asm/cachetype.h>
20#include <asm/proc-fns.h> 20#include <asm/proc-fns.h>
21#include <asm-generic/mm_hooks.h>
22 21
23void __check_kvm_seq(struct mm_struct *mm); 22void __check_kvm_seq(struct mm_struct *mm);
24 23
@@ -134,4 +133,32 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
134#define deactivate_mm(tsk,mm) do { } while (0) 133#define deactivate_mm(tsk,mm) do { } while (0)
135#define activate_mm(prev,next) switch_mm(prev, next, NULL) 134#define activate_mm(prev,next) switch_mm(prev, next, NULL)
136 135
136/*
137 * We are inserting a "fake" vma for the user-accessible vector page so
138 * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
139 * But we also want to remove it before the generic code gets to see it
140 * during process exit or the unmapping of it would cause total havoc.
141 * (the macro is used as remove_vma() is static to mm/mmap.c)
142 */
143#define arch_exit_mmap(mm) \
144do { \
145 struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
146 if (high_vma) { \
147 BUG_ON(high_vma->vm_next); /* it should be last */ \
148 if (high_vma->vm_prev) \
149 high_vma->vm_prev->vm_next = NULL; \
150 else \
151 mm->mmap = NULL; \
152 rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
153 mm->mmap_cache = NULL; \
154 mm->map_count--; \
155 remove_vma(high_vma); \
156 } \
157} while (0)
158
159static inline void arch_dup_mmap(struct mm_struct *oldmm,
160 struct mm_struct *mm)
161{
162}
163
137#endif 164#endif
diff --git a/arch/arm/include/asm/seccomp.h b/arch/arm/include/asm/seccomp.h
new file mode 100644
index 000000000000..52b156b341f5
--- /dev/null
+++ b/arch/arm/include/asm/seccomp.h
@@ -0,0 +1,11 @@
1#ifndef _ASM_ARM_SECCOMP_H
2#define _ASM_ARM_SECCOMP_H
3
4#include <linux/unistd.h>
5
6#define __NR_seccomp_read __NR_read
7#define __NR_seccomp_write __NR_write
8#define __NR_seccomp_exit __NR_exit
9#define __NR_seccomp_sigreturn __NR_rt_sigreturn
10
11#endif /* _ASM_ARM_SECCOMP_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 763e29fa8530..7b5cc8dae06e 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -144,6 +144,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
144#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ 144#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
145#define TIF_FREEZE 19 145#define TIF_FREEZE 19
146#define TIF_RESTORE_SIGMASK 20 146#define TIF_RESTORE_SIGMASK 20
147#define TIF_SECCOMP 21
147 148
148#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 149#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
149#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 150#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
@@ -153,6 +154,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
153#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) 154#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
154#define _TIF_FREEZE (1 << TIF_FREEZE) 155#define _TIF_FREEZE (1 << TIF_FREEZE)
155#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 156#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
157#define _TIF_SECCOMP (1 << TIF_SECCOMP)
156 158
157/* 159/*
158 * Change these and you break ASM code in entry-common.S 160 * Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 7885722bdf4e..0385a8207b67 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -295,7 +295,6 @@ ENTRY(vector_swi)
295 295
296 get_thread_info tsk 296 get_thread_info tsk
297 adr tbl, sys_call_table @ load syscall table pointer 297 adr tbl, sys_call_table @ load syscall table pointer
298 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
299 298
300#if defined(CONFIG_OABI_COMPAT) 299#if defined(CONFIG_OABI_COMPAT)
301 /* 300 /*
@@ -312,8 +311,20 @@ ENTRY(vector_swi)
312 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number 311 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
313#endif 312#endif
314 313
314 ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
315 stmdb sp!, {r4, r5} @ push fifth and sixth args 315 stmdb sp!, {r4, r5} @ push fifth and sixth args
316 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 316
317#ifdef CONFIG_SECCOMP
318 tst r10, #_TIF_SECCOMP
319 beq 1f
320 mov r0, scno
321 bl __secure_computing
322 add r0, sp, #S_R0 + S_OFF @ pointer to regs
323 ldmia r0, {r0 - r3} @ have to reload r0 - r3
3241:
325#endif
326
327 tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
317 bne __sys_trace 328 bne __sys_trace
318 329
319 cmp scno, #NR_syscalls @ check upper syscall limit 330 cmp scno, #NR_syscalls @ check upper syscall limit
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 401e38be1f78..66ac9c926200 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -458,3 +458,24 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
458 unsigned long range_end = mm->brk + 0x02000000; 458 unsigned long range_end = mm->brk + 0x02000000;
459 return randomize_range(mm->brk, range_end, 0) ? : mm->brk; 459 return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
460} 460}
461
462/*
463 * The vectors page is always readable from user space for the
464 * atomic helpers and the signal restart code. Let's declare a mapping
465 * for it so it is visible through ptrace and /proc/<pid>/mem.
466 */
467
468int vectors_user_mapping(void)
469{
470 struct mm_struct *mm = current->mm;
471 return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
472 VM_READ | VM_EXEC |
473 VM_MAYREAD | VM_MAYEXEC |
474 VM_ALWAYSDUMP | VM_RESERVED,
475 NULL);
476}
477
478const char *arch_vma_name(struct vm_area_struct *vma)
479{
480 return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
481}
diff --git a/arch/arm/mach-aaec2000/include/mach/vmalloc.h b/arch/arm/mach-aaec2000/include/mach/vmalloc.h
index 551f68f666bf..cff4e0a996ce 100644
--- a/arch/arm/mach-aaec2000/include/mach/vmalloc.h
+++ b/arch/arm/mach-aaec2000/include/mach/vmalloc.h
@@ -11,6 +11,6 @@
11#ifndef __ASM_ARCH_VMALLOC_H 11#ifndef __ASM_ARCH_VMALLOC_H
12#define __ASM_ARCH_VMALLOC_H 12#define __ASM_ARCH_VMALLOC_H
13 13
14#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 14#define VMALLOC_END 0xd0000000
15 15
16#endif /* __ASM_ARCH_VMALLOC_H */ 16#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h
index 35e2ead8395c..3db3a09fd398 100644
--- a/arch/arm/mach-bcmring/include/mach/vmalloc.h
+++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h
@@ -22,4 +22,4 @@
22 * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles 22 * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
23 * larger physical memory designs better. 23 * larger physical memory designs better.
24 */ 24 */
25#define VMALLOC_END (PAGE_OFFSET + 0x30000000) 25#define VMALLOC_END 0xf0000000
diff --git a/arch/arm/mach-clps711x/include/mach/vmalloc.h b/arch/arm/mach-clps711x/include/mach/vmalloc.h
index ea6cc7beff28..30b3a287ed88 100644
--- a/arch/arm/mach-clps711x/include/mach/vmalloc.h
+++ b/arch/arm/mach-clps711x/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 20#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-ebsa110/include/mach/vmalloc.h b/arch/arm/mach-ebsa110/include/mach/vmalloc.h
index 9b44c19e95ec..60bde56fba4c 100644
--- a/arch/arm/mach-ebsa110/include/mach/vmalloc.h
+++ b/arch/arm/mach-ebsa110/include/mach/vmalloc.h
@@ -7,4 +7,4 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#define VMALLOC_END (PAGE_OFFSET + 0x1f000000) 10#define VMALLOC_END 0xdf000000
diff --git a/arch/arm/mach-footbridge/include/mach/vmalloc.h b/arch/arm/mach-footbridge/include/mach/vmalloc.h
index d0958d860a3c..0ffbb7c85e59 100644
--- a/arch/arm/mach-footbridge/include/mach/vmalloc.h
+++ b/arch/arm/mach-footbridge/include/mach/vmalloc.h
@@ -7,4 +7,4 @@
7 */ 7 */
8 8
9 9
10#define VMALLOC_END (PAGE_OFFSET + 0x30000000) 10#define VMALLOC_END 0xf0000000
diff --git a/arch/arm/mach-h720x/include/mach/vmalloc.h b/arch/arm/mach-h720x/include/mach/vmalloc.h
index ff1460d6841b..a45915b88756 100644
--- a/arch/arm/mach-h720x/include/mach/vmalloc.h
+++ b/arch/arm/mach-h720x/include/mach/vmalloc.h
@@ -5,6 +5,6 @@
5#ifndef __ARCH_ARM_VMALLOC_H 5#ifndef __ARCH_ARM_VMALLOC_H
6#define __ARCH_ARM_VMALLOC_H 6#define __ARCH_ARM_VMALLOC_H
7 7
8#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 8#define VMALLOC_END 0xd0000000
9 9
10#endif 10#endif
diff --git a/arch/arm/mach-integrator/include/mach/vmalloc.h b/arch/arm/mach-integrator/include/mach/vmalloc.h
index e87ab0b37bdd..e056e7cf5645 100644
--- a/arch/arm/mach-integrator/include/mach/vmalloc.h
+++ b/arch/arm/mach-integrator/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 20#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-msm/include/mach/vmalloc.h b/arch/arm/mach-msm/include/mach/vmalloc.h
index 05f81fd8623c..31a32ad062dc 100644
--- a/arch/arm/mach-msm/include/mach/vmalloc.h
+++ b/arch/arm/mach-msm/include/mach/vmalloc.h
@@ -16,7 +16,7 @@
16#ifndef __ASM_ARCH_MSM_VMALLOC_H 16#ifndef __ASM_ARCH_MSM_VMALLOC_H
17#define __ASM_ARCH_MSM_VMALLOC_H 17#define __ASM_ARCH_MSM_VMALLOC_H
18 18
19#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 19#define VMALLOC_END 0xd0000000
20 20
21#endif 21#endif
22 22
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
index 2d37785e3857..eaacb6e9b5d0 100644
--- a/arch/arm/mach-mx5/cpu.c
+++ b/arch/arm/mach-mx5/cpu.c
@@ -70,6 +70,25 @@ int mx51_revision(void)
70} 70}
71EXPORT_SYMBOL(mx51_revision); 71EXPORT_SYMBOL(mx51_revision);
72 72
73#ifdef CONFIG_NEON
74
75/*
76 * All versions of the silicon before Rev. 3 have broken NEON implementations.
77 * Dependent on link order - so the assumption is that vfp_init is called
78 * before us.
79 */
80static int __init mx51_neon_fixup(void)
81{
82 if (mx51_revision() < MX51_CHIP_REV_3_0 && (elf_hwcap & HWCAP_NEON)) {
83 elf_hwcap &= ~HWCAP_NEON;
84 pr_info("Turning off NEON support, detected broken NEON implementation\n");
85 }
86 return 0;
87}
88
89late_initcall(mx51_neon_fixup);
90#endif
91
73static int __init post_cpu_init(void) 92static int __init post_cpu_init(void)
74{ 93{
75 unsigned int reg; 94 unsigned int reg;
diff --git a/arch/arm/mach-netx/include/mach/vmalloc.h b/arch/arm/mach-netx/include/mach/vmalloc.h
index 25d5cc676e0f..7cca3574308f 100644
--- a/arch/arm/mach-netx/include/mach/vmalloc.h
+++ b/arch/arm/mach-netx/include/mach/vmalloc.h
@@ -16,4 +16,4 @@
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 19#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-omap1/include/mach/vmalloc.h b/arch/arm/mach-omap1/include/mach/vmalloc.h
index 1b2af14df151..b001f67d695b 100644
--- a/arch/arm/mach-omap1/include/mach/vmalloc.h
+++ b/arch/arm/mach-omap1/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#define VMALLOC_END (PAGE_OFFSET + 0x18000000) 20#define VMALLOC_END 0xd8000000
diff --git a/arch/arm/mach-omap2/include/mach/vmalloc.h b/arch/arm/mach-omap2/include/mach/vmalloc.h
index 9ce9b6e8ad23..4da31e997efe 100644
--- a/arch/arm/mach-omap2/include/mach/vmalloc.h
+++ b/arch/arm/mach-omap2/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#define VMALLOC_END (PAGE_OFFSET + 0x38000000) 20#define VMALLOC_END 0xf8000000
diff --git a/arch/arm/mach-pnx4008/include/mach/vmalloc.h b/arch/arm/mach-pnx4008/include/mach/vmalloc.h
index 2ad398378aed..31b65ee07b0b 100644
--- a/arch/arm/mach-pnx4008/include/mach/vmalloc.h
+++ b/arch/arm/mach-pnx4008/include/mach/vmalloc.h
@@ -17,4 +17,4 @@
17 * The vmalloc() routines leaves a hole of 4kB between each vmalloced 17 * The vmalloc() routines leaves a hole of 4kB between each vmalloced
18 * area for the same reason. ;) 18 * area for the same reason. ;)
19 */ 19 */
20#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 20#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-rpc/include/mach/vmalloc.h b/arch/arm/mach-rpc/include/mach/vmalloc.h
index 9a96fd69e705..3bcd86fadb81 100644
--- a/arch/arm/mach-rpc/include/mach/vmalloc.h
+++ b/arch/arm/mach-rpc/include/mach/vmalloc.h
@@ -7,4 +7,4 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#define VMALLOC_END (PAGE_OFFSET + 0x1c000000) 10#define VMALLOC_END 0xdc000000
diff --git a/arch/arm/mach-shark/include/mach/vmalloc.h b/arch/arm/mach-shark/include/mach/vmalloc.h
index f6c6837c5451..8e845b6a7cb5 100644
--- a/arch/arm/mach-shark/include/mach/vmalloc.h
+++ b/arch/arm/mach-shark/include/mach/vmalloc.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * arch/arm/mach-shark/include/mach/vmalloc.h 2 * arch/arm/mach-shark/include/mach/vmalloc.h
3 */ 3 */
4#define VMALLOC_END (PAGE_OFFSET + 0x10000000) 4#define VMALLOC_END 0xd0000000
diff --git a/arch/arm/mach-tcc8k/Kconfig b/arch/arm/mach-tcc8k/Kconfig
new file mode 100644
index 000000000000..ad86415d1577
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Kconfig
@@ -0,0 +1,11 @@
1if ARCH_TCC8K
2
3comment "TCC8000 systems:"
4
5config MACH_TCC8000_SDK
6 bool "Telechips TCC8000-SDK development kit"
7 default y
8 help
9 Support for the Telechips TCC8000-SDK board.
10
11endif
diff --git a/arch/arm/mach-tcc8k/Makefile b/arch/arm/mach-tcc8k/Makefile
new file mode 100644
index 000000000000..9bacf31e49ba
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for TCC8K boards and common files.
3#
4
5# Common support
6obj-y += clock.o irq.o time.o io.o devices.o
7
8# Board specific support
9obj-$(CONFIG_MACH_TCC8000_SDK) += board-tcc8000-sdk.o
diff --git a/arch/arm/mach-tcc8k/Makefile.boot b/arch/arm/mach-tcc8k/Makefile.boot
new file mode 100644
index 000000000000..f135c9deae10
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x20008000
2params_phys-y := 0x20000100
3initrd_phys-y := 0x20800000
diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
new file mode 100644
index 000000000000..4e42555b2009
--- /dev/null
+++ b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/platform_device.h>
12
13#include <asm/mach-types.h>
14
15#include <asm/mach/arch.h>
16#include <asm/mach/map.h>
17#include <asm/mach/time.h>
18
19#include <mach/clock.h>
20
21#include "common.h"
22
23#define XI_FREQUENCY 12000000
24#define XTI_FREQUENCY 32768
25
26#ifdef CONFIG_MTD_NAND_TCC
27/* NAND */
28static struct tcc_nand_platform_data tcc8k_sdk_nand_data = {
29 .width = 1,
30 .hw_ecc = 0,
31};
32#endif
33
34static void __init tcc8k_init(void)
35{
36#ifdef CONFIG_MTD_NAND_TCC
37 tcc_nand_device.dev.platform_data = &tcc8k_sdk_nand_data;
38 platform_device_register(&tcc_nand_device);
39#endif
40}
41
42static void __init tcc8k_init_timer(void)
43{
44 tcc_clocks_init(XI_FREQUENCY, XTI_FREQUENCY);
45}
46
47static struct sys_timer tcc8k_timer = {
48 .init = tcc8k_init_timer,
49};
50
51static void __init tcc8k_map_io(void)
52{
53 tcc8k_map_common_io();
54}
55
56MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board")
57 .phys_io = 0x90000000,
58 .io_pg_offst = ((0xf1000000) >> 18) & 0xfffc,
59 .boot_params = PHYS_OFFSET + 0x00000100,
60 .map_io = tcc8k_map_io,
61 .init_irq = tcc8k_init_irq,
62 .init_machine = tcc8k_init,
63 .timer = &tcc8k_timer,
64MACHINE_END
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
new file mode 100644
index 000000000000..ba32a15127ab
--- /dev/null
+++ b/arch/arm/mach-tcc8k/clock.c
@@ -0,0 +1,567 @@
1/*
2 * Lowlevel clock handling for Telechips TCC8xxx SoCs
3 *
4 * Copyright (C) 2010 by Hans J. Koch <hjk@linutronix.de>
5 *
6 * Licensed under the terms of the GPL v2
7 */
8
9#include <linux/clk.h>
10#include <linux/delay.h>
11#include <linux/err.h>
12#include <linux/io.h>
13#include <linux/module.h>
14#include <linux/spinlock.h>
15
16#include <asm/clkdev.h>
17
18#include <mach/clock.h>
19#include <mach/irqs.h>
20#include <mach/tcc8k-regs.h>
21
22#include "common.h"
23
24#define BCLKCTR0 (CKC_BASE + BCLKCTR0_OFFS)
25#define BCLKCTR1 (CKC_BASE + BCLKCTR1_OFFS)
26
27#define ACLKREF (CKC_BASE + ACLKREF_OFFS)
28#define ACLKUART0 (CKC_BASE + ACLKUART0_OFFS)
29#define ACLKUART1 (CKC_BASE + ACLKUART1_OFFS)
30#define ACLKUART2 (CKC_BASE + ACLKUART2_OFFS)
31#define ACLKUART3 (CKC_BASE + ACLKUART3_OFFS)
32#define ACLKUART4 (CKC_BASE + ACLKUART4_OFFS)
33#define ACLKI2C (CKC_BASE + ACLKI2C_OFFS)
34#define ACLKADC (CKC_BASE + ACLKADC_OFFS)
35#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS)
36#define ACLKLCD (CKC_BASE + ACLKLCD_OFFS)
37#define ACLKSDH0 (CKC_BASE + ACLKSDH0_OFFS)
38#define ACLKSDH1 (CKC_BASE + ACLKSDH1_OFFS)
39#define ACLKSPI0 (CKC_BASE + ACLKSPI0_OFFS)
40#define ACLKSPI1 (CKC_BASE + ACLKSPI1_OFFS)
41#define ACLKSPDIF (CKC_BASE + ACLKSPDIF_OFFS)
42#define ACLKC3DEC (CKC_BASE + ACLKC3DEC_OFFS)
43#define ACLKCAN0 (CKC_BASE + ACLKCAN0_OFFS)
44#define ACLKCAN1 (CKC_BASE + ACLKCAN1_OFFS)
45#define ACLKGSB0 (CKC_BASE + ACLKGSB0_OFFS)
46#define ACLKGSB1 (CKC_BASE + ACLKGSB1_OFFS)
47#define ACLKGSB2 (CKC_BASE + ACLKGSB2_OFFS)
48#define ACLKGSB3 (CKC_BASE + ACLKGSB3_OFFS)
49#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS)
50#define ACLKTCT (CKC_BASE + ACLKTCT_OFFS)
51#define ACLKTCX (CKC_BASE + ACLKTCX_OFFS)
52#define ACLKTCZ (CKC_BASE + ACLKTCZ_OFFS)
53
54/* Crystal frequencies */
55static unsigned long xi_rate, xti_rate;
56
57static void __iomem *pll_cfg_addr(int pll)
58{
59 switch (pll) {
60 case 0: return (CKC_BASE + PLL0CFG_OFFS);
61 case 1: return (CKC_BASE + PLL1CFG_OFFS);
62 case 2: return (CKC_BASE + PLL2CFG_OFFS);
63 default:
64 BUG();
65 }
66}
67
68static int pll_enable(int pll, int enable)
69{
70 u32 reg;
71 void __iomem *addr = pll_cfg_addr(pll);
72
73 reg = __raw_readl(addr);
74 if (enable)
75 reg &= ~PLLxCFG_PD;
76 else
77 reg |= PLLxCFG_PD;
78
79 __raw_writel(reg, addr);
80 return 0;
81}
82
83static int xi_enable(int enable)
84{
85 u32 reg;
86
87 reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
88 if (enable)
89 reg |= CLKCTRL_XE;
90 else
91 reg &= ~CLKCTRL_XE;
92
93 __raw_writel(reg, CKC_BASE + CLKCTRL_OFFS);
94 return 0;
95}
96
97static int root_clk_enable(enum root_clks src)
98{
99 switch (src) {
100 case CLK_SRC_PLL0: return pll_enable(0, 1);
101 case CLK_SRC_PLL1: return pll_enable(1, 1);
102 case CLK_SRC_PLL2: return pll_enable(2, 1);
103 case CLK_SRC_XI: return xi_enable(1);
104 default:
105 BUG();
106 }
107 return 0;
108}
109
110static int root_clk_disable(enum root_clks root_src)
111{
112 switch (root_src) {
113 case CLK_SRC_PLL0: return pll_enable(0, 0);
114 case CLK_SRC_PLL1: return pll_enable(1, 0);
115 case CLK_SRC_PLL2: return pll_enable(2, 0);
116 case CLK_SRC_XI: return xi_enable(0);
117 default:
118 BUG();
119 }
120 return 0;
121}
122
123static int enable_clk(struct clk *clk)
124{
125 u32 reg;
126
127 if (clk->root_id != CLK_SRC_NOROOT)
128 return root_clk_enable(clk->root_id);
129
130 if (clk->aclkreg) {
131 reg = __raw_readl(clk->aclkreg);
132 reg |= ACLK_EN;
133 __raw_writel(reg, clk->aclkreg);
134 }
135 if (clk->bclkctr) {
136 reg = __raw_readl(clk->bclkctr);
137 reg |= 1 << clk->bclk_shift;
138 __raw_writel(reg, clk->bclkctr);
139 }
140 return 0;
141}
142
143static void disable_clk(struct clk *clk)
144{
145 u32 reg;
146
147 if (clk->root_id != CLK_SRC_NOROOT) {
148 root_clk_disable(clk->root_id);
149 return;
150 }
151
152 if (clk->bclkctr) {
153 reg = __raw_readl(clk->bclkctr);
154 reg &= ~(1 << clk->bclk_shift);
155 __raw_writel(reg, clk->bclkctr);
156 }
157 if (clk->aclkreg) {
158 reg = __raw_readl(clk->aclkreg);
159 reg &= ~ACLK_EN;
160 __raw_writel(reg, clk->aclkreg);
161 }
162}
163
164static unsigned long get_rate_pll(int pll)
165{
166 u32 reg;
167 unsigned long s, m, p;
168 void __iomem *addr = pll_cfg_addr(pll);
169
170 reg = __raw_readl(addr);
171 s = (reg >> 16) & 0x07;
172 m = (reg >> 8) & 0xff;
173 p = reg & 0x3f;
174
175 return (m * xi_rate) / (p * (1 << s));
176}
177
178static unsigned long get_rate_pll_div(int pll)
179{
180 u32 reg;
181 unsigned long div = 0;
182 void __iomem *addr;
183
184 switch (pll) {
185 case 0:
186 addr = CKC_BASE + CLKDIVC0_OFFS;
187 reg = __raw_readl(addr);
188 if (reg & CLKDIVC0_P0E)
189 div = (reg >> 24) & 0x3f;
190 break;
191 case 1:
192 addr = CKC_BASE + CLKDIVC0_OFFS;
193 reg = __raw_readl(addr);
194 if (reg & CLKDIVC0_P1E)
195 div = (reg >> 16) & 0x3f;
196 break;
197 case 2:
198 addr = CKC_BASE + CLKDIVC1_OFFS;
199 reg = __raw_readl(addr);
200 if (reg & CLKDIVC1_P2E)
201 div = __raw_readl(addr) & 0x3f;
202 break;
203 }
204 return get_rate_pll(pll) / (div + 1);
205}
206
207static unsigned long get_rate_xi_div(void)
208{
209 unsigned long div = 0;
210 u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
211
212 if (reg & CLKDIVC0_XE)
213 div = (reg >> 8) & 0x3f;
214
215 return xi_rate / (div + 1);
216}
217
218static unsigned long get_rate_xti_div(void)
219{
220 unsigned long div = 0;
221 u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
222
223 if (reg & CLKDIVC0_XTE)
224 div = reg & 0x3f;
225
226 return xti_rate / (div + 1);
227}
228
229static unsigned long root_clk_get_rate(enum root_clks src)
230{
231 switch (src) {
232 case CLK_SRC_PLL0: return get_rate_pll(0);
233 case CLK_SRC_PLL1: return get_rate_pll(1);
234 case CLK_SRC_PLL2: return get_rate_pll(2);
235 case CLK_SRC_PLL0DIV: return get_rate_pll_div(0);
236 case CLK_SRC_PLL1DIV: return get_rate_pll_div(1);
237 case CLK_SRC_PLL2DIV: return get_rate_pll_div(2);
238 case CLK_SRC_XI: return xi_rate;
239 case CLK_SRC_XTI: return xti_rate;
240 case CLK_SRC_XIDIV: return get_rate_xi_div();
241 case CLK_SRC_XTIDIV: return get_rate_xti_div();
242 default: return 0;
243 }
244}
245
246static unsigned long aclk_get_rate(struct clk *clk)
247{
248 u32 reg;
249 unsigned long div;
250 unsigned int src;
251
252 reg = __raw_readl(clk->aclkreg);
253 div = reg & 0x0fff;
254 src = (reg >> ACLK_SEL_SHIFT) & CLK_SRC_MASK;
255 return root_clk_get_rate(src) / (div + 1);
256}
257
258static unsigned long aclk_best_div(struct clk *clk, unsigned long rate)
259{
260 unsigned long div, src, freq, r1, r2;
261
262 src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
263 src &= CLK_SRC_MASK;
264 freq = root_clk_get_rate(src);
265 div = freq / rate + 1;
266 r1 = freq / div;
267 r2 = freq / (div + 1);
268 if (r2 >= rate)
269 return div + 1;
270 if ((rate - r2) < (r1 - rate))
271 return div + 1;
272
273 return div;
274}
275
276static unsigned long aclk_round_rate(struct clk *clk, unsigned long rate)
277{
278 unsigned int src;
279
280 src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
281 src &= CLK_SRC_MASK;
282
283 return root_clk_get_rate(src) / aclk_best_div(clk, rate);
284}
285
286static int aclk_set_rate(struct clk *clk, unsigned long rate)
287{
288 u32 reg;
289
290 reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK;
291 reg |= aclk_best_div(clk, rate);
292 return 0;
293}
294
295static unsigned long get_rate_sys(struct clk *clk)
296{
297 unsigned int src;
298
299 src = __raw_readl(CKC_BASE + CLKCTRL_OFFS) & CLK_SRC_MASK;
300 return root_clk_get_rate(src);
301}
302
303static unsigned long get_rate_bus(struct clk *clk)
304{
305 unsigned int div;
306
307 div = (__raw_readl(CKC_BASE + CLKCTRL_OFFS) >> 4) & 0xff;
308 return get_rate_sys(clk) / (div + 1);
309}
310
311static unsigned long get_rate_cpu(struct clk *clk)
312{
313 unsigned int reg, div, fsys, fbus;
314
315 fbus = get_rate_bus(clk);
316 reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
317 if (reg & (1 << 29))
318 return fbus;
319 fsys = get_rate_sys(clk);
320 div = (reg >> 16) & 0x0f;
321 return fbus + ((fsys - fbus) * (div + 1)) / 16;
322}
323
324static unsigned long get_rate_root(struct clk *clk)
325{
326 return root_clk_get_rate(clk->root_id);
327}
328
329static int aclk_set_parent(struct clk *clock, struct clk *parent)
330{
331 u32 reg;
332
333 if (clock->parent == parent)
334 return 0;
335
336 clock->parent = parent;
337
338 if (!parent)
339 return 0;
340
341 if (parent->root_id == CLK_SRC_NOROOT)
342 return 0;
343 reg = __raw_readl(clock->aclkreg);
344 reg &= ~ACLK_SEL_MASK;
345 reg |= (parent->root_id << ACLK_SEL_SHIFT) & ACLK_SEL_MASK;
346 __raw_writel(reg, clock->aclkreg);
347
348 return 0;
349}
350
351#define DEFINE_ROOT_CLOCK(name, ri, p) \
352 static struct clk name = { \
353 .root_id = ri, \
354 .get_rate = get_rate_root, \
355 .enable = enable_clk, \
356 .disable = disable_clk, \
357 .parent = p, \
358 };
359
360#define DEFINE_SPECIAL_CLOCK(name, gr, p) \
361 static struct clk name = { \
362 .root_id = CLK_SRC_NOROOT, \
363 .get_rate = gr, \
364 .parent = p, \
365 };
366
367#define DEFINE_ACLOCK(name, bc, bs, ar) \
368 static struct clk name = { \
369 .root_id = CLK_SRC_NOROOT, \
370 .bclkctr = bc, \
371 .bclk_shift = bs, \
372 .aclkreg = ar, \
373 .get_rate = aclk_get_rate, \
374 .set_rate = aclk_set_rate, \
375 .round_rate = aclk_round_rate, \
376 .enable = enable_clk, \
377 .disable = disable_clk, \
378 .set_parent = aclk_set_parent, \
379 };
380
381#define DEFINE_BCLOCK(name, bc, bs, gr, p) \
382 static struct clk name = { \
383 .root_id = CLK_SRC_NOROOT, \
384 .bclkctr = bc, \
385 .bclk_shift = bs, \
386 .get_rate = gr, \
387 .enable = enable_clk, \
388 .disable = disable_clk, \
389 .parent = p, \
390 };
391
392DEFINE_ROOT_CLOCK(xi, CLK_SRC_XI, NULL)
393DEFINE_ROOT_CLOCK(xti, CLK_SRC_XTI, NULL)
394DEFINE_ROOT_CLOCK(xidiv, CLK_SRC_XIDIV, &xi)
395DEFINE_ROOT_CLOCK(xtidiv, CLK_SRC_XTIDIV, &xti)
396DEFINE_ROOT_CLOCK(pll0, CLK_SRC_PLL0, &xi)
397DEFINE_ROOT_CLOCK(pll1, CLK_SRC_PLL1, &xi)
398DEFINE_ROOT_CLOCK(pll2, CLK_SRC_PLL2, &xi)
399DEFINE_ROOT_CLOCK(pll0div, CLK_SRC_PLL0DIV, &pll0)
400DEFINE_ROOT_CLOCK(pll1div, CLK_SRC_PLL1DIV, &pll1)
401DEFINE_ROOT_CLOCK(pll2div, CLK_SRC_PLL2DIV, &pll2)
402
403/* The following 3 clocks are special and are initialized explicitly later */
404DEFINE_SPECIAL_CLOCK(sys, get_rate_sys, NULL)
405DEFINE_SPECIAL_CLOCK(bus, get_rate_bus, &sys)
406DEFINE_SPECIAL_CLOCK(cpu, get_rate_cpu, &sys)
407
408DEFINE_ACLOCK(tct, NULL, 0, ACLKTCT)
409DEFINE_ACLOCK(tcx, NULL, 0, ACLKTCX)
410DEFINE_ACLOCK(tcz, NULL, 0, ACLKTCZ)
411DEFINE_ACLOCK(ref, NULL, 0, ACLKREF)
412DEFINE_ACLOCK(uart0, BCLKCTR0, 5, ACLKUART0)
413DEFINE_ACLOCK(uart1, BCLKCTR0, 23, ACLKUART1)
414DEFINE_ACLOCK(uart2, BCLKCTR0, 6, ACLKUART2)
415DEFINE_ACLOCK(uart3, BCLKCTR0, 8, ACLKUART3)
416DEFINE_ACLOCK(uart4, BCLKCTR1, 6, ACLKUART4)
417DEFINE_ACLOCK(i2c, BCLKCTR0, 7, ACLKI2C)
418DEFINE_ACLOCK(adc, BCLKCTR0, 10, ACLKADC)
419DEFINE_ACLOCK(usbh0, BCLKCTR0, 11, ACLKUSBH)
420DEFINE_ACLOCK(lcd, BCLKCTR0, 13, ACLKLCD)
421DEFINE_ACLOCK(sd0, BCLKCTR0, 17, ACLKSDH0)
422DEFINE_ACLOCK(sd1, BCLKCTR1, 5, ACLKSDH1)
423DEFINE_ACLOCK(spi0, BCLKCTR0, 24, ACLKSPI0)
424DEFINE_ACLOCK(spi1, BCLKCTR0, 30, ACLKSPI1)
425DEFINE_ACLOCK(spdif, BCLKCTR1, 2, ACLKSPDIF)
426DEFINE_ACLOCK(c3dec, BCLKCTR1, 9, ACLKC3DEC)
427DEFINE_ACLOCK(can0, BCLKCTR1, 10, ACLKCAN0)
428DEFINE_ACLOCK(can1, BCLKCTR1, 11, ACLKCAN1)
429DEFINE_ACLOCK(gsb0, BCLKCTR1, 13, ACLKGSB0)
430DEFINE_ACLOCK(gsb1, BCLKCTR1, 14, ACLKGSB1)
431DEFINE_ACLOCK(gsb2, BCLKCTR1, 15, ACLKGSB2)
432DEFINE_ACLOCK(gsb3, BCLKCTR1, 16, ACLKGSB3)
433DEFINE_ACLOCK(usbh1, BCLKCTR1, 20, ACLKUSBH)
434
435DEFINE_BCLOCK(dai0, BCLKCTR0, 0, NULL, NULL)
436DEFINE_BCLOCK(pic, BCLKCTR0, 1, NULL, NULL)
437DEFINE_BCLOCK(tc, BCLKCTR0, 2, NULL, NULL)
438DEFINE_BCLOCK(gpio, BCLKCTR0, 3, NULL, NULL)
439DEFINE_BCLOCK(usbd, BCLKCTR0, 4, NULL, NULL)
440DEFINE_BCLOCK(ecc, BCLKCTR0, 9, NULL, NULL)
441DEFINE_BCLOCK(gdma0, BCLKCTR0, 12, NULL, NULL)
442DEFINE_BCLOCK(rtc, BCLKCTR0, 15, NULL, NULL)
443DEFINE_BCLOCK(nfc, BCLKCTR0, 16, NULL, NULL)
444DEFINE_BCLOCK(g2d, BCLKCTR0, 18, NULL, NULL)
445DEFINE_BCLOCK(gdma1, BCLKCTR0, 22, NULL, NULL)
446DEFINE_BCLOCK(mscl, BCLKCTR0, 25, NULL, NULL)
447DEFINE_BCLOCK(bdma, BCLKCTR1, 0, NULL, NULL)
448DEFINE_BCLOCK(adma0, BCLKCTR1, 1, NULL, NULL)
449DEFINE_BCLOCK(scfg, BCLKCTR1, 3, NULL, NULL)
450DEFINE_BCLOCK(cid, BCLKCTR1, 4, NULL, NULL)
451DEFINE_BCLOCK(dai1, BCLKCTR1, 7, NULL, NULL)
452DEFINE_BCLOCK(adma1, BCLKCTR1, 8, NULL, NULL)
453DEFINE_BCLOCK(gps, BCLKCTR1, 12, NULL, NULL)
454DEFINE_BCLOCK(gdma2, BCLKCTR1, 17, NULL, NULL)
455DEFINE_BCLOCK(gdma3, BCLKCTR1, 18, NULL, NULL)
456DEFINE_BCLOCK(ddrc, BCLKCTR1, 19, NULL, NULL)
457
458#define _REGISTER_CLOCK(d, n, c) \
459 { \
460 .dev_id = d, \
461 .con_id = n, \
462 .clk = &c, \
463 },
464
465static struct clk_lookup lookups[] = {
466 _REGISTER_CLOCK(NULL, "bus", bus)
467 _REGISTER_CLOCK(NULL, "cpu", cpu)
468 _REGISTER_CLOCK(NULL, "tct", tct)
469 _REGISTER_CLOCK(NULL, "tcx", tcx)
470 _REGISTER_CLOCK(NULL, "tcz", tcz)
471 _REGISTER_CLOCK(NULL, "ref", ref)
472 _REGISTER_CLOCK(NULL, "dai0", dai0)
473 _REGISTER_CLOCK(NULL, "pic", pic)
474 _REGISTER_CLOCK(NULL, "tc", tc)
475 _REGISTER_CLOCK(NULL, "gpio", gpio)
476 _REGISTER_CLOCK(NULL, "usbd", usbd)
477 _REGISTER_CLOCK("tcc-uart.0", NULL, uart0)
478 _REGISTER_CLOCK("tcc-uart.2", NULL, uart2)
479 _REGISTER_CLOCK("tcc-i2c", NULL, i2c)
480 _REGISTER_CLOCK("tcc-uart.3", NULL, uart3)
481 _REGISTER_CLOCK(NULL, "ecc", ecc)
482 _REGISTER_CLOCK(NULL, "adc", adc)
483 _REGISTER_CLOCK("tcc-usbh.0", "usb", usbh0)
484 _REGISTER_CLOCK(NULL, "gdma0", gdma0)
485 _REGISTER_CLOCK(NULL, "lcd", lcd)
486 _REGISTER_CLOCK(NULL, "rtc", rtc)
487 _REGISTER_CLOCK(NULL, "nfc", nfc)
488 _REGISTER_CLOCK("tcc-mmc.0", NULL, sd0)
489 _REGISTER_CLOCK(NULL, "g2d", g2d)
490 _REGISTER_CLOCK(NULL, "gdma1", gdma1)
491 _REGISTER_CLOCK("tcc-uart.1", NULL, uart1)
492 _REGISTER_CLOCK("tcc-spi.0", NULL, spi0)
493 _REGISTER_CLOCK(NULL, "mscl", mscl)
494 _REGISTER_CLOCK("tcc-spi.1", NULL, spi1)
495 _REGISTER_CLOCK(NULL, "bdma", bdma)
496 _REGISTER_CLOCK(NULL, "adma0", adma0)
497 _REGISTER_CLOCK(NULL, "spdif", spdif)
498 _REGISTER_CLOCK(NULL, "scfg", scfg)
499 _REGISTER_CLOCK(NULL, "cid", cid)
500 _REGISTER_CLOCK("tcc-mmc.1", NULL, sd1)
501 _REGISTER_CLOCK("tcc-uart.4", NULL, uart4)
502 _REGISTER_CLOCK(NULL, "dai1", dai1)
503 _REGISTER_CLOCK(NULL, "adma1", adma1)
504 _REGISTER_CLOCK(NULL, "c3dec", c3dec)
505 _REGISTER_CLOCK("tcc-can.0", NULL, can0)
506 _REGISTER_CLOCK("tcc-can.1", NULL, can1)
507 _REGISTER_CLOCK(NULL, "gps", gps)
508 _REGISTER_CLOCK("tcc-gsb.0", NULL, gsb0)
509 _REGISTER_CLOCK("tcc-gsb.1", NULL, gsb1)
510 _REGISTER_CLOCK("tcc-gsb.2", NULL, gsb2)
511 _REGISTER_CLOCK("tcc-gsb.3", NULL, gsb3)
512 _REGISTER_CLOCK(NULL, "gdma2", gdma2)
513 _REGISTER_CLOCK(NULL, "gdma3", gdma3)
514 _REGISTER_CLOCK(NULL, "ddrc", ddrc)
515 _REGISTER_CLOCK("tcc-usbh.1", "usb", usbh1)
516};
517
518static struct clk *root_clk_by_index(enum root_clks src)
519{
520 switch (src) {
521 case CLK_SRC_PLL0: return &pll0;
522 case CLK_SRC_PLL1: return &pll1;
523 case CLK_SRC_PLL2: return &pll2;
524 case CLK_SRC_PLL0DIV: return &pll0div;
525 case CLK_SRC_PLL1DIV: return &pll1div;
526 case CLK_SRC_PLL2DIV: return &pll2div;
527 case CLK_SRC_XI: return &xi;
528 case CLK_SRC_XTI: return &xti;
529 case CLK_SRC_XIDIV: return &xidiv;
530 case CLK_SRC_XTIDIV: return &xtidiv;
531 default: return NULL;
532 }
533}
534
535static void find_aclk_parent(struct clk *clk)
536{
537 unsigned int src;
538 struct clk *clock;
539
540 if (!clk->aclkreg)
541 return;
542
543 src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
544 src &= CLK_SRC_MASK;
545
546 clock = root_clk_by_index(src);
547 if (!clock)
548 return;
549
550 clk->parent = clock;
551 clk->set_parent = aclk_set_parent;
552}
553
554void __init tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq)
555{
556 int i;
557
558 xi_rate = xi_freq;
559 xti_rate = xti_freq;
560
561 /* fixup parents and add the clock */
562 for (i = 0; i < ARRAY_SIZE(lookups); i++) {
563 find_aclk_parent(lookups[i].clk);
564 clkdev_add(&lookups[i]);
565 }
566 tcc8k_timer_init(&tcz, (void __iomem *)TIMER_BASE, INT_TC32);
567}
diff --git a/arch/arm/mach-tcc8k/common.h b/arch/arm/mach-tcc8k/common.h
new file mode 100644
index 000000000000..705690add395
--- /dev/null
+++ b/arch/arm/mach-tcc8k/common.h
@@ -0,0 +1,15 @@
1#ifndef MACH_TCC8K_COMMON_H
2#define MACH_TCC8K_COMMON_H
3
4#include <linux/platform_device.h>
5
6extern struct platform_device tcc_nand_device;
7
8struct clk;
9
10extern void tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq);
11extern void tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq);
12extern void tcc8k_init_irq(void);
13extern void tcc8k_map_common_io(void);
14
15#endif
diff --git a/arch/arm/mach-tcc8k/devices.c b/arch/arm/mach-tcc8k/devices.c
new file mode 100644
index 000000000000..6722ad7c2836
--- /dev/null
+++ b/arch/arm/mach-tcc8k/devices.c
@@ -0,0 +1,239 @@
1/*
2 * linux/arch/arm/mach-tcc8k/devices.c
3 *
4 * Copyright (C) Telechips, Inc.
5 * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
6 *
7 * Licensed under the terms of GPL v2.
8 *
9 */
10
11#include <linux/dma-mapping.h>
12#include <linux/init.h>
13#include <linux/io.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16
17#include <asm/mach/map.h>
18
19#include <mach/tcc8k-regs.h>
20#include <mach/irqs.h>
21
22#include "common.h"
23
24static u64 tcc8k_dmamask = DMA_BIT_MASK(32);
25
26#ifdef CONFIG_MTD_NAND_TCC
27/* NAND controller */
28static struct resource tcc_nand_resources[] = {
29 {
30 .start = (resource_size_t)NFC_BASE,
31 .end = (resource_size_t)NFC_BASE + 0x7f,
32 .flags = IORESOURCE_MEM,
33 }, {
34 .start = INT_NFC,
35 .end = INT_NFC,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40struct platform_device tcc_nand_device = {
41 .name = "tcc_nand",
42 .id = 0,
43 .num_resources = ARRAY_SIZE(tcc_nand_resources),
44 .resource = tcc_nand_resources,
45};
46#endif
47
48#ifdef CONFIG_MMC_TCC8K
49/* MMC controller */
50static struct resource tcc8k_mmc0_resource[] = {
51 {
52 .start = INT_SD0,
53 .end = INT_SD0,
54 .flags = IORESOURCE_IRQ,
55 },
56};
57
58static struct resource tcc8k_mmc1_resource[] = {
59 {
60 .start = INT_SD1,
61 .end = INT_SD1,
62 .flags = IORESOURCE_IRQ,
63 },
64};
65
66struct platform_device tcc8k_mmc0_device = {
67 .name = "tcc-mmc",
68 .id = 0,
69 .num_resources = ARRAY_SIZE(tcc8k_mmc0_resource),
70 .resource = tcc8k_mmc0_resource,
71 .dev = {
72 .dma_mask = &tcc8k_dmamask,
73 .coherent_dma_mask = DMA_BIT_MASK(32),
74 }
75};
76
77struct platform_device tcc8k_mmc1_device = {
78 .name = "tcc-mmc",
79 .id = 1,
80 .num_resources = ARRAY_SIZE(tcc8k_mmc1_resource),
81 .resource = tcc8k_mmc1_resource,
82 .dev = {
83 .dma_mask = &tcc8k_dmamask,
84 .coherent_dma_mask = DMA_BIT_MASK(32),
85 }
86};
87
88static inline void tcc8k_init_mmc(void)
89{
90 u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS);
91
92 reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS;
93 __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS);
94
95 platform_device_register(&tcc8k_mmc0_device);
96 platform_device_register(&tcc8k_mmc1_device);
97}
98#else
99static inline void tcc8k_init_mmc(void) { }
100#endif
101
102#ifdef CONFIG_USB_OHCI_HCD
103static int tcc8k_ohci_init(struct device *dev)
104{
105 u32 reg;
106
107 /* Use GPIO PK19 as VBUS control output */
108 reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS);
109 reg &= ~(1 << 19);
110 __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS);
111 reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS);
112 reg &= ~(1 << 19);
113 __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS);
114
115 reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS);
116 reg |= (1 << 19);
117 __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS);
118 /* Turn on VBUS */
119 reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS);
120 reg |= (1 << 19);
121 __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS);
122
123 return 0;
124}
125
126static struct resource tcc8k_ohci0_resources[] = {
127 [0] = {
128 .start = (resource_size_t)USBH0_BASE,
129 .end = (resource_size_t)USBH0_BASE + 0x5c,
130 .flags = IORESOURCE_MEM,
131 },
132 [1] = {
133 .start = INT_USBH0,
134 .end = INT_USBH0,
135 .flags = IORESOURCE_IRQ,
136 }
137};
138
139static struct resource tcc8k_ohci1_resources[] = {
140 [0] = {
141 .start = (resource_size_t)USBH1_BASE,
142 .end = (resource_size_t)USBH1_BASE + 0x5c,
143 .flags = IORESOURCE_MEM,
144 },
145 [1] = {
146 .start = INT_USBH1,
147 .end = INT_USBH1,
148 .flags = IORESOURCE_IRQ,
149 }
150};
151
152static struct tccohci_platform_data tcc8k_ohci0_platform_data = {
153 .controller = 0,
154 .port_mode = PMM_PERPORT_MODE,
155 .init = tcc8k_ohci_init,
156};
157
158static struct tccohci_platform_data tcc8k_ohci1_platform_data = {
159 .controller = 1,
160 .port_mode = PMM_PERPORT_MODE,
161 .init = tcc8k_ohci_init,
162};
163
164static struct platform_device ohci0_device = {
165 .name = "tcc-ohci",
166 .id = 0,
167 .dev = {
168 .dma_mask = &tcc8k_dmamask,
169 .coherent_dma_mask = DMA_BIT_MASK(32),
170 .platform_data = &tcc8k_ohci0_platform_data,
171 },
172 .num_resources = ARRAY_SIZE(tcc8k_ohci0_resources),
173 .resource = tcc8k_ohci0_resources,
174};
175
176static struct platform_device ohci1_device = {
177 .name = "tcc-ohci",
178 .id = 1,
179 .dev = {
180 .dma_mask = &tcc8k_dmamask,
181 .coherent_dma_mask = DMA_BIT_MASK(32),
182 .platform_data = &tcc8k_ohci1_platform_data,
183 },
184 .num_resources = ARRAY_SIZE(tcc8k_ohci1_resources),
185 .resource = tcc8k_ohci1_resources,
186};
187
188static void __init tcc8k_init_usbhost(void)
189{
190 platform_device_register(&ohci0_device);
191 platform_device_register(&ohci1_device);
192}
193#else
194static void __init tcc8k_init_usbhost(void) { }
195#endif
196
197/* USB device controller*/
198#ifdef CONFIG_USB_GADGET_TCC8K
199static struct resource udc_resources[] = {
200 [0] = {
201 .start = INT_USBD,
202 .end = INT_USBD,
203 .flags = IORESOURCE_IRQ,
204 },
205 [1] = {
206 .start = INT_UDMA,
207 .end = INT_UDMA,
208 .flags = IORESOURCE_IRQ,
209 },
210};
211
212static struct platform_device tcc8k_udc_device = {
213 .name = "tcc-udc",
214 .id = 0,
215 .resource = udc_resources,
216 .num_resources = ARRAY_SIZE(udc_resources),
217 .dev = {
218 .dma_mask = &tcc8k_dmamask,
219 .coherent_dma_mask = DMA_BIT_MASK(32),
220 },
221};
222
223static void __init tcc8k_init_usb_gadget(void)
224{
225 platform_device_register(&tcc8k_udc_device);
226}
227#else
228static void __init tcc8k_init_usb_gadget(void) { }
229#endif /* CONFIG_USB_GADGET_TCC83X */
230
231static int __init tcc8k_init_devices(void)
232{
233 tcc8k_init_mmc();
234 tcc8k_init_usbhost();
235 tcc8k_init_usb_gadget();
236 return 0;
237}
238
239arch_initcall(tcc8k_init_devices);
diff --git a/arch/arm/mach-tcc8k/io.c b/arch/arm/mach-tcc8k/io.c
new file mode 100644
index 000000000000..9b39d7fa658f
--- /dev/null
+++ b/arch/arm/mach-tcc8k/io.c
@@ -0,0 +1,62 @@
1/*
2 * linux/arch/arm/mach-tcc8k/io.c
3 *
4 * (C) 2009 Hans J. Koch <hjk@linutronix.de>
5 *
6 * derived from TCC83xx io.c
7 * Copyright (C) Telechips, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/kernel.h>
17
18#include <asm/mach/map.h>
19
20#include <mach/tcc8k-regs.h>
21
22/*
23 * The machine specific code may provide the extra mapping besides the
24 * default mapping provided here.
25 */
26static struct map_desc tcc8k_io_desc[] __initdata = {
27 {
28 .virtual = (unsigned long)CS1_BASE_VIRT,
29 .pfn = __phys_to_pfn(CS1_BASE),
30 .length = CS1_SIZE,
31 .type = MT_DEVICE,
32 }, {
33 .virtual = (unsigned long)AHB_PERI_BASE_VIRT,
34 .pfn = __phys_to_pfn(AHB_PERI_BASE),
35 .length = AHB_PERI_SIZE,
36 .type = MT_DEVICE,
37 }, {
38 .virtual = (unsigned long)APB0_PERI_BASE_VIRT,
39 .pfn = __phys_to_pfn(APB0_PERI_BASE),
40 .length = APB0_PERI_SIZE,
41 .type = MT_DEVICE,
42 }, {
43 .virtual = (unsigned long)APB1_PERI_BASE_VIRT,
44 .pfn = __phys_to_pfn(APB1_PERI_BASE),
45 .length = APB1_PERI_SIZE,
46 .type = MT_DEVICE,
47 }, {
48 .virtual = (unsigned long)EXT_MEM_CTRL_BASE_VIRT,
49 .pfn = __phys_to_pfn(EXT_MEM_CTRL_BASE),
50 .length = EXT_MEM_CTRL_SIZE,
51 .type = MT_DEVICE,
52 },
53};
54
55/*
56 * Maps common IO regions for tcc8k.
57 *
58 */
59void __init tcc8k_map_common_io(void)
60{
61 iotable_init(tcc8k_io_desc, ARRAY_SIZE(tcc8k_io_desc));
62}
diff --git a/arch/arm/mach-tcc8k/irq.c b/arch/arm/mach-tcc8k/irq.c
new file mode 100644
index 000000000000..34575c4963f0
--- /dev/null
+++ b/arch/arm/mach-tcc8k/irq.c
@@ -0,0 +1,111 @@
1/*
2 * Copyright (C) Telechips, Inc.
3 * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de>
4 *
5 * Licensed under the terms of the GNU GPL version 2.
6 */
7
8#include <linux/init.h>
9#include <linux/interrupt.h>
10#include <linux/io.h>
11
12#include <asm/irq.h>
13#include <asm/mach/irq.h>
14
15#include <mach/tcc8k-regs.h>
16#include <mach/irqs.h>
17
18#include "common.h"
19
20/* Disable IRQ */
21static void tcc8000_mask_ack_irq0(unsigned int irq)
22{
23 PIC0_IEN &= ~(1 << irq);
24 PIC0_CREQ |= (1 << irq);
25}
26
27static void tcc8000_mask_ack_irq1(unsigned int irq)
28{
29 PIC1_IEN &= ~(1 << (irq - 32));
30 PIC1_CREQ |= (1 << (irq - 32));
31}
32
33static void tcc8000_mask_irq0(unsigned int irq)
34{
35 PIC0_IEN &= ~(1 << irq);
36}
37
38static void tcc8000_mask_irq1(unsigned int irq)
39{
40 PIC1_IEN &= ~(1 << (irq - 32));
41}
42
43static void tcc8000_ack_irq0(unsigned int irq)
44{
45 PIC0_CREQ |= (1 << irq);
46}
47
48static void tcc8000_ack_irq1(unsigned int irq)
49{
50 PIC1_CREQ |= (1 << (irq - 32));
51}
52
53/* Enable IRQ */
54static void tcc8000_unmask_irq0(unsigned int irq)
55{
56 PIC0_IEN |= (1 << irq);
57 PIC0_INTOEN |= (1 << irq);
58}
59
60static void tcc8000_unmask_irq1(unsigned int irq)
61{
62 PIC1_IEN |= (1 << (irq - 32));
63 PIC1_INTOEN |= (1 << (irq - 32));
64}
65
66static struct irq_chip tcc8000_irq_chip0 = {
67 .name = "tcc_irq0",
68 .mask = tcc8000_mask_irq0,
69 .ack = tcc8000_ack_irq0,
70 .mask_ack = tcc8000_mask_ack_irq0,
71 .unmask = tcc8000_unmask_irq0,
72};
73
74static struct irq_chip tcc8000_irq_chip1 = {
75 .name = "tcc_irq1",
76 .mask = tcc8000_mask_irq1,
77 .ack = tcc8000_ack_irq1,
78 .mask_ack = tcc8000_mask_ack_irq1,
79 .unmask = tcc8000_unmask_irq1,
80};
81
82void __init tcc8k_init_irq(void)
83{
84 int irqno;
85
86 /* Mask and clear all interrupts */
87 PIC0_IEN = 0x00000000;
88 PIC0_CREQ = 0xffffffff;
89 PIC1_IEN = 0x00000000;
90 PIC1_CREQ = 0xffffffff;
91
92 PIC0_MEN0 = 0x00000003;
93 PIC1_MEN1 = 0x00000003;
94 PIC1_MEN = 0x00000003;
95
96 /* let all IRQs be level triggered */
97 PIC0_TMODE = 0xffffffff;
98 PIC1_TMODE = 0xffffffff;
99 /* all IRQs are IRQs (not FIQs) */
100 PIC0_IRQSEL = 0xffffffff;
101 PIC1_IRQSEL = 0xffffffff;
102
103 for (irqno = 0; irqno < NR_IRQS; irqno++) {
104 if (irqno < 32)
105 set_irq_chip(irqno, &tcc8000_irq_chip0);
106 else
107 set_irq_chip(irqno, &tcc8000_irq_chip1);
108 set_irq_handler(irqno, handle_level_irq);
109 set_irq_flags(irqno, IRQF_VALID);
110 }
111}
diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c
new file mode 100644
index 000000000000..78d06008841d
--- /dev/null
+++ b/arch/arm/mach-tcc8k/time.c
@@ -0,0 +1,149 @@
1/*
2 * TCC8000 system timer setup
3 *
4 * (C) 2009 Hans J. Koch <hjk@linutronix.de>
5 *
6 * Licensed under the terms of the GPL version 2.
7 *
8 */
9
10#include <linux/clk.h>
11#include <linux/clockchips.h>
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/io.h>
15#include <linux/irq.h>
16#include <linux/kernel.h>
17#include <linux/spinlock.h>
18
19#include <asm/mach/time.h>
20
21#include <mach/tcc8k-regs.h>
22#include <mach/irqs.h>
23
24#include "common.h"
25
26static void __iomem *timer_base;
27
28static cycle_t tcc_get_cycles(struct clocksource *cs)
29{
30 return __raw_readl(timer_base + TC32MCNT_OFFS);
31}
32
33static struct clocksource clocksource_tcc = {
34 .name = "tcc_tc32",
35 .rating = 200,
36 .read = tcc_get_cycles,
37 .mask = CLOCKSOURCE_MASK(32),
38 .shift = 28,
39 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
40};
41
42static int tcc_set_next_event(unsigned long evt,
43 struct clock_event_device *unused)
44{
45 unsigned long reg = __raw_readl(timer_base + TC32MCNT_OFFS);
46
47 __raw_writel(reg + evt, timer_base + TC32CMP0_OFFS);
48 return 0;
49}
50
51static void tcc_set_mode(enum clock_event_mode mode,
52 struct clock_event_device *evt)
53{
54 unsigned long tc32irq;
55
56 switch (mode) {
57 case CLOCK_EVT_MODE_ONESHOT:
58 tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
59 tc32irq |= TC32IRQ_IRQEN0;
60 __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
61 break;
62 case CLOCK_EVT_MODE_SHUTDOWN:
63 case CLOCK_EVT_MODE_UNUSED:
64 tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
65 tc32irq &= ~TC32IRQ_IRQEN0;
66 __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
67 break;
68 case CLOCK_EVT_MODE_PERIODIC:
69 case CLOCK_EVT_MODE_RESUME:
70 break;
71 }
72}
73
74static irqreturn_t tcc8k_timer_interrupt(int irq, void *dev_id)
75{
76 struct clock_event_device *evt = dev_id;
77
78 /* Acknowledge TC32 interrupt by reading TC32IRQ */
79 __raw_readl(timer_base + TC32IRQ_OFFS);
80
81 evt->event_handler(evt);
82
83 return IRQ_HANDLED;
84}
85
86static struct clock_event_device clockevent_tcc = {
87 .name = "tcc_timer1",
88 .features = CLOCK_EVT_FEAT_ONESHOT,
89 .shift = 32,
90 .set_mode = tcc_set_mode,
91 .set_next_event = tcc_set_next_event,
92 .rating = 200,
93};
94
95static struct irqaction tcc8k_timer_irq = {
96 .name = "TC32_timer",
97 .flags = IRQF_DISABLED | IRQF_TIMER,
98 .handler = tcc8k_timer_interrupt,
99 .dev_id = &clockevent_tcc,
100};
101
102static int __init tcc_clockevent_init(struct clk *clock)
103{
104 unsigned int c = clk_get_rate(clock);
105
106 clocksource_tcc.mult = clocksource_hz2mult(c,
107 clocksource_tcc.shift);
108 clocksource_register(&clocksource_tcc);
109
110 clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
111 clockevent_tcc.shift);
112 clockevent_tcc.max_delta_ns =
113 clockevent_delta2ns(0xfffffffe, &clockevent_tcc);
114 clockevent_tcc.min_delta_ns =
115 clockevent_delta2ns(0xff, &clockevent_tcc);
116
117 clockevent_tcc.cpumask = cpumask_of(0);
118
119 clockevents_register_device(&clockevent_tcc);
120
121 return 0;
122}
123
124void __init tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq)
125{
126 u32 reg;
127
128 timer_base = base;
129 tcc8k_timer_irq.irq = irq;
130
131 /* Enable clocks */
132 clk_enable(clock);
133
134 /* Initialize 32-bit timer */
135 reg = __raw_readl(timer_base + TC32EN_OFFS);
136 reg &= ~TC32EN_ENABLE; /* Disable timer */
137 __raw_writel(reg, timer_base + TC32EN_OFFS);
138 /* Free running timer, counting from 0 to 0xffffffff */
139 __raw_writel(0, timer_base + TC32EN_OFFS);
140 __raw_writel(0, timer_base + TC32LDV_OFFS);
141 reg = __raw_readl(timer_base + TC32IRQ_OFFS);
142 reg |= TC32IRQ_IRQEN0; /* irq at match with CMP0 */
143 __raw_writel(reg, timer_base + TC32IRQ_OFFS);
144
145 __raw_writel(TC32EN_ENABLE, timer_base + TC32EN_OFFS);
146
147 tcc_clockevent_init(clock);
148 setup_irq(irq, &tcc8k_timer_irq);
149}
diff --git a/arch/arm/mach-versatile/include/mach/vmalloc.h b/arch/arm/mach-versatile/include/mach/vmalloc.h
index 427e3612db5d..ebd8a2543d3b 100644
--- a/arch/arm/mach-versatile/include/mach/vmalloc.h
+++ b/arch/arm/mach-versatile/include/mach/vmalloc.h
@@ -18,4 +18,4 @@
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#define VMALLOC_END (PAGE_OFFSET + 0x18000000) 21#define VMALLOC_END 0xd8000000
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 4f5b39687df5..b0a98305055c 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -144,3 +144,25 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
144{ 144{
145 return !(pfn + (size >> PAGE_SHIFT) > 0x00100000); 145 return !(pfn + (size >> PAGE_SHIFT) > 0x00100000);
146} 146}
147
148#ifdef CONFIG_STRICT_DEVMEM
149
150#include <linux/ioport.h>
151
152/*
153 * devmem_is_allowed() checks to see if /dev/mem access to a certain
154 * address is valid. The argument is a physical page number.
155 * We mimic x86 here by disallowing access to system RAM as well as
156 * device-exclusive MMIO regions. This effectively disable read()/write()
157 * on /dev/mem.
158 */
159int devmem_is_allowed(unsigned long pfn)
160{
161 if (iomem_is_exclusive(pfn << PAGE_SHIFT))
162 return 0;
163 if (!page_is_ram(pfn))
164 return 1;
165 return 0;
166}
167
168#endif
diff --git a/arch/arm/plat-tcc/Kconfig b/arch/arm/plat-tcc/Kconfig
new file mode 100644
index 000000000000..1bf499570f42
--- /dev/null
+++ b/arch/arm/plat-tcc/Kconfig
@@ -0,0 +1,20 @@
1if ARCH_TCC_926
2
3menu "Telechips ARM926-based CPUs"
4
5choice
6 prompt "Telechips CPU type:"
7 default ARCH_TCC8K
8
9config ARCH_TCC8K
10 bool TCC8000
11 select USB_ARCH_HAS_OHCI
12 help
13 Support for Telechips TCC8000 systems
14
15endchoice
16
17source "arch/arm/mach-tcc8k/Kconfig"
18
19endmenu
20endif
diff --git a/arch/arm/plat-tcc/Makefile b/arch/arm/plat-tcc/Makefile
new file mode 100644
index 000000000000..eceabc869b8f
--- /dev/null
+++ b/arch/arm/plat-tcc/Makefile
@@ -0,0 +1,3 @@
1# "Telechips Platform Common Modules"
2
3obj-y := clock.o system.o
diff --git a/arch/arm/plat-tcc/clock.c b/arch/arm/plat-tcc/clock.c
new file mode 100644
index 000000000000..f3ced10d5271
--- /dev/null
+++ b/arch/arm/plat-tcc/clock.c
@@ -0,0 +1,179 @@
1/*
2 * Clock framework for Telechips SoCs
3 * Based on arch/arm/plat-mxc/clock.c
4 *
5 * Copyright (C) 2004 - 2005 Nokia corporation
6 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
7 * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
8 * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
9 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
10 * Copyright 2010 Hans J. Koch, hjk@linutronix.de
11 *
12 * Licensed under the terms of the GPL v2.
13 */
14
15#include <linux/clk.h>
16#include <linux/err.h>
17#include <linux/errno.h>
18#include <linux/module.h>
19#include <linux/mutex.h>
20#include <linux/string.h>
21
22#include <mach/clock.h>
23#include <mach/hardware.h>
24
25static DEFINE_MUTEX(clocks_mutex);
26
27/*-------------------------------------------------------------------------
28 * Standard clock functions defined in include/linux/clk.h
29 *-------------------------------------------------------------------------*/
30
31static void __clk_disable(struct clk *clk)
32{
33 BUG_ON(clk->refcount == 0);
34
35 if (!(--clk->refcount) && clk->disable) {
36 /* Unconditionally disable the clock in hardware */
37 clk->disable(clk);
38 /* recursively disable parents */
39 if (clk->parent)
40 __clk_disable(clk->parent);
41 }
42}
43
44static int __clk_enable(struct clk *clk)
45{
46 int ret = 0;
47
48 if (clk->refcount++ == 0 && clk->enable) {
49 if (clk->parent)
50 ret = __clk_enable(clk->parent);
51 if (ret)
52 return ret;
53 else
54 return clk->enable(clk);
55 }
56
57 return 0;
58}
59
60/* This function increments the reference count on the clock and enables the
61 * clock if not already enabled. The parent clock tree is recursively enabled
62 */
63int clk_enable(struct clk *clk)
64{
65 int ret = 0;
66
67 if (!clk)
68 return -EINVAL;
69
70 mutex_lock(&clocks_mutex);
71 ret = __clk_enable(clk);
72 mutex_unlock(&clocks_mutex);
73
74 return ret;
75}
76EXPORT_SYMBOL_GPL(clk_enable);
77
78/* This function decrements the reference count on the clock and disables
79 * the clock when reference count is 0. The parent clock tree is
80 * recursively disabled
81 */
82void clk_disable(struct clk *clk)
83{
84 if (!clk)
85 return;
86
87 mutex_lock(&clocks_mutex);
88 __clk_disable(clk);
89 mutex_unlock(&clocks_mutex);
90}
91EXPORT_SYMBOL_GPL(clk_disable);
92
93/* Retrieve the *current* clock rate. If the clock itself
94 * does not provide a special calculation routine, ask
95 * its parent and so on, until one is able to return
96 * a valid clock rate
97 */
98unsigned long clk_get_rate(struct clk *clk)
99{
100 if (!clk)
101 return 0UL;
102
103 if (clk->get_rate)
104 return clk->get_rate(clk);
105
106 return clk_get_rate(clk->parent);
107}
108EXPORT_SYMBOL_GPL(clk_get_rate);
109
110/* Round the requested clock rate to the nearest supported
111 * rate that is less than or equal to the requested rate.
112 * This is dependent on the clock's current parent.
113 */
114long clk_round_rate(struct clk *clk, unsigned long rate)
115{
116 if (!clk)
117 return 0;
118 if (!clk->round_rate)
119 return 0;
120
121 return clk->round_rate(clk, rate);
122}
123EXPORT_SYMBOL_GPL(clk_round_rate);
124
125/* Set the clock to the requested clock rate. The rate must
126 * match a supported rate exactly based on what clk_round_rate returns
127 */
128int clk_set_rate(struct clk *clk, unsigned long rate)
129{
130 int ret = -EINVAL;
131
132 if (!clk)
133 return ret;
134 if (!clk->set_rate || !rate)
135 return ret;
136
137 mutex_lock(&clocks_mutex);
138 ret = clk->set_rate(clk, rate);
139 mutex_unlock(&clocks_mutex);
140
141 return ret;
142}
143EXPORT_SYMBOL_GPL(clk_set_rate);
144
145/* Set the clock's parent to another clock source */
146int clk_set_parent(struct clk *clk, struct clk *parent)
147{
148 struct clk *old;
149 int ret = -EINVAL;
150
151 if (!clk)
152 return ret;
153 if (!clk->set_parent || !parent)
154 return ret;
155
156 mutex_lock(&clocks_mutex);
157 old = clk->parent;
158 if (clk->refcount)
159 __clk_enable(parent);
160 ret = clk->set_parent(clk, parent);
161 if (ret)
162 old = parent;
163 if (clk->refcount)
164 __clk_disable(old);
165 mutex_unlock(&clocks_mutex);
166
167 return ret;
168}
169EXPORT_SYMBOL_GPL(clk_set_parent);
170
171/* Retrieve the clock's parent clock source */
172struct clk *clk_get_parent(struct clk *clk)
173{
174 if (!clk)
175 return NULL;
176
177 return clk->parent;
178}
179EXPORT_SYMBOL_GPL(clk_get_parent);
diff --git a/arch/arm/plat-tcc/include/mach/clkdev.h b/arch/arm/plat-tcc/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/clkdev.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do { } while (0)
6
7#endif
diff --git a/arch/arm/plat-tcc/include/mach/clock.h b/arch/arm/plat-tcc/include/mach/clock.h
new file mode 100644
index 000000000000..a12f58ad71a8
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/clock.h
@@ -0,0 +1,48 @@
1/*
2 * Low level clock header file for Telechips TCC architecture
3 * (C) 2010 Hans J. Koch <hjk@linutronix.de>
4 *
5 * Licensed under the GPL v2.
6 */
7
8#ifndef __ASM_ARCH_TCC_CLOCK_H__
9#define __ASM_ARCH_TCC_CLOCK_H__
10
11#ifndef __ASSEMBLY__
12
13struct clk {
14 struct clk *parent;
15 /* id number of a root clock, 0 for normal clocks */
16 int root_id;
17 /* Reference count of clock enable/disable */
18 int refcount;
19 /* Address of associated BCLKCTRx register. Must be set. */
20 void __iomem *bclkctr;
21 /* Bit position for BCLKCTRx. Must be set. */
22 int bclk_shift;
23 /* Address of ACLKxxx register, if any. */
24 void __iomem *aclkreg;
25 /* get the current clock rate (always a fresh value) */
26 unsigned long (*get_rate) (struct clk *);
27 /* Function ptr to set the clock to a new rate. The rate must match a
28 supported rate returned from round_rate. Leave blank if clock is not
29 programmable */
30 int (*set_rate) (struct clk *, unsigned long);
31 /* Function ptr to round the requested clock rate to the nearest
32 supported rate that is less than or equal to the requested rate. */
33 unsigned long (*round_rate) (struct clk *, unsigned long);
34 /* Function ptr to enable the clock. Leave blank if clock can not
35 be gated. */
36 int (*enable) (struct clk *);
37 /* Function ptr to disable the clock. Leave blank if clock can not
38 be gated. */
39 void (*disable) (struct clk *);
40 /* Function ptr to set the parent clock of the clock. */
41 int (*set_parent) (struct clk *, struct clk *);
42};
43
44int clk_register(struct clk *clk);
45void clk_unregister(struct clk *clk);
46
47#endif /* __ASSEMBLY__ */
48#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-tcc/include/mach/debug-macro.S b/arch/arm/plat-tcc/include/mach/debug-macro.S
new file mode 100644
index 000000000000..97537845df64
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/debug-macro.S
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 1994-1999 Russell King
3 * Copyright (C) 2008-2009 Telechips
4 * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12 .macro addruart,rx,tmp
13 mrc p15, 0, \rx, c1, c0
14 tst \rx, #1 @ MMU enabled?
15 moveq \rx, #0x90000000 @ physical base address
16 movne \rx, #0xF1000000 @ virtual base
17 orr \rx, \rx, #0x00007000 @ UART0
18 .endm
19
20 .macro senduart,rd,rx
21 strb \rd, [\rx, #0x44]
22 .endm
23
24 .macro waituart,rd,rx
25 .endm
26
27 .macro busyuart,rd,rx
281001:
29 ldr \rd, [\rx, #0x14]
30 tst \rd, #0x20
31
32 beq 1001b
33 .endm
diff --git a/arch/arm/plat-tcc/include/mach/entry-macro.S b/arch/arm/plat-tcc/include/mach/entry-macro.S
new file mode 100644
index 000000000000..748f401e4b6d
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/entry-macro.S
@@ -0,0 +1,68 @@
1/*
2 * include/asm-arm/arch-tcc83x/entry-macro.S
3 *
4 * Author : <linux@telechips.com>
5 * Created: June 10, 2008
6 * Description: Low-level IRQ helper macros for Telechips-based platforms
7 *
8 * Copyright (C) 2008-2009 Telechips
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 */
14
15#include <mach/hardware.h>
16#include <mach/irqs.h>
17
18 .macro disable_fiq
19 .endm
20
21 .macro get_irqnr_preamble, base, tmp
22 .endm
23
24 .macro arch_ret_to_user, tmp1, tmp2
25 .endm
26
27 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
28
29 ldr \base, =0xF2003000 @ base address of PIC registers
30
31 @@ read MREQ register of PIC0
32
33 mov \irqnr, #0
34 ldr \irqstat, [\base, #0x00000014 ] @ lower 32 interrupts
35 cmp \irqstat, #0
36 bne 1001f
37
38 @@ read MREQ register of PIC1
39
40 ldr \irqstat, [\base, #0x00000094] @ upper 32 interrupts
41 cmp \irqstat, #0
42 beq 1002f
43 mov \irqnr, #0x20
44
451001:
46 movs \tmp, \irqstat, lsl #16
47 movne \irqstat, \tmp
48 addeq \irqnr, \irqnr, #16
49
50 movs \tmp, \irqstat, lsl #8
51 movne \irqstat, \tmp
52 addeq \irqnr, \irqnr, #8
53
54 movs \tmp, \irqstat, lsl #4
55 movne \irqstat, \tmp
56 addeq \irqnr, \irqnr, #4
57
58 movs \tmp, \irqstat, lsl #2
59 movne \irqstat, \tmp
60 addeq \irqnr, \irqnr, #2
61
62 movs \tmp, \irqstat, lsl #1
63 addeq \irqnr, \irqnr, #1
64 orrs \base, \base, #1
651002:
66 @@ exit here, Z flag unset if IRQ
67
68 .endm
diff --git a/arch/arm/plat-tcc/include/mach/hardware.h b/arch/arm/plat-tcc/include/mach/hardware.h
new file mode 100644
index 000000000000..e70d126ccaf3
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/hardware.h
@@ -0,0 +1,43 @@
1/*
2 * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
3 * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
4 * and Dirk Behme <dirk.behme@de.bosch.com>
5 * Rewritten by: <linux@telechips.com>
6 * Description: Hardware definitions for TCC8300 processors and boards
7 *
8 * Copyright (C) 2001 RidgeRun, Inc.
9 * Copyright (C) 2008-2009 Telechips
10 *
11 * Modifications for mainline (C) 2009 Hans J. Koch <hjk@linutronix.de>
12 *
13 * Licensed under the terms of the GNU Pulic License version 2.
14 */
15
16#ifndef __ASM_ARCH_TCC_HARDWARE_H
17#define __ASM_ARCH_TCC_HARDWARE_H
18
19#include <asm/sizes.h>
20#ifndef __ASSEMBLER__
21#include <asm/types.h>
22#endif
23#include <mach/io.h>
24
25/*
26 * ----------------------------------------------------------------------------
27 * Clocks
28 * ----------------------------------------------------------------------------
29 */
30#define CLKGEN_REG_BASE 0xfffece00
31#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0)
32#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4)
33#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8)
34#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC)
35#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10)
36#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14)
37#define ARM_SYSST (CLKGEN_REG_BASE + 0x18)
38#define ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
39
40/* DPLL control registers */
41#define DPLL_CTL 0xfffecf00
42
43#endif /* __ASM_ARCH_TCC_HARDWARE_H */
diff --git a/arch/arm/plat-tcc/include/mach/io.h b/arch/arm/plat-tcc/include/mach/io.h
new file mode 100644
index 000000000000..3e911d3ea0f1
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/io.h
@@ -0,0 +1,23 @@
1/*
2 * IO definitions for TCC8000 processors and boards
3 *
4 * Copyright (C) 1997-1999 Russell King
5 * Copyright (C) 2008-2009 Telechips
6 * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
7 *
8 * Licensed under the terms of the GNU Public License version 2.
9 */
10
11#ifndef __ASM_ARM_ARCH_IO_H
12#define __ASM_ARM_ARCH_IO_H
13
14#define IO_SPACE_LIMIT 0xffffffff
15
16/*
17 * We don't actually have real ISA nor PCI buses, but there is so many
18 * drivers out there that might just work if we fake them...
19 */
20#define __io(a) __typesafe_io(a)
21#define __mem_pci(a) (a)
22
23#endif
diff --git a/arch/arm/plat-tcc/include/mach/irqs.h b/arch/arm/plat-tcc/include/mach/irqs.h
new file mode 100644
index 000000000000..da863894d498
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/irqs.h
@@ -0,0 +1,83 @@
1/*
2 * IRQ definitions for TCC8xxx
3 *
4 * Copyright (C) 2008-2009 Telechips
5 * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
6 *
7 * Licensed under the terms of the GPL v2.
8 *
9 */
10
11#ifndef __ASM_ARCH_TCC_IRQS_H
12#define __ASM_ARCH_TCC_IRQS_H
13
14#define NR_IRQS 64
15
16/* PIC0 interrupts */
17#define INT_ADMA1 0
18#define INT_BDMA 1
19#define INT_ADMA0 2
20#define INT_GDMA1 3
21#define INT_I2S0RX 4
22#define INT_I2S0TX 5
23#define INT_TC 6
24#define INT_UART0 7
25#define INT_USBD 8
26#define INT_SPI0TX 9
27#define INT_UDMA 10
28#define INT_LIRQ 11
29#define INT_GDMA2 12
30#define INT_GDMA0 13
31#define INT_TC32 14
32#define INT_LCD 15
33#define INT_ADC 16
34#define INT_I2C 17
35#define INT_RTCP 18
36#define INT_RTCA 19
37#define INT_NFC 20
38#define INT_SD0 21
39#define INT_GSB0 22
40#define INT_PK 23
41#define INT_USBH0 24
42#define INT_USBH1 25
43#define INT_G2D 26
44#define INT_ECC 27
45#define INT_SPI0RX 28
46#define INT_UART1 29
47#define INT_MSCL 30
48#define INT_GSB1 31
49/* PIC1 interrupts */
50#define INT_E0 32
51#define INT_E1 33
52#define INT_E2 34
53#define INT_E3 35
54#define INT_E4 36
55#define INT_E5 37
56#define INT_E6 38
57#define INT_E7 39
58#define INT_UART2 40
59#define INT_UART3 41
60#define INT_SPI1TX 42
61#define INT_SPI1RX 43
62#define INT_GSB2 44
63#define INT_SPDIF 45
64#define INT_CDIF 46
65#define INT_VBON 47
66#define INT_VBOFF 48
67#define INT_SD1 49
68#define INT_UART4 50
69#define INT_GDMA3 51
70#define INT_I2S1RX 52
71#define INT_I2S1TX 53
72#define INT_CAN0 54
73#define INT_CAN1 55
74#define INT_GSB3 56
75#define INT_KRST 57
76#define INT_UNUSED 58
77#define INT_SD0D3 59
78#define INT_SD1D3 60
79#define INT_GPS0 61
80#define INT_GPS1 62
81#define INT_GPS2 63
82
83#endif /* ASM_ARCH_TCC_IRQS_H */
diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h
new file mode 100644
index 000000000000..cd91ba8a670b
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/memory.h
@@ -0,0 +1,18 @@
1/*
2 * Copyright (C) 1999 ARM Limited
3 * Copyright (C) 2000 RidgeRun, Inc.
4 * Copyright (C) 2008-2009 Telechips
5 * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
6 *
7 * Licensed under the terms of the GPL v2.
8 */
9
10#ifndef __ASM_ARCH_MEMORY_H
11#define __ASM_ARCH_MEMORY_H
12
13/*
14 * Physical DRAM offset.
15 */
16#define PHYS_OFFSET UL(0x20000000)
17
18#endif
diff --git a/arch/arm/plat-tcc/include/mach/system.h b/arch/arm/plat-tcc/include/mach/system.h
new file mode 100644
index 000000000000..909e6035d843
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/system.h
@@ -0,0 +1,31 @@
1/*
2 * Author: <linux@telechips.com>
3 * Created: June 10, 2008
4 * Description: LINUX SYSTEM FUNCTIONS for TCC83x
5 *
6 * Copyright (C) 2008-2009 Telechips
7 *
8 * Licensed under the terms of the GPL v2.
9 *
10 */
11
12#ifndef __ASM_ARCH_SYSTEM_H
13#define __ASM_ARCH_SYSTEM_H
14#include <linux/clk.h>
15
16#include <asm/mach-types.h>
17#include <mach/hardware.h>
18
19extern void plat_tcc_reboot(void);
20
21static inline void arch_idle(void)
22{
23 cpu_do_idle();
24}
25
26static inline void arch_reset(char mode, const char *cmd)
27{
28 plat_tcc_reboot();
29}
30
31#endif
diff --git a/arch/arm/plat-tcc/include/mach/tcc8k-regs.h b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h
new file mode 100644
index 000000000000..1d9428295332
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h
@@ -0,0 +1,807 @@
1/*
2 * Telechips TCC8000 register definitions
3 *
4 * (C) 2009 Hans J. Koch <hjk@linutronix.de>
5 *
6 * Licensed under the terms of the GPLv2.
7 */
8
9#ifndef TCC8K_REGS_H
10#define TCC8K_REGS_H
11
12#include <linux/types.h>
13
14#define EXT_SDRAM_BASE 0x20000000
15#define INT_SRAM_BASE 0x30000000
16#define INT_SRAM_SIZE SZ_32K
17#define CS0_BASE 0x40000000
18#define CS1_BASE 0x50000000
19#define CS1_SIZE SZ_64K
20#define CS2_BASE 0x60000000
21#define CS3_BASE 0x70000000
22#define AHB_PERI_BASE 0x80000000
23#define AHB_PERI_SIZE SZ_64K
24#define APB0_PERI_BASE 0x90000000
25#define APB0_PERI_SIZE SZ_128K
26#define APB1_PERI_BASE 0x98000000
27#define APB1_PERI_SIZE SZ_128K
28#define DATA_TCM_BASE 0xa0000000
29#define DATA_TCM_SIZE SZ_8K
30#define EXT_MEM_CTRL_BASE 0xf0000000
31#define EXT_MEM_CTRL_SIZE SZ_4K
32
33#define CS1_BASE_VIRT (void __iomem *)0xf7000000
34#define AHB_PERI_BASE_VIRT (void __iomem *)0xf4000000
35#define APB0_PERI_BASE_VIRT (void __iomem *)0xf1000000
36#define APB1_PERI_BASE_VIRT (void __iomem *)0xf2000000
37#define EXT_MEM_CTRL_BASE_VIRT (void __iomem *)0xf3000000
38#define INT_SRAM_BASE_VIRT (void __iomem *)0xf5000000
39#define DATA_TCM_BASE_VIRT (void __iomem *)0xf6000000
40
41#define __REG(x) (*((volatile u32 *)(x)))
42
43/* USB Device Controller Registers */
44#define UDC_BASE (AHB_PERI_BASE_VIRT + 0x8000)
45#define UDC_BASE_PHYS (AHB_PERI_BASE + 0x8000)
46
47#define UDC_IR_OFFS 0x00
48#define UDC_EIR_OFFS 0x04
49#define UDC_EIER_OFFS 0x08
50#define UDC_FAR_OFFS 0x0c
51#define UDC_FNR_OFFS 0x10
52#define UDC_EDR_OFFS 0x14
53#define UDC_RT_OFFS 0x18
54#define UDC_SSR_OFFS 0x1c
55#define UDC_SCR_OFFS 0x20
56#define UDC_EP0SR_OFFS 0x24
57#define UDC_EP0CR_OFFS 0x28
58
59#define UDC_ESR_OFFS 0x2c
60#define UDC_ECR_OFFS 0x30
61#define UDC_BRCR_OFFS 0x34
62#define UDC_BWCR_OFFS 0x38
63#define UDC_MPR_OFFS 0x3c
64#define UDC_DCR_OFFS 0x40
65#define UDC_DTCR_OFFS 0x44
66#define UDC_DFCR_OFFS 0x48
67#define UDC_DTTCR1_OFFS 0x4c
68#define UDC_DTTCR2_OFFS 0x50
69#define UDC_ESR2_OFFS 0x54
70
71#define UDC_SCR2_OFFS 0x58
72#define UDC_EP0BUF_OFFS 0x60
73#define UDC_EP1BUF_OFFS 0x64
74#define UDC_EP2BUF_OFFS 0x68
75#define UDC_EP3BUF_OFFS 0x6c
76#define UDC_PLICR_OFFS 0xa0
77#define UDC_PCR_OFFS 0xa4
78
79#define UDC_UPCR0_OFFS 0xc8
80#define UDC_UPCR1_OFFS 0xcc
81#define UDC_UPCR2_OFFS 0xd0
82#define UDC_UPCR3_OFFS 0xd4
83
84/* Bits in UDC_EIR */
85#define UDC_EIR_EP0I (1 << 0)
86#define UDC_EIR_EP1I (1 << 1)
87#define UDC_EIR_EP2I (1 << 2)
88#define UDC_EIR_EP3I (1 << 3)
89#define UDC_EIR_EPI_MASK 0x0f
90
91/* Bits in UDC_EIER */
92#define UDC_EIER_EP0IE (1 << 0)
93#define UDC_EIER_EP1IE (1 << 1)
94#define UDC_EIER_EP2IE (1 << 2)
95#define UDC_EIER_EP3IE (1 << 3)
96
97/* Bits in UDC_FNR */
98#define UDC_FNR_FN_MASK 0x7ff
99#define UDC_FNR_SM (1 << 13)
100#define UDC_FNR_FTL (1 << 14)
101
102/* Bits in UDC_SSR */
103#define UDC_SSR_HFRES (1 << 0)
104#define UDC_SSR_HFSUSP (1 << 1)
105#define UDC_SSR_HFRM (1 << 2)
106#define UDC_SSR_SDE (1 << 3)
107#define UDC_SSR_HSP (1 << 4)
108#define UDC_SSR_DM (1 << 5)
109#define UDC_SSR_DP (1 << 6)
110#define UDC_SSR_TBM (1 << 7)
111#define UDC_SSR_VBON (1 << 8)
112#define UDC_SSR_VBOFF (1 << 9)
113#define UDC_SSR_EOERR (1 << 10)
114#define UDC_SSR_DCERR (1 << 11)
115#define UDC_SSR_TCERR (1 << 12)
116#define UDC_SSR_BSERR (1 << 13)
117#define UDC_SSR_TMERR (1 << 14)
118#define UDC_SSR_BAERR (1 << 15)
119
120/* Bits in UDC_SCR */
121#define UDC_SCR_HRESE (1 << 0)
122#define UDC_SCR_HSSPE (1 << 1)
123#define UDC_SCR_RRDE (1 << 5)
124#define UDC_SCR_SPDEN (1 << 6)
125#define UDC_SCR_DIEN (1 << 12)
126
127/* Bits in UDC_EP0SR */
128#define UDC_EP0SR_RSR (1 << 0)
129#define UDC_EP0SR_TST (1 << 1)
130#define UDC_EP0SR_SHT (1 << 4)
131#define UDC_EP0SR_LWO (1 << 6)
132
133/* Bits in UDC_EP0CR */
134#define UDC_EP0CR_ESS (1 << 1)
135
136/* Bits in UDC_ESR */
137#define UDC_ESR_RPS (1 << 0)
138#define UDC_ESR_TPS (1 << 1)
139#define UDC_ESR_LWO (1 << 4)
140#define UDC_ESR_FFS (1 << 6)
141
142/* Bits in UDC_ECR */
143#define UDC_ECR_ESS (1 << 1)
144#define UDC_ECR_CDP (1 << 2)
145
146#define UDC_ECR_FLUSH (1 << 6)
147#define UDC_ECR_DUEN (1 << 7)
148
149/* Bits in UDC_UPCR0 */
150#define UDC_UPCR0_VBD (1 << 1)
151#define UDC_UPCR0_VBDS (1 << 6)
152#define UDC_UPCR0_RCD_12 (0x0 << 9)
153#define UDC_UPCR0_RCD_24 (0x1 << 9)
154#define UDC_UPCR0_RCD_48 (0x2 << 9)
155#define UDC_UPCR0_RCS_EXT (0x1 << 11)
156#define UDC_UPCR0_RCS_XTAL (0x0 << 11)
157
158/* Bits in UDC_UPCR1 */
159#define UDC_UPCR1_CDT(x) ((x) << 0)
160#define UDC_UPCR1_OTGT(x) ((x) << 3)
161#define UDC_UPCR1_SQRXT(x) ((x) << 8)
162#define UDC_UPCR1_TXFSLST(x) ((x) << 12)
163
164/* Bits in UDC_UPCR2 */
165#define UDC_UPCR2_TP (1 << 0)
166#define UDC_UPCR2_TXRT(x) ((x) << 2)
167#define UDC_UPCR2_TXVRT(x) ((x) << 5)
168#define UDC_UPCR2_OPMODE(x) ((x) << 9)
169#define UDC_UPCR2_XCVRSEL(x) ((x) << 12)
170#define UDC_UPCR2_TM (1 << 14)
171
172/* USB Host Controller registers */
173#define USBH0_BASE (AHB_PERI_BASE_VIRT + 0xb000)
174#define USBH1_BASE (AHB_PERI_BASE_VIRT + 0xb800)
175
176#define OHCI_INT_ENABLE_OFFS 0x10
177
178#define RH_DESCRIPTOR_A_OFFS 0x48
179#define RH_DESCRIPTOR_B_OFFS 0x4c
180
181#define USBHTCFG0_OFFS 0x100
182#define USBHHCFG0_OFFS 0x104
183#define USBHHCFG1_OFFS 0x104
184
185/* DMA controller registers */
186#define DMAC0_BASE (AHB_PERI_BASE + 0x4000)
187#define DMAC1_BASE (AHB_PERI_BASE + 0xa000)
188#define DMAC2_BASE (AHB_PERI_BASE + 0x4800)
189#define DMAC3_BASE (AHB_PERI_BASE + 0xa800)
190
191#define DMAC_CH_OFFSET(ch) (ch * 0x30)
192
193#define ST_SADR_OFFS 0x00
194#define SPARAM_OFFS 0x04
195#define C_SADR_OFFS 0x0c
196#define ST_DADR_OFFS 0x10
197#define DPARAM_OFFS 0x14
198#define C_DADR_OFFS 0x1c
199#define HCOUNT_OFFS 0x20
200#define CHCTRL_OFFS 0x24
201#define RPTCTRL_OFFS 0x28
202#define EXTREQ_A_OFFS 0x2c
203
204/* Bits in CHCTRL register */
205#define CHCTRL_EN (1 << 0)
206
207#define CHCTRL_IEN (1 << 2)
208#define CHCTRL_FLAG (1 << 3)
209#define CHCTRL_WSIZE8 (0 << 4)
210#define CHCTRL_WSIZE16 (1 << 4)
211#define CHCTRL_WSIZE32 (2 << 4)
212
213#define CHCTRL_BSIZE1 (0 << 6)
214#define CHCTRL_BSIZE2 (1 << 6)
215#define CHCTRL_BSIZE4 (2 << 6)
216#define CHCTRL_BSIZE8 (3 << 6)
217
218#define CHCTRL_TYPE_SINGLE_E (0 << 8)
219#define CHCTRL_TYPE_HW (1 << 8)
220#define CHCTRL_TYPE_SW (2 << 8)
221#define CHCTRL_TYPE_SINGLE_L (3 << 8)
222
223#define CHCTRL_BST (1 << 10)
224
225/* Use DMA controller 0, channel 2 for USB */
226#define USB_DMA_BASE (DMAC0_BASE + DMAC_CH_OFFSET(2))
227
228/* NAND flash controller registers */
229#define NFC_BASE (AHB_PERI_BASE_VIRT + 0xd000)
230#define NFC_BASE_PHYS (AHB_PERI_BASE + 0xd000)
231
232#define NFC_CMD_OFFS 0x00
233#define NFC_LADDR_OFFS 0x04
234#define NFC_BADDR_OFFS 0x08
235#define NFC_SADDR_OFFS 0x0c
236#define NFC_WDATA_OFFS 0x10
237#define NFC_LDATA_OFFS 0x20
238#define NFC_SDATA_OFFS 0x40
239#define NFC_CTRL_OFFS 0x50
240#define NFC_PSTART_OFFS 0x54
241#define NFC_RSTART_OFFS 0x58
242#define NFC_DSIZE_OFFS 0x5c
243#define NFC_IREQ_OFFS 0x60
244#define NFC_RST_OFFS 0x64
245#define NFC_CTRL1_OFFS 0x68
246#define NFC_MDATA_OFFS 0x70
247
248#define NFC_WDATA_PHYS_ADDR (NFC_BASE_PHYS + NFC_WDATA_OFFS)
249
250/* Bits in NFC_CTRL */
251#define NFC_CTRL_BHLD_MASK (0xf << 0)
252#define NFC_CTRL_BPW_MASK (0xf << 4)
253#define NFC_CTRL_BSTP_MASK (0xf << 8)
254#define NFC_CTRL_CADDR_MASK (0x7 << 12)
255#define NFC_CTRL_CADDR_1 (0x0 << 12)
256#define NFC_CTRL_CADDR_2 (0x1 << 12)
257#define NFC_CTRL_CADDR_3 (0x2 << 12)
258#define NFC_CTRL_CADDR_4 (0x3 << 12)
259#define NFC_CTRL_CADDR_5 (0x4 << 12)
260#define NFC_CTRL_MSK (1 << 15)
261#define NFC_CTRL_PSIZE256 (0 << 16)
262#define NFC_CTRL_PSIZE512 (1 << 16)
263#define NFC_CTRL_PSIZE1024 (2 << 16)
264#define NFC_CTRL_PSIZE2048 (3 << 16)
265#define NFC_CTRL_PSIZE4096 (4 << 16)
266#define NFC_CTRL_PSIZE_MASK (7 << 16)
267#define NFC_CTRL_BSIZE1 (0 << 19)
268#define NFC_CTRL_BSIZE2 (1 << 19)
269#define NFC_CTRL_BSIZE4 (2 << 19)
270#define NFC_CTRL_BSIZE8 (3 << 19)
271#define NFC_CTRL_BSIZE_MASK (3 << 19)
272#define NFC_CTRL_RDY (1 << 21)
273#define NFC_CTRL_CS0SEL (1 << 22)
274#define NFC_CTRL_CS1SEL (1 << 23)
275#define NFC_CTRL_CS2SEL (1 << 24)
276#define NFC_CTRL_CS3SEL (1 << 25)
277#define NFC_CTRL_CSMASK (0xf << 22)
278#define NFC_CTRL_BW (1 << 26)
279#define NFC_CTRL_FS (1 << 27)
280#define NFC_CTRL_DEN (1 << 28)
281#define NFC_CTRL_READ_IEN (1 << 29)
282#define NFC_CTRL_PROG_IEN (1 << 30)
283#define NFC_CTRL_RDY_IEN (1 << 31)
284
285/* Bits in NFC_IREQ */
286#define NFC_IREQ_IRQ0 (1 << 0)
287#define NFC_IREQ_IRQ1 (1 << 1)
288#define NFC_IREQ_IRQ2 (1 << 2)
289
290#define NFC_IREQ_FLAG0 (1 << 4)
291#define NFC_IREQ_FLAG1 (1 << 5)
292#define NFC_IREQ_FLAG2 (1 << 6)
293
294/* MMC controller registers */
295#define MMC0_BASE (AHB_PERI_BASE_VIRT + 0xe000)
296#define MMC1_BASE (AHB_PERI_BASE_VIRT + 0xe800)
297
298/* UART base addresses */
299
300#define UART0_BASE (APB0_PERI_BASE_VIRT + 0x07000)
301#define UART0_BASE_PHYS (APB0_PERI_BASE + 0x07000)
302#define UART1_BASE (APB0_PERI_BASE_VIRT + 0x08000)
303#define UART1_BASE_PHYS (APB0_PERI_BASE + 0x08000)
304#define UART2_BASE (APB0_PERI_BASE_VIRT + 0x09000)
305#define UART2_BASE_PHYS (APB0_PERI_BASE + 0x09000)
306#define UART3_BASE (APB0_PERI_BASE_VIRT + 0x0a000)
307#define UART3_BASE_PHYS (APB0_PERI_BASE + 0x0a000)
308#define UART4_BASE (APB0_PERI_BASE_VIRT + 0x15000)
309#define UART4_BASE_PHYS (APB0_PERI_BASE + 0x15000)
310
311#define UART_BASE UART0_BASE
312#define UART_BASE_PHYS UART0_BASE_PHYS
313
314/* ECC controller */
315#define ECC_CTR_BASE (APB0_PERI_BASE_VIRT + 0xd000)
316
317#define ECC_CTRL_OFFS 0x00
318#define ECC_BASE_OFFS 0x04
319#define ECC_MASK_OFFS 0x08
320#define ECC_CLEAR_OFFS 0x0c
321#define ECC4_0_OFFS 0x10
322#define ECC4_1_OFFS 0x14
323
324#define ECC_EADDR0_OFFS 0x50
325
326#define ECC_ERRNUM_OFFS 0x90
327#define ECC_IREQ_OFFS 0x94
328
329/* Bits in ECC_CTRL */
330#define ECC_CTRL_ECC4_DIEN (1 << 28)
331#define ECC_CTRL_ECC8_DIEN (1 << 29)
332#define ECC_CTRL_ECC12_DIEN (1 << 30)
333#define ECC_CTRL_ECC_DISABLE 0x0
334#define ECC_CTRL_ECC_SLC_ENC 0x8
335#define ECC_CTRL_ECC_SLC_DEC 0x9
336#define ECC_CTRL_ECC4_ENC 0xa
337#define ECC_CTRL_ECC4_DEC 0xb
338#define ECC_CTRL_ECC8_ENC 0xc
339#define ECC_CTRL_ECC8_DEC 0xd
340#define ECC_CTRL_ECC12_ENC 0xe
341#define ECC_CTRL_ECC12_DEC 0xf
342
343/* Bits in ECC_IREQ */
344#define ECC_IREQ_E4DI (1 << 4)
345
346#define ECC_IREQ_E4DF (1 << 20)
347#define ECC_IREQ_E4EF (1 << 21)
348
349/* Interrupt controller */
350
351#define PIC0_BASE (APB1_PERI_BASE_VIRT + 0x3000)
352#define PIC0_BASE_PHYS (APB1_PERI_BASE + 0x3000)
353
354#define PIC0_IEN_OFFS 0x00
355#define PIC0_CREQ_OFFS 0x04
356#define PIC0_IREQ_OFFS 0x08
357#define PIC0_IRQSEL_OFFS 0x0c
358#define PIC0_SRC_OFFS 0x10
359#define PIC0_MREQ_OFFS 0x14
360#define PIC0_TSTREQ_OFFS 0x18
361#define PIC0_POL_OFFS 0x1c
362#define PIC0_IRQ_OFFS 0x20
363#define PIC0_FIQ_OFFS 0x24
364#define PIC0_MIRQ_OFFS 0x28
365#define PIC0_MFIQ_OFFS 0x2c
366#define PIC0_TMODE_OFFS 0x30
367#define PIC0_SYNC_OFFS 0x34
368#define PIC0_WKUP_OFFS 0x38
369#define PIC0_TMODEA_OFFS 0x3c
370#define PIC0_INTOEN_OFFS 0x40
371#define PIC0_MEN0_OFFS 0x44
372#define PIC0_MEN_OFFS 0x48
373
374#define PIC0_IEN __REG(PIC0_BASE + PIC0_IEN_OFFS)
375#define PIC0_IEN_PHYS __REG(PIC0_BASE_PHYS + PIC0_IEN_OFFS)
376#define PIC0_CREQ __REG(PIC0_BASE + PIC0_CREQ_OFFS)
377#define PIC0_CREQ_PHYS __REG(PIC0_BASE_PHYS + PIC0_CREQ_OFFS)
378#define PIC0_IREQ __REG(PIC0_BASE + PIC0_IREQ_OFFS)
379#define PIC0_IRQSEL __REG(PIC0_BASE + PIC0_IRQSEL_OFFS)
380#define PIC0_IRQSEL_PHYS __REG(PIC0_BASE_PHYS + PIC0_IRQSEL_OFFS)
381#define PIC0_SRC __REG(PIC0_BASE + PIC0_SRC_OFFS)
382#define PIC0_MREQ __REG(PIC0_BASE + PIC0_MREQ_OFFS)
383#define PIC0_TSTREQ __REG(PIC0_BASE + PIC0_TSTREQ_OFFS)
384#define PIC0_POL __REG(PIC0_BASE + PIC0_POL_OFFS)
385#define PIC0_IRQ __REG(PIC0_BASE + PIC0_IRQ_OFFS)
386#define PIC0_FIQ __REG(PIC0_BASE + PIC0_FIQ_OFFS)
387#define PIC0_MIRQ __REG(PIC0_BASE + PIC0_MIRQ_OFFS)
388#define PIC0_MFIQ __REG(PIC0_BASE + PIC0_MFIQ_OFFS)
389#define PIC0_TMODE __REG(PIC0_BASE + PIC0_TMODE_OFFS)
390#define PIC0_TMODE_PHYS __REG(PIC0_BASE_PHYS + PIC0_TMODE_OFFS)
391#define PIC0_SYNC __REG(PIC0_BASE + PIC0_SYNC_OFFS)
392#define PIC0_WKUP __REG(PIC0_BASE + PIC0_WKUP_OFFS)
393#define PIC0_TMODEA __REG(PIC0_BASE + PIC0_TMODEA_OFFS)
394#define PIC0_INTOEN __REG(PIC0_BASE + PIC0_INTOEN_OFFS)
395#define PIC0_MEN0 __REG(PIC0_BASE + PIC0_MEN0_OFFS)
396#define PIC0_MEN __REG(PIC0_BASE + PIC0_MEN_OFFS)
397
398#define PIC1_BASE (APB1_PERI_BASE_VIRT + 0x3080)
399
400#define PIC1_IEN_OFFS 0x00
401#define PIC1_CREQ_OFFS 0x04
402#define PIC1_IREQ_OFFS 0x08
403#define PIC1_IRQSEL_OFFS 0x0c
404#define PIC1_SRC_OFFS 0x10
405#define PIC1_MREQ_OFFS 0x14
406#define PIC1_TSTREQ_OFFS 0x18
407#define PIC1_POL_OFFS 0x1c
408#define PIC1_IRQ_OFFS 0x20
409#define PIC1_FIQ_OFFS 0x24
410#define PIC1_MIRQ_OFFS 0x28
411#define PIC1_MFIQ_OFFS 0x2c
412#define PIC1_TMODE_OFFS 0x30
413#define PIC1_SYNC_OFFS 0x34
414#define PIC1_WKUP_OFFS 0x38
415#define PIC1_TMODEA_OFFS 0x3c
416#define PIC1_INTOEN_OFFS 0x40
417#define PIC1_MEN1_OFFS 0x44
418#define PIC1_MEN_OFFS 0x48
419
420#define PIC1_IEN __REG(PIC1_BASE + PIC1_IEN_OFFS)
421#define PIC1_CREQ __REG(PIC1_BASE + PIC1_CREQ_OFFS)
422#define PIC1_IREQ __REG(PIC1_BASE + PIC1_IREQ_OFFS)
423#define PIC1_IRQSEL __REG(PIC1_BASE + PIC1_IRQSEL_OFFS)
424#define PIC1_SRC __REG(PIC1_BASE + PIC1_SRC_OFFS)
425#define PIC1_MREQ __REG(PIC1_BASE + PIC1_MREQ_OFFS)
426#define PIC1_TSTREQ __REG(PIC1_BASE + PIC1_TSTREQ_OFFS)
427#define PIC1_POL __REG(PIC1_BASE + PIC1_POL_OFFS)
428#define PIC1_IRQ __REG(PIC1_BASE + PIC1_IRQ_OFFS)
429#define PIC1_FIQ __REG(PIC1_BASE + PIC1_FIQ_OFFS)
430#define PIC1_MIRQ __REG(PIC1_BASE + PIC1_MIRQ_OFFS)
431#define PIC1_MFIQ __REG(PIC1_BASE + PIC1_MFIQ_OFFS)
432#define PIC1_TMODE __REG(PIC1_BASE + PIC1_TMODE_OFFS)
433#define PIC1_SYNC __REG(PIC1_BASE + PIC1_SYNC_OFFS)
434#define PIC1_WKUP __REG(PIC1_BASE + PIC1_WKUP_OFFS)
435#define PIC1_TMODEA __REG(PIC1_BASE + PIC1_TMODEA_OFFS)
436#define PIC1_INTOEN __REG(PIC1_BASE + PIC1_INTOEN_OFFS)
437#define PIC1_MEN1 __REG(PIC1_BASE + PIC1_MEN1_OFFS)
438#define PIC1_MEN __REG(PIC1_BASE + PIC1_MEN_OFFS)
439
440/* Timer registers */
441#define TIMER_BASE (APB1_PERI_BASE_VIRT + 0x4000)
442#define TIMER_BASE_PHYS (APB1_PERI_BASE + 0x4000)
443
444#define TWDCFG_OFFS 0x70
445
446#define TC32EN_OFFS 0x80
447#define TC32LDV_OFFS 0x84
448#define TC32CMP0_OFFS 0x88
449#define TC32CMP1_OFFS 0x8c
450#define TC32PCNT_OFFS 0x90
451#define TC32MCNT_OFFS 0x94
452#define TC32IRQ_OFFS 0x98
453
454/* Bits in TC32EN */
455#define TC32EN_PRESCALE_MASK 0x00ffffff
456#define TC32EN_ENABLE (1 << 24)
457#define TC32EN_LOADZERO (1 << 25)
458#define TC32EN_STOPMODE (1 << 26)
459#define TC32EN_LDM0 (1 << 28)
460#define TC32EN_LDM1 (1 << 29)
461
462/* Bits in TC32IRQ */
463#define TC32IRQ_MSTAT_MASK 0x0000001f
464#define TC32IRQ_RSTAT_MASK (0x1f << 8)
465#define TC32IRQ_IRQEN0 (1 << 16)
466#define TC32IRQ_IRQEN1 (1 << 17)
467#define TC32IRQ_IRQEN2 (1 << 18)
468#define TC32IRQ_IRQEN3 (1 << 19)
469#define TC32IRQ_IRQEN4 (1 << 20)
470#define TC32IRQ_RSYNC (1 << 30)
471#define TC32IRQ_IRQCLR (1 << 31)
472
473/* GPIO registers */
474#define GPIOPD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
475
476#define GPIOPD_DAT_OFFS 0x00
477#define GPIOPD_DOE_OFFS 0x04
478#define GPIOPD_FS0_OFFS 0x08
479#define GPIOPD_FS1_OFFS 0x0c
480#define GPIOPD_FS2_OFFS 0x10
481#define GPIOPD_RPU_OFFS 0x30
482#define GPIOPD_RPD_OFFS 0x34
483#define GPIOPD_DV0_OFFS 0x38
484#define GPIOPD_DV1_OFFS 0x3c
485
486#define GPIOPS_BASE (APB1_PERI_BASE_VIRT + 0x5000)
487
488#define GPIOPS_DAT_OFFS 0x40
489#define GPIOPS_DOE_OFFS 0x44
490#define GPIOPS_FS0_OFFS 0x48
491#define GPIOPS_FS1_OFFS 0x4c
492#define GPIOPS_FS2_OFFS 0x50
493#define GPIOPS_FS3_OFFS 0x54
494#define GPIOPS_RPU_OFFS 0x70
495#define GPIOPS_RPD_OFFS 0x74
496#define GPIOPS_DV0_OFFS 0x78
497#define GPIOPS_DV1_OFFS 0x7c
498
499#define GPIOPS_FS1_SDH0_BITS 0x000000ff
500#define GPIOPS_FS1_SDH1_BITS 0x0000ff00
501
502#define GPIOPU_BASE (APB1_PERI_BASE_VIRT + 0x5000)
503
504#define GPIOPU_DAT_OFFS 0x80
505#define GPIOPU_DOE_OFFS 0x84
506#define GPIOPU_FS0_OFFS 0x88
507#define GPIOPU_FS1_OFFS 0x8c
508#define GPIOPU_FS2_OFFS 0x90
509#define GPIOPU_RPU_OFFS 0xb0
510#define GPIOPU_RPD_OFFS 0xb4
511#define GPIOPU_DV0_OFFS 0xb8
512#define GPIOPU_DV1_OFFS 0xbc
513
514#define GPIOPU_FS0_TXD0 (1 << 0)
515#define GPIOPU_FS0_RXD0 (1 << 1)
516#define GPIOPU_FS0_CTS0 (1 << 2)
517#define GPIOPU_FS0_RTS0 (1 << 3)
518#define GPIOPU_FS0_TXD1 (1 << 4)
519#define GPIOPU_FS0_RXD1 (1 << 5)
520#define GPIOPU_FS0_CTS1 (1 << 6)
521#define GPIOPU_FS0_RTS1 (1 << 7)
522#define GPIOPU_FS0_TXD2 (1 << 8)
523#define GPIOPU_FS0_RXD2 (1 << 9)
524#define GPIOPU_FS0_CTS2 (1 << 10)
525#define GPIOPU_FS0_RTS2 (1 << 11)
526#define GPIOPU_FS0_TXD3 (1 << 12)
527#define GPIOPU_FS0_RXD3 (1 << 13)
528#define GPIOPU_FS0_CTS3 (1 << 14)
529#define GPIOPU_FS0_RTS3 (1 << 15)
530#define GPIOPU_FS0_TXD4 (1 << 16)
531#define GPIOPU_FS0_RXD4 (1 << 17)
532#define GPIOPU_FS0_CTS4 (1 << 18)
533#define GPIOPU_FS0_RTS4 (1 << 19)
534
535#define GPIOFC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
536
537#define GPIOFC_DAT_OFFS 0xc0
538#define GPIOFC_DOE_OFFS 0xc4
539#define GPIOFC_FS0_OFFS 0xc8
540#define GPIOFC_FS1_OFFS 0xcc
541#define GPIOFC_FS2_OFFS 0xd0
542#define GPIOFC_FS3_OFFS 0xd4
543#define GPIOFC_RPU_OFFS 0xf0
544#define GPIOFC_RPD_OFFS 0xf4
545#define GPIOFC_DV0_OFFS 0xf8
546#define GPIOFC_DV1_OFFS 0xfc
547
548#define GPIOFD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
549
550#define GPIOFD_DAT_OFFS 0x100
551#define GPIOFD_DOE_OFFS 0x104
552#define GPIOFD_FS0_OFFS 0x108
553#define GPIOFD_FS1_OFFS 0x10c
554#define GPIOFD_FS2_OFFS 0x110
555#define GPIOFD_RPU_OFFS 0x130
556#define GPIOFD_RPD_OFFS 0x134
557#define GPIOFD_DV0_OFFS 0x138
558#define GPIOFD_DV1_OFFS 0x13c
559
560#define GPIOLC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
561
562#define GPIOLC_DAT_OFFS 0x140
563#define GPIOLC_DOE_OFFS 0x144
564#define GPIOLC_FS0_OFFS 0x148
565#define GPIOLC_FS1_OFFS 0x14c
566#define GPIOLC_RPU_OFFS 0x170
567#define GPIOLC_RPD_OFFS 0x174
568#define GPIOLC_DV0_OFFS 0x178
569#define GPIOLC_DV1_OFFS 0x17c
570
571#define GPIOLD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
572
573#define GPIOLD_DAT_OFFS 0x180
574#define GPIOLD_DOE_OFFS 0x184
575#define GPIOLD_FS0_OFFS 0x188
576#define GPIOLD_FS1_OFFS 0x18c
577#define GPIOLD_FS2_OFFS 0x190
578#define GPIOLD_RPU_OFFS 0x1b0
579#define GPIOLD_RPD_OFFS 0x1b4
580#define GPIOLD_DV0_OFFS 0x1b8
581#define GPIOLD_DV1_OFFS 0x1bc
582
583#define GPIOAD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
584
585#define GPIOAD_DAT_OFFS 0x1c0
586#define GPIOAD_DOE_OFFS 0x1c4
587#define GPIOAD_FS0_OFFS 0x1c8
588#define GPIOAD_RPU_OFFS 0x1f0
589#define GPIOAD_RPD_OFFS 0x1f4
590#define GPIOAD_DV0_OFFS 0x1f8
591#define GPIOAD_DV1_OFFS 0x1fc
592
593#define GPIOXC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
594
595#define GPIOXC_DAT_OFFS 0x200
596#define GPIOXC_DOE_OFFS 0x204
597#define GPIOXC_FS0_OFFS 0x208
598#define GPIOXC_RPU_OFFS 0x230
599#define GPIOXC_RPD_OFFS 0x234
600#define GPIOXC_DV0_OFFS 0x238
601#define GPIOXC_DV1_OFFS 0x23c
602
603#define GPIOXC_FS0 __REG(GPIOXC_BASE + GPIOXC_FS0_OFFS)
604
605#define GPIOXC_FS0_CS0 (1 << 26)
606#define GPIOXC_FS0_CS1 (1 << 27)
607
608#define GPIOXD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
609
610#define GPIOXD_DAT_OFFS 0x240
611#define GPIOXD_FS0_OFFS 0x248
612#define GPIOXD_RPU_OFFS 0x270
613#define GPIOXD_RPD_OFFS 0x274
614#define GPIOXD_DV0_OFFS 0x278
615#define GPIOXD_DV1_OFFS 0x27c
616
617#define GPIOPK_BASE (APB1_PERI_BASE_VIRT + 0x1c000)
618
619#define GPIOPK_RST_OFFS 0x008
620#define GPIOPK_DAT_OFFS 0x100
621#define GPIOPK_DOE_OFFS 0x104
622#define GPIOPK_FS0_OFFS 0x108
623#define GPIOPK_FS1_OFFS 0x10c
624#define GPIOPK_FS2_OFFS 0x110
625#define GPIOPK_IRQST_OFFS 0x210
626#define GPIOPK_IRQEN_OFFS 0x214
627#define GPIOPK_IRQPOL_OFFS 0x218
628#define GPIOPK_IRQTM0_OFFS 0x21c
629#define GPIOPK_IRQTM1_OFFS 0x220
630#define GPIOPK_CTL_OFFS 0x22c
631
632#define PMGPIO_BASE (APB1_PERI_BASE_VIRT + 0x10000)
633#define BACKUP_RAM_BASE PMGPIO_BASE
634
635#define PMGPIO_DAT_OFFS 0x800
636#define PMGPIO_DOE_OFFS 0x804
637#define PMGPIO_FS0_OFFS 0x808
638#define PMGPIO_RPU_OFFS 0x810
639#define PMGPIO_RPD_OFFS 0x814
640#define PMGPIO_DV0_OFFS 0x818
641#define PMGPIO_DV1_OFFS 0x81c
642#define PMGPIO_EE0_OFFS 0x820
643#define PMGPIO_EE1_OFFS 0x824
644#define PMGPIO_CTL_OFFS 0x828
645#define PMGPIO_DI_OFFS 0x82c
646#define PMGPIO_STR_OFFS 0x830
647#define PMGPIO_STF_OFFS 0x834
648#define PMGPIO_POL_OFFS 0x838
649#define PMGPIO_APB_OFFS 0x800
650
651/* Clock controller registers */
652#define CKC_BASE ((void __iomem *)(APB1_PERI_BASE_VIRT + 0x6000))
653
654#define CLKCTRL_OFFS 0x00
655#define PLL0CFG_OFFS 0x04
656#define PLL1CFG_OFFS 0x08
657#define CLKDIVC0_OFFS 0x0c
658
659#define BCLKCTR0_OFFS 0x14
660#define SWRESET0_OFFS 0x18
661
662#define BCLKCTR1_OFFS 0x60
663#define SWRESET1_OFFS 0x64
664#define PWDCTL_OFFS 0x68
665#define PLL2CFG_OFFS 0x6c
666#define CLKDIVC1_OFFS 0x70
667
668#define ACLKREF_OFFS 0x80
669#define ACLKI2C_OFFS 0x84
670#define ACLKSPI0_OFFS 0x88
671#define ACLKSPI1_OFFS 0x8c
672#define ACLKUART0_OFFS 0x90
673#define ACLKUART1_OFFS 0x94
674#define ACLKUART2_OFFS 0x98
675#define ACLKUART3_OFFS 0x9c
676#define ACLKUART4_OFFS 0xa0
677#define ACLKTCT_OFFS 0xa4
678#define ACLKTCX_OFFS 0xa8
679#define ACLKTCZ_OFFS 0xac
680#define ACLKADC_OFFS 0xb0
681#define ACLKDAI0_OFFS 0xb4
682#define ACLKDAI1_OFFS 0xb8
683#define ACLKLCD_OFFS 0xbc
684#define ACLKSPDIF_OFFS 0xc0
685#define ACLKUSBH_OFFS 0xc4
686#define ACLKSDH0_OFFS 0xc8
687#define ACLKSDH1_OFFS 0xcc
688#define ACLKC3DEC_OFFS 0xd0
689#define ACLKEXT_OFFS 0xd4
690#define ACLKCAN0_OFFS 0xd8
691#define ACLKCAN1_OFFS 0xdc
692#define ACLKGSB0_OFFS 0xe0
693#define ACLKGSB1_OFFS 0xe4
694#define ACLKGSB2_OFFS 0xe8
695#define ACLKGSB3_OFFS 0xec
696
697#define PLLxCFG_PD (1 << 31)
698
699/* CLKCTRL bits */
700#define CLKCTRL_XE (1 << 31)
701
702/* CLKDIVCx bits */
703#define CLKDIVC0_XTE (1 << 7)
704#define CLKDIVC0_XE (1 << 15)
705#define CLKDIVC0_P1E (1 << 23)
706#define CLKDIVC0_P0E (1 << 31)
707
708#define CLKDIVC1_P2E (1 << 7)
709
710/* BCLKCTR0 clock bits */
711#define BCLKCTR0_USBD (1 << 4)
712#define BCLKCTR0_ECC (1 << 9)
713#define BCLKCTR0_USBH0 (1 << 11)
714#define BCLKCTR0_NFC (1 << 16)
715
716/* BCLKCTR1 clock bits */
717#define BCLKCTR1_USBH1 (1 << 20)
718
719/* SWRESET0 bits */
720#define SWRESET0_USBD (1 << 4)
721#define SWRESET0_USBH0 (1 << 11)
722
723/* SWRESET1 bits */
724#define SWRESET1_USBH1 (1 << 20)
725
726/* System clock sources.
727 * Note: These are the clock sources that serve as parents for
728 * all other clocks. They have no parents themselves.
729 *
730 * These values are used for struct clk->root_id. All clocks
731 * that are not system clock sources have this value set to
732 * CLK_SRC_NOROOT.
733 * The values for system clocks start with CLK_SRC_PLL0 == 0
734 * because this gives us exactly the values needed for the lower
735 * 4 bits of ACLK_* registers. Therefore, CLK_SRC_NOROOT is
736 * defined as -1 to not disturb the order.
737 */
738enum root_clks {
739 CLK_SRC_NOROOT = -1,
740 CLK_SRC_PLL0 = 0,
741 CLK_SRC_PLL1,
742 CLK_SRC_PLL0DIV,
743 CLK_SRC_PLL1DIV,
744 CLK_SRC_XI,
745 CLK_SRC_XIDIV,
746 CLK_SRC_XTI,
747 CLK_SRC_XTIDIV,
748 CLK_SRC_PLL2,
749 CLK_SRC_PLL2DIV,
750 CLK_SRC_PK0,
751 CLK_SRC_PK1,
752 CLK_SRC_PK2,
753 CLK_SRC_PK3,
754 CLK_SRC_PK4,
755 CLK_SRC_48MHZ
756};
757
758#define CLK_SRC_MASK 0xf
759
760/* Bits in ACLK* registers */
761#define ACLK_EN (1 << 28)
762#define ACLK_SEL_SHIFT 24
763#define ACLK_SEL_MASK 0x0f000000
764#define ACLK_DIV_MASK 0x00000fff
765
766/* System configuration registers */
767
768#define SCFG_BASE (APB1_PERI_BASE_VIRT + 0x13000)
769
770#define BMI_OFFS 0x00
771#define AHBCON0_OFFS 0x04
772#define APBPWE_OFFS 0x08
773#define DTCMWAIT_OFFS 0x0c
774#define ECCSEL_OFFS 0x10
775#define AHBCON1_OFFS 0x14
776#define SDHCFG_OFFS 0x18
777#define REMAP_OFFS 0x20
778#define LCDSIAE_OFFS 0x24
779#define XMCCFG_OFFS 0xe0
780#define IMCCFG_OFFS 0xe4
781
782/* Values for ECCSEL */
783#define ECCSEL_EXTMEM 0x0
784#define ECCSEL_DTCM 0x1
785#define ECCSEL_INT_SRAM 0x2
786#define ECCSEL_AHB 0x3
787
788/* Bits in XMCCFG */
789#define XMCCFG_NFCE (1 << 1)
790#define XMCCFG_FDXD (1 << 2)
791
792/* External memory controller registers */
793
794#define EMC_BASE EXT_MEM_CTRL_BASE
795
796#define SDCFG_OFFS 0x00
797#define SDFSM_OFFS 0x04
798#define MCFG_OFFS 0x08
799
800#define CSCFG0_OFFS 0x10
801#define CSCFG1_OFFS 0x14
802#define CSCFG2_OFFS 0x18
803#define CSCFG3_OFFS 0x1c
804
805#define MCFG_SDEN (1 << 4)
806
807#endif /* TCC8K_REGS_H */
diff --git a/arch/arm/plat-tcc/include/mach/timex.h b/arch/arm/plat-tcc/include/mach/timex.h
new file mode 100644
index 000000000000..057acbe651d9
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/timex.h
@@ -0,0 +1,5 @@
1/*
2 * A definition needed by arch core code.
3 *
4 */
5#define CLOCK_TICK_RATE (HZ * 100000UL)
diff --git a/arch/arm/plat-tcc/include/mach/uncompress.h b/arch/arm/plat-tcc/include/mach/uncompress.h
new file mode 100644
index 000000000000..7a3e33a27a30
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/uncompress.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
3 *
4 * This file is licensed under the terms of the GPL version 2.
5 */
6
7#include <linux/serial_reg.h>
8#include <linux/types.h>
9
10#include <mach/tcc8k-regs.h>
11
12unsigned int system_rev;
13
14#define ID_MASK 0x7fff
15
16static void putc(int c)
17{
18 u32 *uart_lsr = (u32 *)(UART_BASE_PHYS + (UART_LSR << 2));
19 u32 *uart_tx = (u32 *)(UART_BASE_PHYS + (UART_TX << 2));
20
21 while (!(*uart_lsr & UART_LSR_THRE))
22 barrier();
23 *uart_tx = c;
24}
25
26static inline void flush(void)
27{
28}
29
30/*
31 * nothing to do
32 */
33#define arch_decomp_setup()
34#define arch_decomp_wdog()
diff --git a/arch/arm/plat-tcc/include/mach/vmalloc.h b/arch/arm/plat-tcc/include/mach/vmalloc.h
new file mode 100644
index 000000000000..99414d9c2b94
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
1/*
2 * Author: <linux@telechips.com>
3 * Created: June 10, 2008
4 *
5 * Copyright (C) 2000 Russell King.
6 * Copyright (C) 2008-2009 Telechips
7 *
8 * Licensed under the terms of the GPL v2.
9 */
10#define VMALLOC_END 0xf0000000UL
diff --git a/arch/arm/plat-tcc/system.c b/arch/arm/plat-tcc/system.c
new file mode 100644
index 000000000000..cc208fae3e7a
--- /dev/null
+++ b/arch/arm/plat-tcc/system.c
@@ -0,0 +1,25 @@
1/*
2 * System functions for Telechips TCCxxxx SoCs
3 *
4 * Copyright (C) Hans J. Koch <hjk@linutronix.de>
5 *
6 * Licensed under the terms of the GPL v2.
7 *
8 */
9
10#include <linux/io.h>
11
12#include <mach/tcc8k-regs.h>
13
14/* System reboot */
15void plat_tcc_reboot(void)
16{
17 /* Make sure clocks are on */
18 __raw_writel(0xffffffff, CKC_BASE + BCLKCTR0_OFFS);
19
20 /* Enable watchdog reset */
21 __raw_writel(0x49, TIMER_BASE + TWDCFG_OFFS);
22 /* Wait for reset */
23 while(1)
24 ;
25}