diff options
author | Arnd Bergmann <arnd@arndb.de> | 2013-04-19 16:30:31 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2013-04-19 16:50:01 -0400 |
commit | 1b361942b53c33f38d55065c13785aadb5103a18 (patch) | |
tree | 07b26d32b175f27f18f1fca3d5944a58f89cd17f /arch/arm/mach-spear | |
parent | 61b464aef0e306f141dbc0bb3f9c58049a987a7e (diff) | |
parent | bcf3e72eff584136600a51a5b30ef7a794664d19 (diff) |
Merge branch 'spear/multiplatform' into late/cleanup
This is a prerequisite for the spear/dwdma series.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-spear')
26 files changed, 3003 insertions, 0 deletions
diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig new file mode 100644 index 000000000000..5412aeb377ac --- /dev/null +++ b/arch/arm/mach-spear/Kconfig | |||
@@ -0,0 +1,103 @@ | |||
1 | # | ||
2 | # SPEAr Platform configuration file | ||
3 | # | ||
4 | |||
5 | menuconfig PLAT_SPEAR | ||
6 | bool "ST SPEAr Family" if ARCH_MULTI_V7 || ARCH_MULTI_V5 | ||
7 | default PLAT_SPEAR_SINGLE | ||
8 | select ARCH_REQUIRE_GPIOLIB | ||
9 | select ARM_AMBA | ||
10 | select CLKDEV_LOOKUP | ||
11 | select CLKSRC_MMIO | ||
12 | select COMMON_CLK | ||
13 | select GENERIC_CLOCKEVENTS | ||
14 | select HAVE_CLK | ||
15 | |||
16 | if PLAT_SPEAR | ||
17 | |||
18 | config ARCH_SPEAR13XX | ||
19 | bool "ST SPEAr13xx" | ||
20 | depends on ARCH_MULTI_V7 || PLAT_SPEAR_SINGLE | ||
21 | select ARCH_HAS_CPUFREQ | ||
22 | select ARM_GIC | ||
23 | select CPU_V7 | ||
24 | select GPIO_SPEAR_SPICS | ||
25 | select HAVE_SMP | ||
26 | select MIGHT_HAVE_CACHE_L2X0 | ||
27 | select PINCTRL | ||
28 | select USE_OF | ||
29 | help | ||
30 | Supports for ARM's SPEAR13XX family | ||
31 | |||
32 | if ARCH_SPEAR13XX | ||
33 | |||
34 | config MACH_SPEAR1310 | ||
35 | bool "SPEAr1310 Machine support with Device Tree" | ||
36 | select PINCTRL_SPEAR1310 | ||
37 | help | ||
38 | Supports ST SPEAr1310 machine configured via the device-tree | ||
39 | |||
40 | config MACH_SPEAR1340 | ||
41 | bool "SPEAr1340 Machine support with Device Tree" | ||
42 | select PINCTRL_SPEAR1340 | ||
43 | help | ||
44 | Supports ST SPEAr1340 machine configured via the device-tree | ||
45 | |||
46 | endif #ARCH_SPEAR13XX | ||
47 | |||
48 | config ARCH_SPEAR3XX | ||
49 | bool "ST SPEAr3xx" | ||
50 | depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE | ||
51 | depends on !ARCH_SPEAR13XX | ||
52 | select ARM_VIC | ||
53 | select CPU_ARM926T | ||
54 | select PINCTRL | ||
55 | select USE_OF | ||
56 | help | ||
57 | Supports for ARM's SPEAR3XX family | ||
58 | |||
59 | if ARCH_SPEAR3XX | ||
60 | |||
61 | config MACH_SPEAR300 | ||
62 | bool "SPEAr300 Machine support with Device Tree" | ||
63 | select PINCTRL_SPEAR300 | ||
64 | help | ||
65 | Supports ST SPEAr300 machine configured via the device-tree | ||
66 | |||
67 | config MACH_SPEAR310 | ||
68 | bool "SPEAr310 Machine support with Device Tree" | ||
69 | select PINCTRL_SPEAR310 | ||
70 | help | ||
71 | Supports ST SPEAr310 machine configured via the device-tree | ||
72 | |||
73 | config MACH_SPEAR320 | ||
74 | bool "SPEAr320 Machine support with Device Tree" | ||
75 | select PINCTRL_SPEAR320 | ||
76 | help | ||
77 | Supports ST SPEAr320 machine configured via the device-tree | ||
78 | |||
79 | endif | ||
80 | |||
81 | config ARCH_SPEAR6XX | ||
82 | bool "ST SPEAr6XX" | ||
83 | depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE | ||
84 | depends on !ARCH_SPEAR13XX | ||
85 | select ARM_VIC | ||
86 | select CPU_ARM926T | ||
87 | help | ||
88 | Supports for ARM's SPEAR6XX family | ||
89 | |||
90 | config MACH_SPEAR600 | ||
91 | def_bool y | ||
92 | depends on ARCH_SPEAR6XX | ||
93 | select USE_OF | ||
94 | help | ||
95 | Supports ST SPEAr600 boards configured via the device-treesource "arch/arm/mach-spear6xx/Kconfig" | ||
96 | |||
97 | config ARCH_SPEAR_AUTO | ||
98 | def_bool PLAT_SPEAR_SINGLE | ||
99 | depends on !ARCH_SPEAR13XX && !ARCH_SPEAR6XX | ||
100 | select ARCH_SPEAR3XX | ||
101 | |||
102 | endif | ||
103 | |||
diff --git a/arch/arm/mach-spear/Makefile b/arch/arm/mach-spear/Makefile new file mode 100644 index 000000000000..dc9ce80508ad --- /dev/null +++ b/arch/arm/mach-spear/Makefile | |||
@@ -0,0 +1,24 @@ | |||
1 | # | ||
2 | # SPEAr Platform specific Makefile | ||
3 | # | ||
4 | |||
5 | ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include | ||
6 | |||
7 | # Common support | ||
8 | obj-y := restart.o time.o | ||
9 | |||
10 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o | ||
11 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
12 | |||
13 | obj-$(CONFIG_ARCH_SPEAR13XX) += spear13xx.o | ||
14 | obj-$(CONFIG_MACH_SPEAR1310) += spear1310.o | ||
15 | obj-$(CONFIG_MACH_SPEAR1340) += spear1340.o | ||
16 | |||
17 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear3xx.o | ||
18 | obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o | ||
19 | obj-$(CONFIG_MACH_SPEAR300) += spear300.o | ||
20 | obj-$(CONFIG_MACH_SPEAR310) += spear310.o | ||
21 | obj-$(CONFIG_MACH_SPEAR320) += spear320.o | ||
22 | |||
23 | obj-$(CONFIG_ARCH_SPEAR6XX) += spear6xx.o | ||
24 | obj-$(CONFIG_ARCH_SPEAR6XX) += pl080.o | ||
diff --git a/arch/arm/mach-spear/Makefile.boot b/arch/arm/mach-spear/Makefile.boot new file mode 100644 index 000000000000..4674a4c221db --- /dev/null +++ b/arch/arm/mach-spear/Makefile.boot | |||
@@ -0,0 +1,3 @@ | |||
1 | zreladdr-y += 0x00008000 | ||
2 | params_phys-y := 0x00000100 | ||
3 | initrd_phys-y := 0x00800000 | ||
diff --git a/arch/arm/mach-spear/generic.h b/arch/arm/mach-spear/generic.h new file mode 100644 index 000000000000..8ba7e75b648d --- /dev/null +++ b/arch/arm/mach-spear/generic.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * spear machine family generic header file | ||
3 | * | ||
4 | * Copyright (C) 2009-2012 ST Microelectronics | ||
5 | * Rajeev Kumar <rajeev-dlh.kumar@st.com> | ||
6 | * Viresh Kumar <viresh.linux@gmail.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #ifndef __MACH_GENERIC_H | ||
14 | #define __MACH_GENERIC_H | ||
15 | |||
16 | #include <linux/dmaengine.h> | ||
17 | #include <linux/amba/pl08x.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <asm/mach/time.h> | ||
20 | |||
21 | extern void spear13xx_timer_init(void); | ||
22 | extern void spear3xx_timer_init(void); | ||
23 | extern struct pl022_ssp_controller pl022_plat_data; | ||
24 | extern struct pl08x_platform_data pl080_plat_data; | ||
25 | extern struct dw_dma_platform_data dmac_plat_data; | ||
26 | extern struct dw_dma_slave cf_dma_priv; | ||
27 | extern struct dw_dma_slave nand_read_dma_priv; | ||
28 | extern struct dw_dma_slave nand_write_dma_priv; | ||
29 | bool dw_dma_filter(struct dma_chan *chan, void *slave); | ||
30 | |||
31 | void __init spear_setup_of_timer(void); | ||
32 | void __init spear3xx_clk_init(void __iomem *misc_base, | ||
33 | void __iomem *soc_config_base); | ||
34 | void __init spear3xx_map_io(void); | ||
35 | void __init spear3xx_dt_init_irq(void); | ||
36 | void __init spear6xx_clk_init(void __iomem *misc_base); | ||
37 | void __init spear13xx_map_io(void); | ||
38 | void __init spear13xx_l2x0_init(void); | ||
39 | |||
40 | void spear_restart(char, const char *); | ||
41 | |||
42 | void spear13xx_secondary_startup(void); | ||
43 | void __cpuinit spear13xx_cpu_die(unsigned int cpu); | ||
44 | |||
45 | extern struct smp_operations spear13xx_smp_ops; | ||
46 | |||
47 | #ifdef CONFIG_MACH_SPEAR1310 | ||
48 | void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base); | ||
49 | #else | ||
50 | static inline void spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) {} | ||
51 | #endif | ||
52 | |||
53 | #ifdef CONFIG_MACH_SPEAR1340 | ||
54 | void __init spear1340_clk_init(void __iomem *misc_base); | ||
55 | #else | ||
56 | static inline void spear1340_clk_init(void __iomem *misc_base) {} | ||
57 | #endif | ||
58 | |||
59 | #endif /* __MACH_GENERIC_H */ | ||
diff --git a/arch/arm/mach-spear/headsmp.S b/arch/arm/mach-spear/headsmp.S new file mode 100644 index 000000000000..ed85473a047f --- /dev/null +++ b/arch/arm/mach-spear/headsmp.S | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear13XX/headsmp.S | ||
3 | * | ||
4 | * Picked from realview | ||
5 | * Copyright (c) 2012 ST Microelectronics Limited | ||
6 | * Shiraz Hashim <shiraz.hashim@st.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/linkage.h> | ||
14 | #include <linux/init.h> | ||
15 | |||
16 | __INIT | ||
17 | |||
18 | /* | ||
19 | * spear13xx specific entry point for secondary CPUs. This provides | ||
20 | * a "holding pen" into which all secondary cores are held until we're | ||
21 | * ready for them to initialise. | ||
22 | */ | ||
23 | ENTRY(spear13xx_secondary_startup) | ||
24 | mrc p15, 0, r0, c0, c0, 5 | ||
25 | and r0, r0, #15 | ||
26 | adr r4, 1f | ||
27 | ldmia r4, {r5, r6} | ||
28 | sub r4, r4, r5 | ||
29 | add r6, r6, r4 | ||
30 | pen: ldr r7, [r6] | ||
31 | cmp r7, r0 | ||
32 | bne pen | ||
33 | |||
34 | /* re-enable coherency */ | ||
35 | mrc p15, 0, r0, c1, c0, 1 | ||
36 | orr r0, r0, #(1 << 6) | (1 << 0) | ||
37 | mcr p15, 0, r0, c1, c0, 1 | ||
38 | /* | ||
39 | * we've been released from the holding pen: secondary_stack | ||
40 | * should now contain the SVC stack for this core | ||
41 | */ | ||
42 | b secondary_startup | ||
43 | |||
44 | .align | ||
45 | 1: .long . | ||
46 | .long pen_release | ||
47 | ENDPROC(spear13xx_secondary_startup) | ||
diff --git a/arch/arm/mach-spear/hotplug.c b/arch/arm/mach-spear/hotplug.c new file mode 100644 index 000000000000..a7d2dd11a4f2 --- /dev/null +++ b/arch/arm/mach-spear/hotplug.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-spear13xx/hotplug.c | ||
3 | * | ||
4 | * Copyright (C) 2012 ST Microelectronics Ltd. | ||
5 | * Deepak Sikri <deepak.sikri@st.com> | ||
6 | * | ||
7 | * based upon linux/arch/arm/mach-realview/hotplug.c | ||
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 | #include <linux/kernel.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/smp.h> | ||
16 | #include <asm/cacheflush.h> | ||
17 | #include <asm/cp15.h> | ||
18 | #include <asm/smp_plat.h> | ||
19 | |||
20 | static inline void cpu_enter_lowpower(void) | ||
21 | { | ||
22 | unsigned int v; | ||
23 | |||
24 | flush_cache_all(); | ||
25 | asm volatile( | ||
26 | " mcr p15, 0, %1, c7, c5, 0\n" | ||
27 | " dsb\n" | ||
28 | /* | ||
29 | * Turn off coherency | ||
30 | */ | ||
31 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
32 | " bic %0, %0, #0x20\n" | ||
33 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
34 | " mrc p15, 0, %0, c1, c0, 0\n" | ||
35 | " bic %0, %0, %2\n" | ||
36 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
37 | : "=&r" (v) | ||
38 | : "r" (0), "Ir" (CR_C) | ||
39 | : "cc", "memory"); | ||
40 | } | ||
41 | |||
42 | static inline void cpu_leave_lowpower(void) | ||
43 | { | ||
44 | unsigned int v; | ||
45 | |||
46 | asm volatile("mrc p15, 0, %0, c1, c0, 0\n" | ||
47 | " orr %0, %0, %1\n" | ||
48 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
49 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
50 | " orr %0, %0, #0x20\n" | ||
51 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
52 | : "=&r" (v) | ||
53 | : "Ir" (CR_C) | ||
54 | : "cc"); | ||
55 | } | ||
56 | |||
57 | static inline void spear13xx_do_lowpower(unsigned int cpu, int *spurious) | ||
58 | { | ||
59 | for (;;) { | ||
60 | wfi(); | ||
61 | |||
62 | if (pen_release == cpu) { | ||
63 | /* | ||
64 | * OK, proper wakeup, we're done | ||
65 | */ | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * Getting here, means that we have come out of WFI without | ||
71 | * having been woken up - this shouldn't happen | ||
72 | * | ||
73 | * Just note it happening - when we're woken, we can report | ||
74 | * its occurrence. | ||
75 | */ | ||
76 | (*spurious)++; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * platform-specific code to shutdown a CPU | ||
82 | * | ||
83 | * Called with IRQs disabled | ||
84 | */ | ||
85 | void __ref spear13xx_cpu_die(unsigned int cpu) | ||
86 | { | ||
87 | int spurious = 0; | ||
88 | |||
89 | /* | ||
90 | * we're ready for shutdown now, so do it | ||
91 | */ | ||
92 | cpu_enter_lowpower(); | ||
93 | spear13xx_do_lowpower(cpu, &spurious); | ||
94 | |||
95 | /* | ||
96 | * bring this CPU back into the world of cache | ||
97 | * coherency, and then restore interrupts | ||
98 | */ | ||
99 | cpu_leave_lowpower(); | ||
100 | |||
101 | if (spurious) | ||
102 | pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); | ||
103 | } | ||
diff --git a/arch/arm/mach-spear/include/mach/debug-macro.S b/arch/arm/mach-spear/include/mach/debug-macro.S new file mode 100644 index 000000000000..75b05ad0fbad --- /dev/null +++ b/arch/arm/mach-spear/include/mach/debug-macro.S | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/include/plat/debug-macro.S | ||
3 | * | ||
4 | * Debugging macro include header for spear platform | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/amba/serial.h> | ||
15 | #include <mach/spear.h> | ||
16 | |||
17 | .macro addruart, rp, rv, tmp | ||
18 | mov \rp, #SPEAR_DBG_UART_BASE @ Physical base | ||
19 | mov \rv, #VA_SPEAR_DBG_UART_BASE @ Virtual base | ||
20 | .endm | ||
21 | |||
22 | .macro senduart, rd, rx | ||
23 | strb \rd, [\rx, #UART01x_DR] @ ASC_TX_BUFFER | ||
24 | .endm | ||
25 | |||
26 | .macro waituart, rd, rx | ||
27 | 1001: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER | ||
28 | tst \rd, #UART01x_FR_TXFF @ TX_FULL | ||
29 | bne 1001b | ||
30 | .endm | ||
31 | |||
32 | .macro busyuart, rd, rx | ||
33 | 1002: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER | ||
34 | tst \rd, #UART011_FR_TXFE @ TX_EMPTY | ||
35 | beq 1002b | ||
36 | .endm | ||
diff --git a/arch/arm/mach-spear/include/mach/irqs.h b/arch/arm/mach-spear/include/mach/irqs.h new file mode 100644 index 000000000000..92da0a8c6bce --- /dev/null +++ b/arch/arm/mach-spear/include/mach/irqs.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * IRQ helper macros for spear machine family | ||
3 | * | ||
4 | * Copyright (C) 2009-2012 ST Microelectronics | ||
5 | * Rajeev Kumar <rajeev-dlh.kumar@st.com> | ||
6 | * Viresh Kumar <viresh.linux@gmail.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #ifndef __MACH_IRQS_H | ||
14 | #define __MACH_IRQS_H | ||
15 | |||
16 | #ifdef CONFIG_ARCH_SPEAR3XX | ||
17 | #define NR_IRQS 256 | ||
18 | #endif | ||
19 | |||
20 | #ifdef CONFIG_ARCH_SPEAR6XX | ||
21 | /* IRQ definitions */ | ||
22 | /* VIC 1 */ | ||
23 | #define IRQ_VIC_END 64 | ||
24 | |||
25 | /* GPIO pins virtual irqs */ | ||
26 | #define VIRTUAL_IRQS 24 | ||
27 | #define NR_IRQS (IRQ_VIC_END + VIRTUAL_IRQS) | ||
28 | #endif | ||
29 | |||
30 | #ifdef CONFIG_ARCH_SPEAR13XX | ||
31 | #define IRQ_GIC_END 160 | ||
32 | #define NR_IRQS IRQ_GIC_END | ||
33 | #endif | ||
34 | |||
35 | #endif /* __MACH_IRQS_H */ | ||
diff --git a/arch/arm/mach-spear/include/mach/misc_regs.h b/arch/arm/mach-spear/include/mach/misc_regs.h new file mode 100644 index 000000000000..935639ce59ba --- /dev/null +++ b/arch/arm/mach-spear/include/mach/misc_regs.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear3xx/include/mach/misc_regs.h | ||
3 | * | ||
4 | * Miscellaneous registers definitions for SPEAr3xx machine family | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #ifndef __MACH_MISC_REGS_H | ||
15 | #define __MACH_MISC_REGS_H | ||
16 | |||
17 | #include <mach/spear.h> | ||
18 | |||
19 | #define MISC_BASE (VA_SPEAR_ICM3_MISC_REG_BASE) | ||
20 | #define DMA_CHN_CFG (MISC_BASE + 0x0A0) | ||
21 | |||
22 | #endif /* __MACH_MISC_REGS_H */ | ||
diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h new file mode 100644 index 000000000000..374ddc393df1 --- /dev/null +++ b/arch/arm/mach-spear/include/mach/spear.h | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * SPEAr3xx/6xx Machine family specific definition | ||
3 | * | ||
4 | * Copyright (C) 2009,2012 ST Microelectronics | ||
5 | * Rajeev Kumar<rajeev-dlh.kumar@st.com> | ||
6 | * Viresh Kumar <viresh.linux@gmail.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #ifndef __MACH_SPEAR_H | ||
14 | #define __MACH_SPEAR_H | ||
15 | |||
16 | #include <asm/memory.h> | ||
17 | |||
18 | #if defined(CONFIG_ARCH_SPEAR3XX) || defined (CONFIG_ARCH_SPEAR6XX) | ||
19 | |||
20 | /* ICM1 - Low speed connection */ | ||
21 | #define SPEAR_ICM1_2_BASE UL(0xD0000000) | ||
22 | #define VA_SPEAR_ICM1_2_BASE IOMEM(0xFD000000) | ||
23 | #define SPEAR_ICM1_UART_BASE UL(0xD0000000) | ||
24 | #define VA_SPEAR_ICM1_UART_BASE (VA_SPEAR_ICM1_2_BASE - SPEAR_ICM1_2_BASE + SPEAR_ICM1_UART_BASE) | ||
25 | #define SPEAR3XX_ICM1_SSP_BASE UL(0xD0100000) | ||
26 | |||
27 | /* ML-1, 2 - Multi Layer CPU Subsystem */ | ||
28 | #define SPEAR_ICM3_ML1_2_BASE UL(0xF0000000) | ||
29 | #define VA_SPEAR6XX_ML_CPU_BASE IOMEM(0xF0000000) | ||
30 | |||
31 | /* ICM3 - Basic Subsystem */ | ||
32 | #define SPEAR_ICM3_SMI_CTRL_BASE UL(0xFC000000) | ||
33 | #define VA_SPEAR_ICM3_SMI_CTRL_BASE IOMEM(0xFC000000) | ||
34 | #define SPEAR_ICM3_DMA_BASE UL(0xFC400000) | ||
35 | #define SPEAR_ICM3_SYS_CTRL_BASE UL(0xFCA00000) | ||
36 | #define VA_SPEAR_ICM3_SYS_CTRL_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_SYS_CTRL_BASE) | ||
37 | #define SPEAR_ICM3_MISC_REG_BASE UL(0xFCA80000) | ||
38 | #define VA_SPEAR_ICM3_MISC_REG_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_MISC_REG_BASE) | ||
39 | |||
40 | /* Debug uart for linux, will be used for debug and uncompress messages */ | ||
41 | #define SPEAR_DBG_UART_BASE SPEAR_ICM1_UART_BASE | ||
42 | #define VA_SPEAR_DBG_UART_BASE VA_SPEAR_ICM1_UART_BASE | ||
43 | |||
44 | /* Sysctl base for spear platform */ | ||
45 | #define SPEAR_SYS_CTRL_BASE SPEAR_ICM3_SYS_CTRL_BASE | ||
46 | #define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR_ICM3_SYS_CTRL_BASE | ||
47 | #endif /* SPEAR3xx || SPEAR6XX */ | ||
48 | |||
49 | /* SPEAr320 Macros */ | ||
50 | #define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000) | ||
51 | #define VA_SPEAR320_SOC_CONFIG_BASE IOMEM(0xFE000000) | ||
52 | |||
53 | #ifdef CONFIG_ARCH_SPEAR13XX | ||
54 | |||
55 | #define PERIP_GRP2_BASE UL(0xB3000000) | ||
56 | #define VA_PERIP_GRP2_BASE IOMEM(0xFE000000) | ||
57 | #define MCIF_SDHCI_BASE UL(0xB3000000) | ||
58 | #define SYSRAM0_BASE UL(0xB3800000) | ||
59 | #define VA_SYSRAM0_BASE IOMEM(0xFE800000) | ||
60 | #define SYS_LOCATION (VA_SYSRAM0_BASE + 0x600) | ||
61 | |||
62 | #define PERIP_GRP1_BASE UL(0xE0000000) | ||
63 | #define VA_PERIP_GRP1_BASE IOMEM(0xFD000000) | ||
64 | #define UART_BASE UL(0xE0000000) | ||
65 | #define VA_UART_BASE IOMEM(0xFD000000) | ||
66 | #define SSP_BASE UL(0xE0100000) | ||
67 | #define MISC_BASE UL(0xE0700000) | ||
68 | #define VA_MISC_BASE IOMEM(0xFD700000) | ||
69 | |||
70 | #define A9SM_AND_MPMC_BASE UL(0xEC000000) | ||
71 | #define VA_A9SM_AND_MPMC_BASE IOMEM(0xFC000000) | ||
72 | |||
73 | #define SPEAR1310_RAS_BASE UL(0xD8400000) | ||
74 | #define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) | ||
75 | |||
76 | /* A9SM peripheral offsets */ | ||
77 | #define A9SM_PERIP_BASE UL(0xEC800000) | ||
78 | #define VA_A9SM_PERIP_BASE IOMEM(0xFC800000) | ||
79 | #define VA_SCU_BASE (VA_A9SM_PERIP_BASE + 0x00) | ||
80 | |||
81 | #define L2CC_BASE UL(0xED000000) | ||
82 | #define VA_L2CC_BASE IOMEM(UL(0xFB000000)) | ||
83 | |||
84 | /* others */ | ||
85 | #define DMAC0_BASE UL(0xEA800000) | ||
86 | #define DMAC1_BASE UL(0xEB000000) | ||
87 | #define MCIF_CF_BASE UL(0xB2800000) | ||
88 | |||
89 | /* Debug uart for linux, will be used for debug and uncompress messages */ | ||
90 | #define SPEAR_DBG_UART_BASE UART_BASE | ||
91 | #define VA_SPEAR_DBG_UART_BASE VA_UART_BASE | ||
92 | |||
93 | #endif /* SPEAR13XX */ | ||
94 | |||
95 | #endif /* __MACH_SPEAR_H */ | ||
diff --git a/arch/arm/mach-spear/include/mach/timex.h b/arch/arm/mach-spear/include/mach/timex.h new file mode 100644 index 000000000000..ef95e5b780bd --- /dev/null +++ b/arch/arm/mach-spear/include/mach/timex.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/include/plat/timex.h | ||
3 | * | ||
4 | * SPEAr platform specific timex definitions | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #ifndef __PLAT_TIMEX_H | ||
15 | #define __PLAT_TIMEX_H | ||
16 | |||
17 | #define CLOCK_TICK_RATE 48000000 | ||
18 | |||
19 | #endif /* __PLAT_TIMEX_H */ | ||
diff --git a/arch/arm/mach-spear/include/mach/uncompress.h b/arch/arm/mach-spear/include/mach/uncompress.h new file mode 100644 index 000000000000..51b2dc93e4da --- /dev/null +++ b/arch/arm/mach-spear/include/mach/uncompress.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/include/plat/uncompress.h | ||
3 | * | ||
4 | * Serial port stubs for kernel decompress status messages | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/io.h> | ||
15 | #include <linux/amba/serial.h> | ||
16 | #include <mach/spear.h> | ||
17 | |||
18 | #ifndef __PLAT_UNCOMPRESS_H | ||
19 | #define __PLAT_UNCOMPRESS_H | ||
20 | /* | ||
21 | * This does not append a newline | ||
22 | */ | ||
23 | static inline void putc(int c) | ||
24 | { | ||
25 | void __iomem *base = (void __iomem *)SPEAR_DBG_UART_BASE; | ||
26 | |||
27 | while (readl_relaxed(base + UART01x_FR) & UART01x_FR_TXFF) | ||
28 | barrier(); | ||
29 | |||
30 | writel_relaxed(c, base + UART01x_DR); | ||
31 | } | ||
32 | |||
33 | static inline void flush(void) | ||
34 | { | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * nothing to do | ||
39 | */ | ||
40 | #define arch_decomp_setup() | ||
41 | |||
42 | #endif /* __PLAT_UNCOMPRESS_H */ | ||
diff --git a/arch/arm/mach-spear/pl080.c b/arch/arm/mach-spear/pl080.c new file mode 100644 index 000000000000..cfa1199d0f4a --- /dev/null +++ b/arch/arm/mach-spear/pl080.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/pl080.c | ||
3 | * | ||
4 | * DMAC pl080 definitions for SPEAr platform | ||
5 | * | ||
6 | * Copyright (C) 2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/amba/pl08x.h> | ||
15 | #include <linux/amba/bus.h> | ||
16 | #include <linux/bug.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/spinlock_types.h> | ||
20 | #include <mach/spear.h> | ||
21 | #include <mach/misc_regs.h> | ||
22 | |||
23 | static spinlock_t lock = __SPIN_LOCK_UNLOCKED(x); | ||
24 | |||
25 | struct { | ||
26 | unsigned char busy; | ||
27 | unsigned char val; | ||
28 | } signals[16] = {{0, 0}, }; | ||
29 | |||
30 | int pl080_get_signal(const struct pl08x_channel_data *cd) | ||
31 | { | ||
32 | unsigned int signal = cd->min_signal, val; | ||
33 | unsigned long flags; | ||
34 | |||
35 | spin_lock_irqsave(&lock, flags); | ||
36 | |||
37 | /* Return if signal is already acquired by somebody else */ | ||
38 | if (signals[signal].busy && | ||
39 | (signals[signal].val != cd->muxval)) { | ||
40 | spin_unlock_irqrestore(&lock, flags); | ||
41 | return -EBUSY; | ||
42 | } | ||
43 | |||
44 | /* If acquiring for the first time, configure it */ | ||
45 | if (!signals[signal].busy) { | ||
46 | val = readl(DMA_CHN_CFG); | ||
47 | |||
48 | /* | ||
49 | * Each request line has two bits in DMA_CHN_CFG register. To | ||
50 | * goto the bits of current request line, do left shift of | ||
51 | * value by 2 * signal number. | ||
52 | */ | ||
53 | val &= ~(0x3 << (signal * 2)); | ||
54 | val |= cd->muxval << (signal * 2); | ||
55 | writel(val, DMA_CHN_CFG); | ||
56 | } | ||
57 | |||
58 | signals[signal].busy++; | ||
59 | signals[signal].val = cd->muxval; | ||
60 | spin_unlock_irqrestore(&lock, flags); | ||
61 | |||
62 | return signal; | ||
63 | } | ||
64 | |||
65 | void pl080_put_signal(const struct pl08x_channel_data *cd, int signal) | ||
66 | { | ||
67 | unsigned long flags; | ||
68 | |||
69 | spin_lock_irqsave(&lock, flags); | ||
70 | |||
71 | /* if signal is not used */ | ||
72 | if (!signals[signal].busy) | ||
73 | BUG(); | ||
74 | |||
75 | signals[signal].busy--; | ||
76 | |||
77 | spin_unlock_irqrestore(&lock, flags); | ||
78 | } | ||
diff --git a/arch/arm/mach-spear/pl080.h b/arch/arm/mach-spear/pl080.h new file mode 100644 index 000000000000..eb6590ded40d --- /dev/null +++ b/arch/arm/mach-spear/pl080.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/include/plat/pl080.h | ||
3 | * | ||
4 | * DMAC pl080 definitions for SPEAr platform | ||
5 | * | ||
6 | * Copyright (C) 2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #ifndef __PLAT_PL080_H | ||
15 | #define __PLAT_PL080_H | ||
16 | |||
17 | struct pl08x_channel_data; | ||
18 | int pl080_get_signal(const struct pl08x_channel_data *cd); | ||
19 | void pl080_put_signal(const struct pl08x_channel_data *cd, int signal); | ||
20 | |||
21 | #endif /* __PLAT_PL080_H */ | ||
diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c new file mode 100644 index 000000000000..927979e26b4d --- /dev/null +++ b/arch/arm/mach-spear/platsmp.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear13xx/platsmp.c | ||
3 | * | ||
4 | * based upon linux/arch/arm/mach-realview/platsmp.c | ||
5 | * | ||
6 | * Copyright (C) 2012 ST Microelectronics Ltd. | ||
7 | * Shiraz Hashim <shiraz.hashim@st.com> | ||
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/delay.h> | ||
15 | #include <linux/jiffies.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/smp.h> | ||
18 | #include <linux/irqchip/arm-gic.h> | ||
19 | #include <asm/cacheflush.h> | ||
20 | #include <asm/smp_scu.h> | ||
21 | #include <mach/spear.h> | ||
22 | #include "generic.h" | ||
23 | |||
24 | static DEFINE_SPINLOCK(boot_lock); | ||
25 | |||
26 | static void __iomem *scu_base = IOMEM(VA_SCU_BASE); | ||
27 | |||
28 | static void __cpuinit spear13xx_secondary_init(unsigned int cpu) | ||
29 | { | ||
30 | /* | ||
31 | * if any interrupts are already enabled for the primary | ||
32 | * core (e.g. timer irq), then they will not have been enabled | ||
33 | * for us: do so | ||
34 | */ | ||
35 | gic_secondary_init(0); | ||
36 | |||
37 | /* | ||
38 | * let the primary processor know we're out of the | ||
39 | * pen, then head off into the C entry point | ||
40 | */ | ||
41 | pen_release = -1; | ||
42 | smp_wmb(); | ||
43 | |||
44 | /* | ||
45 | * Synchronise with the boot thread. | ||
46 | */ | ||
47 | spin_lock(&boot_lock); | ||
48 | spin_unlock(&boot_lock); | ||
49 | } | ||
50 | |||
51 | static int __cpuinit spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
52 | { | ||
53 | unsigned long timeout; | ||
54 | |||
55 | /* | ||
56 | * set synchronisation state between this boot processor | ||
57 | * and the secondary one | ||
58 | */ | ||
59 | spin_lock(&boot_lock); | ||
60 | |||
61 | /* | ||
62 | * The secondary processor is waiting to be released from | ||
63 | * the holding pen - release it, then wait for it to flag | ||
64 | * that it has been released by resetting pen_release. | ||
65 | * | ||
66 | * Note that "pen_release" is the hardware CPU ID, whereas | ||
67 | * "cpu" is Linux's internal ID. | ||
68 | */ | ||
69 | pen_release = cpu; | ||
70 | flush_cache_all(); | ||
71 | outer_flush_all(); | ||
72 | |||
73 | timeout = jiffies + (1 * HZ); | ||
74 | while (time_before(jiffies, timeout)) { | ||
75 | smp_rmb(); | ||
76 | if (pen_release == -1) | ||
77 | break; | ||
78 | |||
79 | udelay(10); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * now the secondary core is starting up let it run its | ||
84 | * calibrations, then wait for it to finish | ||
85 | */ | ||
86 | spin_unlock(&boot_lock); | ||
87 | |||
88 | return pen_release != -1 ? -ENOSYS : 0; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * Initialise the CPU possible map early - this describes the CPUs | ||
93 | * which may be present or become present in the system. | ||
94 | */ | ||
95 | static void __init spear13xx_smp_init_cpus(void) | ||
96 | { | ||
97 | unsigned int i, ncores = scu_get_core_count(scu_base); | ||
98 | |||
99 | if (ncores > nr_cpu_ids) { | ||
100 | pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", | ||
101 | ncores, nr_cpu_ids); | ||
102 | ncores = nr_cpu_ids; | ||
103 | } | ||
104 | |||
105 | for (i = 0; i < ncores; i++) | ||
106 | set_cpu_possible(i, true); | ||
107 | } | ||
108 | |||
109 | static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus) | ||
110 | { | ||
111 | |||
112 | scu_enable(scu_base); | ||
113 | |||
114 | /* | ||
115 | * Write the address of secondary startup into the system-wide location | ||
116 | * (presently it is in SRAM). The BootMonitor waits until it receives a | ||
117 | * soft interrupt, and then the secondary CPU branches to this address. | ||
118 | */ | ||
119 | __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION); | ||
120 | } | ||
121 | |||
122 | struct smp_operations spear13xx_smp_ops __initdata = { | ||
123 | .smp_init_cpus = spear13xx_smp_init_cpus, | ||
124 | .smp_prepare_cpus = spear13xx_smp_prepare_cpus, | ||
125 | .smp_secondary_init = spear13xx_secondary_init, | ||
126 | .smp_boot_secondary = spear13xx_boot_secondary, | ||
127 | #ifdef CONFIG_HOTPLUG_CPU | ||
128 | .cpu_die = spear13xx_cpu_die, | ||
129 | #endif | ||
130 | }; | ||
diff --git a/arch/arm/mach-spear/restart.c b/arch/arm/mach-spear/restart.c new file mode 100644 index 000000000000..2b44500bb718 --- /dev/null +++ b/arch/arm/mach-spear/restart.c | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/restart.c | ||
3 | * | ||
4 | * SPEAr platform specific restart functions | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/amba/sp810.h> | ||
15 | #include <asm/system_misc.h> | ||
16 | #include <mach/spear.h> | ||
17 | #include "generic.h" | ||
18 | |||
19 | #define SPEAR13XX_SYS_SW_RES (VA_MISC_BASE + 0x204) | ||
20 | void spear_restart(char mode, const char *cmd) | ||
21 | { | ||
22 | if (mode == 's') { | ||
23 | /* software reset, Jump into ROM at address 0 */ | ||
24 | soft_restart(0); | ||
25 | } else { | ||
26 | /* hardware reset, Use on-chip reset capability */ | ||
27 | #ifdef CONFIG_ARCH_SPEAR13XX | ||
28 | writel_relaxed(0x01, SPEAR13XX_SYS_SW_RES); | ||
29 | #endif | ||
30 | #if defined(CONFIG_ARCH_SPEAR3XX) || defined(CONFIG_ARCH_SPEAR6XX) | ||
31 | sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE); | ||
32 | #endif | ||
33 | } | ||
34 | } | ||
diff --git a/arch/arm/mach-spear/spear1310.c b/arch/arm/mach-spear/spear1310.c new file mode 100644 index 000000000000..ed3b5c287a7b --- /dev/null +++ b/arch/arm/mach-spear/spear1310.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear13xx/spear1310.c | ||
3 | * | ||
4 | * SPEAr1310 machine source file | ||
5 | * | ||
6 | * Copyright (C) 2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "SPEAr1310: " fmt | ||
15 | |||
16 | #include <linux/amba/pl022.h> | ||
17 | #include <linux/irqchip.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <linux/pata_arasan_cf_data.h> | ||
20 | #include <asm/mach/arch.h> | ||
21 | #include <asm/mach/map.h> | ||
22 | #include "generic.h" | ||
23 | #include <mach/spear.h> | ||
24 | |||
25 | /* Base addresses */ | ||
26 | #define SPEAR1310_SSP1_BASE UL(0x5D400000) | ||
27 | #define SPEAR1310_SATA0_BASE UL(0xB1000000) | ||
28 | #define SPEAR1310_SATA1_BASE UL(0xB1800000) | ||
29 | #define SPEAR1310_SATA2_BASE UL(0xB4000000) | ||
30 | |||
31 | #define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000) | ||
32 | #define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000) | ||
33 | |||
34 | static struct arasan_cf_pdata cf_pdata = { | ||
35 | .cf_if_clk = CF_IF_CLK_166M, | ||
36 | .quirk = CF_BROKEN_UDMA, | ||
37 | .dma_priv = &cf_dma_priv, | ||
38 | }; | ||
39 | |||
40 | /* ssp device registration */ | ||
41 | static struct pl022_ssp_controller ssp1_plat_data = { | ||
42 | .enable_dma = 0, | ||
43 | }; | ||
44 | |||
45 | /* Add SPEAr1310 auxdata to pass platform data */ | ||
46 | static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = { | ||
47 | OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_pdata), | ||
48 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data), | ||
49 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data), | ||
50 | OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data), | ||
51 | |||
52 | OF_DEV_AUXDATA("arm,pl022", SPEAR1310_SSP1_BASE, NULL, &ssp1_plat_data), | ||
53 | {} | ||
54 | }; | ||
55 | |||
56 | static void __init spear1310_dt_init(void) | ||
57 | { | ||
58 | of_platform_populate(NULL, of_default_bus_match_table, | ||
59 | spear1310_auxdata_lookup, NULL); | ||
60 | } | ||
61 | |||
62 | static const char * const spear1310_dt_board_compat[] = { | ||
63 | "st,spear1310", | ||
64 | "st,spear1310-evb", | ||
65 | NULL, | ||
66 | }; | ||
67 | |||
68 | /* | ||
69 | * Following will create 16MB static virtual/physical mappings | ||
70 | * PHYSICAL VIRTUAL | ||
71 | * 0xD8000000 0xFA000000 | ||
72 | */ | ||
73 | struct map_desc spear1310_io_desc[] __initdata = { | ||
74 | { | ||
75 | .virtual = VA_SPEAR1310_RAS_GRP1_BASE, | ||
76 | .pfn = __phys_to_pfn(SPEAR1310_RAS_GRP1_BASE), | ||
77 | .length = SZ_16M, | ||
78 | .type = MT_DEVICE | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | static void __init spear1310_map_io(void) | ||
83 | { | ||
84 | iotable_init(spear1310_io_desc, ARRAY_SIZE(spear1310_io_desc)); | ||
85 | spear13xx_map_io(); | ||
86 | } | ||
87 | |||
88 | DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree") | ||
89 | .smp = smp_ops(spear13xx_smp_ops), | ||
90 | .map_io = spear1310_map_io, | ||
91 | .init_irq = irqchip_init, | ||
92 | .init_time = spear13xx_timer_init, | ||
93 | .init_machine = spear1310_dt_init, | ||
94 | .restart = spear_restart, | ||
95 | .dt_compat = spear1310_dt_board_compat, | ||
96 | MACHINE_END | ||
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c new file mode 100644 index 000000000000..75e38644bbfb --- /dev/null +++ b/arch/arm/mach-spear/spear1340.c | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear13xx/spear1340.c | ||
3 | * | ||
4 | * SPEAr1340 machine source file | ||
5 | * | ||
6 | * Copyright (C) 2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "SPEAr1340: " fmt | ||
15 | |||
16 | #include <linux/ahci_platform.h> | ||
17 | #include <linux/amba/serial.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/dw_dmac.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | #include <linux/irqchip.h> | ||
22 | #include <asm/mach/arch.h> | ||
23 | #include "generic.h" | ||
24 | #include <mach/spear.h> | ||
25 | |||
26 | #include "spear13xx-dma.h" | ||
27 | |||
28 | /* Base addresses */ | ||
29 | #define SPEAR1340_SATA_BASE UL(0xB1000000) | ||
30 | #define SPEAR1340_UART1_BASE UL(0xB4100000) | ||
31 | |||
32 | /* Power Management Registers */ | ||
33 | #define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100) | ||
34 | #define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104) | ||
35 | #define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108) | ||
36 | |||
37 | #define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318) | ||
38 | #define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C) | ||
39 | #define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320) | ||
40 | |||
41 | /* PCIE - SATA configuration registers */ | ||
42 | #define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424) | ||
43 | /* PCIE CFG MASks */ | ||
44 | #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11) | ||
45 | #define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10) | ||
46 | #define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9) | ||
47 | #define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8) | ||
48 | #define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4) | ||
49 | #define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3) | ||
50 | #define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2) | ||
51 | #define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1) | ||
52 | #define SPEAR1340_PCIE_SATA_SEL_PCIE (0) | ||
53 | #define SPEAR1340_PCIE_SATA_SEL_SATA (1) | ||
54 | #define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F | ||
55 | #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \ | ||
56 | SPEAR1340_PCIE_CFG_AUX_CLK_EN | \ | ||
57 | SPEAR1340_PCIE_CFG_CORE_CLK_EN | \ | ||
58 | SPEAR1340_PCIE_CFG_POWERUP_RESET | \ | ||
59 | SPEAR1340_PCIE_CFG_DEVICE_PRESENT) | ||
60 | #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \ | ||
61 | SPEAR1340_SATA_CFG_PM_CLK_EN | \ | ||
62 | SPEAR1340_SATA_CFG_POWERUP_RESET | \ | ||
63 | SPEAR1340_SATA_CFG_RX_CLK_EN | \ | ||
64 | SPEAR1340_SATA_CFG_TX_CLK_EN) | ||
65 | |||
66 | #define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428) | ||
67 | #define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31) | ||
68 | #define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27) | ||
69 | #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27) | ||
70 | #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27) | ||
71 | #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0) | ||
72 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \ | ||
73 | (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ | ||
74 | SPEAR1340_MIPHY_CLK_REF_DIV2 | \ | ||
75 | SPEAR1340_MIPHY_PLL_RATIO_TOP(60)) | ||
76 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \ | ||
77 | (SPEAR1340_MIPHY_PLL_RATIO_TOP(120)) | ||
78 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \ | ||
79 | (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ | ||
80 | SPEAR1340_MIPHY_PLL_RATIO_TOP(25)) | ||
81 | |||
82 | static struct dw_dma_slave uart1_dma_param[] = { | ||
83 | { | ||
84 | /* Tx */ | ||
85 | .cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX), | ||
86 | .cfg_lo = 0, | ||
87 | .src_master = DMA_MASTER_MEMORY, | ||
88 | .dst_master = SPEAR1340_DMA_MASTER_UART1, | ||
89 | }, { | ||
90 | /* Rx */ | ||
91 | .cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX), | ||
92 | .cfg_lo = 0, | ||
93 | .src_master = SPEAR1340_DMA_MASTER_UART1, | ||
94 | .dst_master = DMA_MASTER_MEMORY, | ||
95 | } | ||
96 | }; | ||
97 | |||
98 | static struct amba_pl011_data uart1_data = { | ||
99 | .dma_filter = dw_dma_filter, | ||
100 | .dma_tx_param = &uart1_dma_param[0], | ||
101 | .dma_rx_param = &uart1_dma_param[1], | ||
102 | }; | ||
103 | |||
104 | /* SATA device registration */ | ||
105 | static int sata_miphy_init(struct device *dev, void __iomem *addr) | ||
106 | { | ||
107 | writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG); | ||
108 | writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK, | ||
109 | SPEAR1340_PCIE_MIPHY_CFG); | ||
110 | /* Switch on sata power domain */ | ||
111 | writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG); | ||
112 | msleep(20); | ||
113 | /* Disable PCIE SATA Controller reset */ | ||
114 | writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)), | ||
115 | SPEAR1340_PERIP1_SW_RST); | ||
116 | msleep(20); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | void sata_miphy_exit(struct device *dev) | ||
122 | { | ||
123 | writel(0, SPEAR1340_PCIE_SATA_CFG); | ||
124 | writel(0, SPEAR1340_PCIE_MIPHY_CFG); | ||
125 | |||
126 | /* Enable PCIE SATA Controller reset */ | ||
127 | writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)), | ||
128 | SPEAR1340_PERIP1_SW_RST); | ||
129 | msleep(20); | ||
130 | /* Switch off sata power domain */ | ||
131 | writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG); | ||
132 | msleep(20); | ||
133 | } | ||
134 | |||
135 | int sata_suspend(struct device *dev) | ||
136 | { | ||
137 | if (dev->power.power_state.event == PM_EVENT_FREEZE) | ||
138 | return 0; | ||
139 | |||
140 | sata_miphy_exit(dev); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | int sata_resume(struct device *dev) | ||
146 | { | ||
147 | if (dev->power.power_state.event == PM_EVENT_THAW) | ||
148 | return 0; | ||
149 | |||
150 | return sata_miphy_init(dev, NULL); | ||
151 | } | ||
152 | |||
153 | static struct ahci_platform_data sata_pdata = { | ||
154 | .init = sata_miphy_init, | ||
155 | .exit = sata_miphy_exit, | ||
156 | .suspend = sata_suspend, | ||
157 | .resume = sata_resume, | ||
158 | }; | ||
159 | |||
160 | /* Add SPEAr1340 auxdata to pass platform data */ | ||
161 | static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = { | ||
162 | OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv), | ||
163 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data), | ||
164 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data), | ||
165 | OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data), | ||
166 | |||
167 | OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL, | ||
168 | &sata_pdata), | ||
169 | OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data), | ||
170 | {} | ||
171 | }; | ||
172 | |||
173 | static void __init spear1340_dt_init(void) | ||
174 | { | ||
175 | of_platform_populate(NULL, of_default_bus_match_table, | ||
176 | spear1340_auxdata_lookup, NULL); | ||
177 | } | ||
178 | |||
179 | static const char * const spear1340_dt_board_compat[] = { | ||
180 | "st,spear1340", | ||
181 | "st,spear1340-evb", | ||
182 | NULL, | ||
183 | }; | ||
184 | |||
185 | DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree") | ||
186 | .smp = smp_ops(spear13xx_smp_ops), | ||
187 | .map_io = spear13xx_map_io, | ||
188 | .init_irq = irqchip_init, | ||
189 | .init_time = spear13xx_timer_init, | ||
190 | .init_machine = spear1340_dt_init, | ||
191 | .restart = spear_restart, | ||
192 | .dt_compat = spear1340_dt_board_compat, | ||
193 | MACHINE_END | ||
diff --git a/arch/arm/mach-spear/spear13xx-dma.h b/arch/arm/mach-spear/spear13xx-dma.h new file mode 100644 index 000000000000..d50bdb605925 --- /dev/null +++ b/arch/arm/mach-spear/spear13xx-dma.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear13xx/include/mach/dma.h | ||
3 | * | ||
4 | * DMA information for SPEAr13xx machine family | ||
5 | * | ||
6 | * Copyright (C) 2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #ifndef __MACH_DMA_H | ||
15 | #define __MACH_DMA_H | ||
16 | |||
17 | /* request id of all the peripherals */ | ||
18 | enum dma_master_info { | ||
19 | /* Accessible from only one master */ | ||
20 | DMA_MASTER_MCIF = 0, | ||
21 | DMA_MASTER_FSMC = 1, | ||
22 | /* Accessible from both 0 & 1 */ | ||
23 | DMA_MASTER_MEMORY = 0, | ||
24 | DMA_MASTER_ADC = 0, | ||
25 | DMA_MASTER_UART0 = 0, | ||
26 | DMA_MASTER_SSP0 = 0, | ||
27 | DMA_MASTER_I2C0 = 0, | ||
28 | |||
29 | #ifdef CONFIG_MACH_SPEAR1310 | ||
30 | /* Accessible from only one master */ | ||
31 | SPEAR1310_DMA_MASTER_JPEG = 1, | ||
32 | |||
33 | /* Accessible from both 0 & 1 */ | ||
34 | SPEAR1310_DMA_MASTER_I2S = 0, | ||
35 | SPEAR1310_DMA_MASTER_UART1 = 0, | ||
36 | SPEAR1310_DMA_MASTER_UART2 = 0, | ||
37 | SPEAR1310_DMA_MASTER_UART3 = 0, | ||
38 | SPEAR1310_DMA_MASTER_UART4 = 0, | ||
39 | SPEAR1310_DMA_MASTER_UART5 = 0, | ||
40 | SPEAR1310_DMA_MASTER_I2C1 = 0, | ||
41 | SPEAR1310_DMA_MASTER_I2C2 = 0, | ||
42 | SPEAR1310_DMA_MASTER_I2C3 = 0, | ||
43 | SPEAR1310_DMA_MASTER_I2C4 = 0, | ||
44 | SPEAR1310_DMA_MASTER_I2C5 = 0, | ||
45 | SPEAR1310_DMA_MASTER_I2C6 = 0, | ||
46 | SPEAR1310_DMA_MASTER_I2C7 = 0, | ||
47 | SPEAR1310_DMA_MASTER_SSP1 = 0, | ||
48 | #endif | ||
49 | |||
50 | #ifdef CONFIG_MACH_SPEAR1340 | ||
51 | /* Accessible from only one master */ | ||
52 | SPEAR1340_DMA_MASTER_I2S_PLAY = 1, | ||
53 | SPEAR1340_DMA_MASTER_I2S_REC = 1, | ||
54 | SPEAR1340_DMA_MASTER_I2C1 = 1, | ||
55 | SPEAR1340_DMA_MASTER_UART1 = 1, | ||
56 | |||
57 | /* following are accessible from both master 0 & 1 */ | ||
58 | SPEAR1340_DMA_MASTER_SPDIF = 0, | ||
59 | SPEAR1340_DMA_MASTER_CAM = 1, | ||
60 | SPEAR1340_DMA_MASTER_VIDEO_IN = 0, | ||
61 | SPEAR1340_DMA_MASTER_MALI = 0, | ||
62 | #endif | ||
63 | }; | ||
64 | |||
65 | enum request_id { | ||
66 | DMA_REQ_ADC = 0, | ||
67 | DMA_REQ_SSP0_TX = 4, | ||
68 | DMA_REQ_SSP0_RX = 5, | ||
69 | DMA_REQ_UART0_TX = 6, | ||
70 | DMA_REQ_UART0_RX = 7, | ||
71 | DMA_REQ_I2C0_TX = 8, | ||
72 | DMA_REQ_I2C0_RX = 9, | ||
73 | |||
74 | #ifdef CONFIG_MACH_SPEAR1310 | ||
75 | SPEAR1310_DMA_REQ_FROM_JPEG = 2, | ||
76 | SPEAR1310_DMA_REQ_TO_JPEG = 3, | ||
77 | SPEAR1310_DMA_REQ_I2S_TX = 10, | ||
78 | SPEAR1310_DMA_REQ_I2S_RX = 11, | ||
79 | |||
80 | SPEAR1310_DMA_REQ_I2C1_RX = 0, | ||
81 | SPEAR1310_DMA_REQ_I2C1_TX = 1, | ||
82 | SPEAR1310_DMA_REQ_I2C2_RX = 2, | ||
83 | SPEAR1310_DMA_REQ_I2C2_TX = 3, | ||
84 | SPEAR1310_DMA_REQ_I2C3_RX = 4, | ||
85 | SPEAR1310_DMA_REQ_I2C3_TX = 5, | ||
86 | SPEAR1310_DMA_REQ_I2C4_RX = 6, | ||
87 | SPEAR1310_DMA_REQ_I2C4_TX = 7, | ||
88 | SPEAR1310_DMA_REQ_I2C5_RX = 8, | ||
89 | SPEAR1310_DMA_REQ_I2C5_TX = 9, | ||
90 | SPEAR1310_DMA_REQ_I2C6_RX = 10, | ||
91 | SPEAR1310_DMA_REQ_I2C6_TX = 11, | ||
92 | SPEAR1310_DMA_REQ_UART1_RX = 12, | ||
93 | SPEAR1310_DMA_REQ_UART1_TX = 13, | ||
94 | SPEAR1310_DMA_REQ_UART2_RX = 14, | ||
95 | SPEAR1310_DMA_REQ_UART2_TX = 15, | ||
96 | SPEAR1310_DMA_REQ_UART5_RX = 16, | ||
97 | SPEAR1310_DMA_REQ_UART5_TX = 17, | ||
98 | SPEAR1310_DMA_REQ_SSP1_RX = 18, | ||
99 | SPEAR1310_DMA_REQ_SSP1_TX = 19, | ||
100 | SPEAR1310_DMA_REQ_I2C7_RX = 20, | ||
101 | SPEAR1310_DMA_REQ_I2C7_TX = 21, | ||
102 | SPEAR1310_DMA_REQ_UART3_RX = 28, | ||
103 | SPEAR1310_DMA_REQ_UART3_TX = 29, | ||
104 | SPEAR1310_DMA_REQ_UART4_RX = 30, | ||
105 | SPEAR1310_DMA_REQ_UART4_TX = 31, | ||
106 | #endif | ||
107 | |||
108 | #ifdef CONFIG_MACH_SPEAR1340 | ||
109 | SPEAR1340_DMA_REQ_SPDIF_TX = 2, | ||
110 | SPEAR1340_DMA_REQ_SPDIF_RX = 3, | ||
111 | SPEAR1340_DMA_REQ_I2S_TX = 10, | ||
112 | SPEAR1340_DMA_REQ_I2S_RX = 11, | ||
113 | SPEAR1340_DMA_REQ_UART1_TX = 12, | ||
114 | SPEAR1340_DMA_REQ_UART1_RX = 13, | ||
115 | SPEAR1340_DMA_REQ_I2C1_TX = 14, | ||
116 | SPEAR1340_DMA_REQ_I2C1_RX = 15, | ||
117 | SPEAR1340_DMA_REQ_CAM0_EVEN = 0, | ||
118 | SPEAR1340_DMA_REQ_CAM0_ODD = 1, | ||
119 | SPEAR1340_DMA_REQ_CAM1_EVEN = 2, | ||
120 | SPEAR1340_DMA_REQ_CAM1_ODD = 3, | ||
121 | SPEAR1340_DMA_REQ_CAM2_EVEN = 4, | ||
122 | SPEAR1340_DMA_REQ_CAM2_ODD = 5, | ||
123 | SPEAR1340_DMA_REQ_CAM3_EVEN = 6, | ||
124 | SPEAR1340_DMA_REQ_CAM3_ODD = 7, | ||
125 | #endif | ||
126 | }; | ||
127 | |||
128 | #endif /* __MACH_DMA_H */ | ||
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c new file mode 100644 index 000000000000..1b97e8623472 --- /dev/null +++ b/arch/arm/mach-spear/spear13xx.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear13xx/spear13xx.c | ||
3 | * | ||
4 | * SPEAr13XX machines common source file | ||
5 | * | ||
6 | * Copyright (C) 2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "SPEAr13xx: " fmt | ||
15 | |||
16 | #include <linux/amba/pl022.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/dw_dmac.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <asm/hardware/cache-l2x0.h> | ||
22 | #include <asm/mach/map.h> | ||
23 | #include <asm/smp_twd.h> | ||
24 | #include "generic.h" | ||
25 | #include <mach/spear.h> | ||
26 | |||
27 | #include "spear13xx-dma.h" | ||
28 | |||
29 | /* common dw_dma filter routine to be used by peripherals */ | ||
30 | bool dw_dma_filter(struct dma_chan *chan, void *slave) | ||
31 | { | ||
32 | struct dw_dma_slave *dws = (struct dw_dma_slave *)slave; | ||
33 | |||
34 | if (chan->device->dev == dws->dma_dev) { | ||
35 | chan->private = slave; | ||
36 | return true; | ||
37 | } else { | ||
38 | return false; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | /* ssp device registration */ | ||
43 | static struct dw_dma_slave ssp_dma_param[] = { | ||
44 | { | ||
45 | /* Tx */ | ||
46 | .cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX), | ||
47 | .cfg_lo = 0, | ||
48 | .src_master = DMA_MASTER_MEMORY, | ||
49 | .dst_master = DMA_MASTER_SSP0, | ||
50 | }, { | ||
51 | /* Rx */ | ||
52 | .cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX), | ||
53 | .cfg_lo = 0, | ||
54 | .src_master = DMA_MASTER_SSP0, | ||
55 | .dst_master = DMA_MASTER_MEMORY, | ||
56 | } | ||
57 | }; | ||
58 | |||
59 | struct pl022_ssp_controller pl022_plat_data = { | ||
60 | .enable_dma = 1, | ||
61 | .dma_filter = dw_dma_filter, | ||
62 | .dma_rx_param = &ssp_dma_param[1], | ||
63 | .dma_tx_param = &ssp_dma_param[0], | ||
64 | }; | ||
65 | |||
66 | /* CF device registration */ | ||
67 | struct dw_dma_slave cf_dma_priv = { | ||
68 | .cfg_hi = 0, | ||
69 | .cfg_lo = 0, | ||
70 | .src_master = 0, | ||
71 | .dst_master = 0, | ||
72 | }; | ||
73 | |||
74 | /* dmac device registeration */ | ||
75 | struct dw_dma_platform_data dmac_plat_data = { | ||
76 | .nr_channels = 8, | ||
77 | .chan_allocation_order = CHAN_ALLOCATION_DESCENDING, | ||
78 | .chan_priority = CHAN_PRIORITY_DESCENDING, | ||
79 | .block_size = 4095U, | ||
80 | .nr_masters = 2, | ||
81 | .data_width = { 3, 3, 0, 0 }, | ||
82 | }; | ||
83 | |||
84 | void __init spear13xx_l2x0_init(void) | ||
85 | { | ||
86 | /* | ||
87 | * 512KB (64KB/way), 8-way associativity, parity supported | ||
88 | * | ||
89 | * FIXME: 9th bit, of Auxillary Controller register must be set | ||
90 | * for some spear13xx devices for stable L2 operation. | ||
91 | * | ||
92 | * Enable Early BRESP, L2 prefetch for Instruction and Data, | ||
93 | * write alloc and 'Full line of zero' options | ||
94 | * | ||
95 | */ | ||
96 | |||
97 | writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL); | ||
98 | |||
99 | /* | ||
100 | * Program following latencies in order to make | ||
101 | * SPEAr1340 work at 600 MHz | ||
102 | */ | ||
103 | writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL); | ||
104 | writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL); | ||
105 | l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Following will create 16MB static virtual/physical mappings | ||
110 | * PHYSICAL VIRTUAL | ||
111 | * 0xB3000000 0xFE000000 | ||
112 | * 0xE0000000 0xFD000000 | ||
113 | * 0xEC000000 0xFC000000 | ||
114 | * 0xED000000 0xFB000000 | ||
115 | */ | ||
116 | struct map_desc spear13xx_io_desc[] __initdata = { | ||
117 | { | ||
118 | .virtual = (unsigned long)VA_PERIP_GRP2_BASE, | ||
119 | .pfn = __phys_to_pfn(PERIP_GRP2_BASE), | ||
120 | .length = SZ_16M, | ||
121 | .type = MT_DEVICE | ||
122 | }, { | ||
123 | .virtual = (unsigned long)VA_PERIP_GRP1_BASE, | ||
124 | .pfn = __phys_to_pfn(PERIP_GRP1_BASE), | ||
125 | .length = SZ_16M, | ||
126 | .type = MT_DEVICE | ||
127 | }, { | ||
128 | .virtual = (unsigned long)VA_A9SM_AND_MPMC_BASE, | ||
129 | .pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE), | ||
130 | .length = SZ_16M, | ||
131 | .type = MT_DEVICE | ||
132 | }, { | ||
133 | .virtual = (unsigned long)VA_L2CC_BASE, | ||
134 | .pfn = __phys_to_pfn(L2CC_BASE), | ||
135 | .length = SZ_4K, | ||
136 | .type = MT_DEVICE | ||
137 | }, | ||
138 | }; | ||
139 | |||
140 | /* This will create static memory mapping for selected devices */ | ||
141 | void __init spear13xx_map_io(void) | ||
142 | { | ||
143 | iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc)); | ||
144 | } | ||
145 | |||
146 | static void __init spear13xx_clk_init(void) | ||
147 | { | ||
148 | if (of_machine_is_compatible("st,spear1310")) | ||
149 | spear1310_clk_init(VA_MISC_BASE, VA_SPEAR1310_RAS_BASE); | ||
150 | else if (of_machine_is_compatible("st,spear1340")) | ||
151 | spear1340_clk_init(VA_MISC_BASE); | ||
152 | else | ||
153 | pr_err("%s: Unknown machine\n", __func__); | ||
154 | } | ||
155 | |||
156 | void __init spear13xx_timer_init(void) | ||
157 | { | ||
158 | char pclk_name[] = "osc_24m_clk"; | ||
159 | struct clk *gpt_clk, *pclk; | ||
160 | |||
161 | spear13xx_clk_init(); | ||
162 | |||
163 | /* get the system timer clock */ | ||
164 | gpt_clk = clk_get_sys("gpt0", NULL); | ||
165 | if (IS_ERR(gpt_clk)) { | ||
166 | pr_err("%s:couldn't get clk for gpt\n", __func__); | ||
167 | BUG(); | ||
168 | } | ||
169 | |||
170 | /* get the suitable parent clock for timer*/ | ||
171 | pclk = clk_get(NULL, pclk_name); | ||
172 | if (IS_ERR(pclk)) { | ||
173 | pr_err("%s:couldn't get %s as parent for gpt\n", __func__, | ||
174 | pclk_name); | ||
175 | BUG(); | ||
176 | } | ||
177 | |||
178 | clk_set_parent(gpt_clk, pclk); | ||
179 | clk_put(gpt_clk); | ||
180 | clk_put(pclk); | ||
181 | |||
182 | spear_setup_of_timer(); | ||
183 | twd_local_timer_of_register(); | ||
184 | } | ||
diff --git a/arch/arm/mach-spear/spear300.c b/arch/arm/mach-spear/spear300.c new file mode 100644 index 000000000000..bac56e845f7a --- /dev/null +++ b/arch/arm/mach-spear/spear300.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear3xx/spear300.c | ||
3 | * | ||
4 | * SPEAr300 machine source file | ||
5 | * | ||
6 | * Copyright (C) 2009-2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "SPEAr300: " fmt | ||
15 | |||
16 | #include <linux/amba/pl08x.h> | ||
17 | #include <linux/irqchip.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <asm/mach/arch.h> | ||
20 | #include "generic.h" | ||
21 | #include <mach/spear.h> | ||
22 | |||
23 | /* DMAC platform data's slave info */ | ||
24 | struct pl08x_channel_data spear300_dma_info[] = { | ||
25 | { | ||
26 | .bus_id = "uart0_rx", | ||
27 | .min_signal = 2, | ||
28 | .max_signal = 2, | ||
29 | .muxval = 0, | ||
30 | .periph_buses = PL08X_AHB1, | ||
31 | }, { | ||
32 | .bus_id = "uart0_tx", | ||
33 | .min_signal = 3, | ||
34 | .max_signal = 3, | ||
35 | .muxval = 0, | ||
36 | .periph_buses = PL08X_AHB1, | ||
37 | }, { | ||
38 | .bus_id = "ssp0_rx", | ||
39 | .min_signal = 8, | ||
40 | .max_signal = 8, | ||
41 | .muxval = 0, | ||
42 | .periph_buses = PL08X_AHB1, | ||
43 | }, { | ||
44 | .bus_id = "ssp0_tx", | ||
45 | .min_signal = 9, | ||
46 | .max_signal = 9, | ||
47 | .muxval = 0, | ||
48 | .periph_buses = PL08X_AHB1, | ||
49 | }, { | ||
50 | .bus_id = "i2c_rx", | ||
51 | .min_signal = 10, | ||
52 | .max_signal = 10, | ||
53 | .muxval = 0, | ||
54 | .periph_buses = PL08X_AHB1, | ||
55 | }, { | ||
56 | .bus_id = "i2c_tx", | ||
57 | .min_signal = 11, | ||
58 | .max_signal = 11, | ||
59 | .muxval = 0, | ||
60 | .periph_buses = PL08X_AHB1, | ||
61 | }, { | ||
62 | .bus_id = "irda", | ||
63 | .min_signal = 12, | ||
64 | .max_signal = 12, | ||
65 | .muxval = 0, | ||
66 | .periph_buses = PL08X_AHB1, | ||
67 | }, { | ||
68 | .bus_id = "adc", | ||
69 | .min_signal = 13, | ||
70 | .max_signal = 13, | ||
71 | .muxval = 0, | ||
72 | .periph_buses = PL08X_AHB1, | ||
73 | }, { | ||
74 | .bus_id = "to_jpeg", | ||
75 | .min_signal = 14, | ||
76 | .max_signal = 14, | ||
77 | .muxval = 0, | ||
78 | .periph_buses = PL08X_AHB1, | ||
79 | }, { | ||
80 | .bus_id = "from_jpeg", | ||
81 | .min_signal = 15, | ||
82 | .max_signal = 15, | ||
83 | .muxval = 0, | ||
84 | .periph_buses = PL08X_AHB1, | ||
85 | }, { | ||
86 | .bus_id = "ras0_rx", | ||
87 | .min_signal = 0, | ||
88 | .max_signal = 0, | ||
89 | .muxval = 1, | ||
90 | .periph_buses = PL08X_AHB1, | ||
91 | }, { | ||
92 | .bus_id = "ras0_tx", | ||
93 | .min_signal = 1, | ||
94 | .max_signal = 1, | ||
95 | .muxval = 1, | ||
96 | .periph_buses = PL08X_AHB1, | ||
97 | }, { | ||
98 | .bus_id = "ras1_rx", | ||
99 | .min_signal = 2, | ||
100 | .max_signal = 2, | ||
101 | .muxval = 1, | ||
102 | .periph_buses = PL08X_AHB1, | ||
103 | }, { | ||
104 | .bus_id = "ras1_tx", | ||
105 | .min_signal = 3, | ||
106 | .max_signal = 3, | ||
107 | .muxval = 1, | ||
108 | .periph_buses = PL08X_AHB1, | ||
109 | }, { | ||
110 | .bus_id = "ras2_rx", | ||
111 | .min_signal = 4, | ||
112 | .max_signal = 4, | ||
113 | .muxval = 1, | ||
114 | .periph_buses = PL08X_AHB1, | ||
115 | }, { | ||
116 | .bus_id = "ras2_tx", | ||
117 | .min_signal = 5, | ||
118 | .max_signal = 5, | ||
119 | .muxval = 1, | ||
120 | .periph_buses = PL08X_AHB1, | ||
121 | }, { | ||
122 | .bus_id = "ras3_rx", | ||
123 | .min_signal = 6, | ||
124 | .max_signal = 6, | ||
125 | .muxval = 1, | ||
126 | .periph_buses = PL08X_AHB1, | ||
127 | }, { | ||
128 | .bus_id = "ras3_tx", | ||
129 | .min_signal = 7, | ||
130 | .max_signal = 7, | ||
131 | .muxval = 1, | ||
132 | .periph_buses = PL08X_AHB1, | ||
133 | }, { | ||
134 | .bus_id = "ras4_rx", | ||
135 | .min_signal = 8, | ||
136 | .max_signal = 8, | ||
137 | .muxval = 1, | ||
138 | .periph_buses = PL08X_AHB1, | ||
139 | }, { | ||
140 | .bus_id = "ras4_tx", | ||
141 | .min_signal = 9, | ||
142 | .max_signal = 9, | ||
143 | .muxval = 1, | ||
144 | .periph_buses = PL08X_AHB1, | ||
145 | }, { | ||
146 | .bus_id = "ras5_rx", | ||
147 | .min_signal = 10, | ||
148 | .max_signal = 10, | ||
149 | .muxval = 1, | ||
150 | .periph_buses = PL08X_AHB1, | ||
151 | }, { | ||
152 | .bus_id = "ras5_tx", | ||
153 | .min_signal = 11, | ||
154 | .max_signal = 11, | ||
155 | .muxval = 1, | ||
156 | .periph_buses = PL08X_AHB1, | ||
157 | }, { | ||
158 | .bus_id = "ras6_rx", | ||
159 | .min_signal = 12, | ||
160 | .max_signal = 12, | ||
161 | .muxval = 1, | ||
162 | .periph_buses = PL08X_AHB1, | ||
163 | }, { | ||
164 | .bus_id = "ras6_tx", | ||
165 | .min_signal = 13, | ||
166 | .max_signal = 13, | ||
167 | .muxval = 1, | ||
168 | .periph_buses = PL08X_AHB1, | ||
169 | }, { | ||
170 | .bus_id = "ras7_rx", | ||
171 | .min_signal = 14, | ||
172 | .max_signal = 14, | ||
173 | .muxval = 1, | ||
174 | .periph_buses = PL08X_AHB1, | ||
175 | }, { | ||
176 | .bus_id = "ras7_tx", | ||
177 | .min_signal = 15, | ||
178 | .max_signal = 15, | ||
179 | .muxval = 1, | ||
180 | .periph_buses = PL08X_AHB1, | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | /* Add SPEAr300 auxdata to pass platform data */ | ||
185 | static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = { | ||
186 | OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL, | ||
187 | &pl022_plat_data), | ||
188 | OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL, | ||
189 | &pl080_plat_data), | ||
190 | {} | ||
191 | }; | ||
192 | |||
193 | static void __init spear300_dt_init(void) | ||
194 | { | ||
195 | pl080_plat_data.slave_channels = spear300_dma_info; | ||
196 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info); | ||
197 | |||
198 | of_platform_populate(NULL, of_default_bus_match_table, | ||
199 | spear300_auxdata_lookup, NULL); | ||
200 | } | ||
201 | |||
202 | static const char * const spear300_dt_board_compat[] = { | ||
203 | "st,spear300", | ||
204 | "st,spear300-evb", | ||
205 | NULL, | ||
206 | }; | ||
207 | |||
208 | static void __init spear300_map_io(void) | ||
209 | { | ||
210 | spear3xx_map_io(); | ||
211 | } | ||
212 | |||
213 | DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree") | ||
214 | .map_io = spear300_map_io, | ||
215 | .init_irq = irqchip_init, | ||
216 | .init_time = spear3xx_timer_init, | ||
217 | .init_machine = spear300_dt_init, | ||
218 | .restart = spear_restart, | ||
219 | .dt_compat = spear300_dt_board_compat, | ||
220 | MACHINE_END | ||
diff --git a/arch/arm/mach-spear/spear310.c b/arch/arm/mach-spear/spear310.c new file mode 100644 index 000000000000..6ffbc63d516d --- /dev/null +++ b/arch/arm/mach-spear/spear310.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear3xx/spear310.c | ||
3 | * | ||
4 | * SPEAr310 machine source file | ||
5 | * | ||
6 | * Copyright (C) 2009-2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "SPEAr310: " fmt | ||
15 | |||
16 | #include <linux/amba/pl08x.h> | ||
17 | #include <linux/amba/serial.h> | ||
18 | #include <linux/irqchip.h> | ||
19 | #include <linux/of_platform.h> | ||
20 | #include <asm/mach/arch.h> | ||
21 | #include "generic.h" | ||
22 | #include <mach/spear.h> | ||
23 | |||
24 | #define SPEAR310_UART1_BASE UL(0xB2000000) | ||
25 | #define SPEAR310_UART2_BASE UL(0xB2080000) | ||
26 | #define SPEAR310_UART3_BASE UL(0xB2100000) | ||
27 | #define SPEAR310_UART4_BASE UL(0xB2180000) | ||
28 | #define SPEAR310_UART5_BASE UL(0xB2200000) | ||
29 | |||
30 | /* DMAC platform data's slave info */ | ||
31 | struct pl08x_channel_data spear310_dma_info[] = { | ||
32 | { | ||
33 | .bus_id = "uart0_rx", | ||
34 | .min_signal = 2, | ||
35 | .max_signal = 2, | ||
36 | .muxval = 0, | ||
37 | .periph_buses = PL08X_AHB1, | ||
38 | }, { | ||
39 | .bus_id = "uart0_tx", | ||
40 | .min_signal = 3, | ||
41 | .max_signal = 3, | ||
42 | .muxval = 0, | ||
43 | .periph_buses = PL08X_AHB1, | ||
44 | }, { | ||
45 | .bus_id = "ssp0_rx", | ||
46 | .min_signal = 8, | ||
47 | .max_signal = 8, | ||
48 | .muxval = 0, | ||
49 | .periph_buses = PL08X_AHB1, | ||
50 | }, { | ||
51 | .bus_id = "ssp0_tx", | ||
52 | .min_signal = 9, | ||
53 | .max_signal = 9, | ||
54 | .muxval = 0, | ||
55 | .periph_buses = PL08X_AHB1, | ||
56 | }, { | ||
57 | .bus_id = "i2c_rx", | ||
58 | .min_signal = 10, | ||
59 | .max_signal = 10, | ||
60 | .muxval = 0, | ||
61 | .periph_buses = PL08X_AHB1, | ||
62 | }, { | ||
63 | .bus_id = "i2c_tx", | ||
64 | .min_signal = 11, | ||
65 | .max_signal = 11, | ||
66 | .muxval = 0, | ||
67 | .periph_buses = PL08X_AHB1, | ||
68 | }, { | ||
69 | .bus_id = "irda", | ||
70 | .min_signal = 12, | ||
71 | .max_signal = 12, | ||
72 | .muxval = 0, | ||
73 | .periph_buses = PL08X_AHB1, | ||
74 | }, { | ||
75 | .bus_id = "adc", | ||
76 | .min_signal = 13, | ||
77 | .max_signal = 13, | ||
78 | .muxval = 0, | ||
79 | .periph_buses = PL08X_AHB1, | ||
80 | }, { | ||
81 | .bus_id = "to_jpeg", | ||
82 | .min_signal = 14, | ||
83 | .max_signal = 14, | ||
84 | .muxval = 0, | ||
85 | .periph_buses = PL08X_AHB1, | ||
86 | }, { | ||
87 | .bus_id = "from_jpeg", | ||
88 | .min_signal = 15, | ||
89 | .max_signal = 15, | ||
90 | .muxval = 0, | ||
91 | .periph_buses = PL08X_AHB1, | ||
92 | }, { | ||
93 | .bus_id = "uart1_rx", | ||
94 | .min_signal = 0, | ||
95 | .max_signal = 0, | ||
96 | .muxval = 1, | ||
97 | .periph_buses = PL08X_AHB1, | ||
98 | }, { | ||
99 | .bus_id = "uart1_tx", | ||
100 | .min_signal = 1, | ||
101 | .max_signal = 1, | ||
102 | .muxval = 1, | ||
103 | .periph_buses = PL08X_AHB1, | ||
104 | }, { | ||
105 | .bus_id = "uart2_rx", | ||
106 | .min_signal = 2, | ||
107 | .max_signal = 2, | ||
108 | .muxval = 1, | ||
109 | .periph_buses = PL08X_AHB1, | ||
110 | }, { | ||
111 | .bus_id = "uart2_tx", | ||
112 | .min_signal = 3, | ||
113 | .max_signal = 3, | ||
114 | .muxval = 1, | ||
115 | .periph_buses = PL08X_AHB1, | ||
116 | }, { | ||
117 | .bus_id = "uart3_rx", | ||
118 | .min_signal = 4, | ||
119 | .max_signal = 4, | ||
120 | .muxval = 1, | ||
121 | .periph_buses = PL08X_AHB1, | ||
122 | }, { | ||
123 | .bus_id = "uart3_tx", | ||
124 | .min_signal = 5, | ||
125 | .max_signal = 5, | ||
126 | .muxval = 1, | ||
127 | .periph_buses = PL08X_AHB1, | ||
128 | }, { | ||
129 | .bus_id = "uart4_rx", | ||
130 | .min_signal = 6, | ||
131 | .max_signal = 6, | ||
132 | .muxval = 1, | ||
133 | .periph_buses = PL08X_AHB1, | ||
134 | }, { | ||
135 | .bus_id = "uart4_tx", | ||
136 | .min_signal = 7, | ||
137 | .max_signal = 7, | ||
138 | .muxval = 1, | ||
139 | .periph_buses = PL08X_AHB1, | ||
140 | }, { | ||
141 | .bus_id = "uart5_rx", | ||
142 | .min_signal = 8, | ||
143 | .max_signal = 8, | ||
144 | .muxval = 1, | ||
145 | .periph_buses = PL08X_AHB1, | ||
146 | }, { | ||
147 | .bus_id = "uart5_tx", | ||
148 | .min_signal = 9, | ||
149 | .max_signal = 9, | ||
150 | .muxval = 1, | ||
151 | .periph_buses = PL08X_AHB1, | ||
152 | }, { | ||
153 | .bus_id = "ras5_rx", | ||
154 | .min_signal = 10, | ||
155 | .max_signal = 10, | ||
156 | .muxval = 1, | ||
157 | .periph_buses = PL08X_AHB1, | ||
158 | }, { | ||
159 | .bus_id = "ras5_tx", | ||
160 | .min_signal = 11, | ||
161 | .max_signal = 11, | ||
162 | .muxval = 1, | ||
163 | .periph_buses = PL08X_AHB1, | ||
164 | }, { | ||
165 | .bus_id = "ras6_rx", | ||
166 | .min_signal = 12, | ||
167 | .max_signal = 12, | ||
168 | .muxval = 1, | ||
169 | .periph_buses = PL08X_AHB1, | ||
170 | }, { | ||
171 | .bus_id = "ras6_tx", | ||
172 | .min_signal = 13, | ||
173 | .max_signal = 13, | ||
174 | .muxval = 1, | ||
175 | .periph_buses = PL08X_AHB1, | ||
176 | }, { | ||
177 | .bus_id = "ras7_rx", | ||
178 | .min_signal = 14, | ||
179 | .max_signal = 14, | ||
180 | .muxval = 1, | ||
181 | .periph_buses = PL08X_AHB1, | ||
182 | }, { | ||
183 | .bus_id = "ras7_tx", | ||
184 | .min_signal = 15, | ||
185 | .max_signal = 15, | ||
186 | .muxval = 1, | ||
187 | .periph_buses = PL08X_AHB1, | ||
188 | }, | ||
189 | }; | ||
190 | |||
191 | /* uart devices plat data */ | ||
192 | static struct amba_pl011_data spear310_uart_data[] = { | ||
193 | { | ||
194 | .dma_filter = pl08x_filter_id, | ||
195 | .dma_tx_param = "uart1_tx", | ||
196 | .dma_rx_param = "uart1_rx", | ||
197 | }, { | ||
198 | .dma_filter = pl08x_filter_id, | ||
199 | .dma_tx_param = "uart2_tx", | ||
200 | .dma_rx_param = "uart2_rx", | ||
201 | }, { | ||
202 | .dma_filter = pl08x_filter_id, | ||
203 | .dma_tx_param = "uart3_tx", | ||
204 | .dma_rx_param = "uart3_rx", | ||
205 | }, { | ||
206 | .dma_filter = pl08x_filter_id, | ||
207 | .dma_tx_param = "uart4_tx", | ||
208 | .dma_rx_param = "uart4_rx", | ||
209 | }, { | ||
210 | .dma_filter = pl08x_filter_id, | ||
211 | .dma_tx_param = "uart5_tx", | ||
212 | .dma_rx_param = "uart5_rx", | ||
213 | }, | ||
214 | }; | ||
215 | |||
216 | /* Add SPEAr310 auxdata to pass platform data */ | ||
217 | static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = { | ||
218 | OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL, | ||
219 | &pl022_plat_data), | ||
220 | OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL, | ||
221 | &pl080_plat_data), | ||
222 | OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART1_BASE, NULL, | ||
223 | &spear310_uart_data[0]), | ||
224 | OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART2_BASE, NULL, | ||
225 | &spear310_uart_data[1]), | ||
226 | OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART3_BASE, NULL, | ||
227 | &spear310_uart_data[2]), | ||
228 | OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART4_BASE, NULL, | ||
229 | &spear310_uart_data[3]), | ||
230 | OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART5_BASE, NULL, | ||
231 | &spear310_uart_data[4]), | ||
232 | {} | ||
233 | }; | ||
234 | |||
235 | static void __init spear310_dt_init(void) | ||
236 | { | ||
237 | pl080_plat_data.slave_channels = spear310_dma_info; | ||
238 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info); | ||
239 | |||
240 | of_platform_populate(NULL, of_default_bus_match_table, | ||
241 | spear310_auxdata_lookup, NULL); | ||
242 | } | ||
243 | |||
244 | static const char * const spear310_dt_board_compat[] = { | ||
245 | "st,spear310", | ||
246 | "st,spear310-evb", | ||
247 | NULL, | ||
248 | }; | ||
249 | |||
250 | static void __init spear310_map_io(void) | ||
251 | { | ||
252 | spear3xx_map_io(); | ||
253 | } | ||
254 | |||
255 | DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree") | ||
256 | .map_io = spear310_map_io, | ||
257 | .init_irq = irqchip_init, | ||
258 | .init_time = spear3xx_timer_init, | ||
259 | .init_machine = spear310_dt_init, | ||
260 | .restart = spear_restart, | ||
261 | .dt_compat = spear310_dt_board_compat, | ||
262 | MACHINE_END | ||
diff --git a/arch/arm/mach-spear/spear320.c b/arch/arm/mach-spear/spear320.c new file mode 100644 index 000000000000..6eb3eec65f96 --- /dev/null +++ b/arch/arm/mach-spear/spear320.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear3xx/spear320.c | ||
3 | * | ||
4 | * SPEAr320 machine source file | ||
5 | * | ||
6 | * Copyright (C) 2009-2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "SPEAr320: " fmt | ||
15 | |||
16 | #include <linux/amba/pl022.h> | ||
17 | #include <linux/amba/pl08x.h> | ||
18 | #include <linux/amba/serial.h> | ||
19 | #include <linux/irqchip.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | #include <asm/mach/arch.h> | ||
22 | #include <asm/mach/map.h> | ||
23 | #include "generic.h" | ||
24 | #include <mach/spear.h> | ||
25 | |||
26 | #define SPEAR320_UART1_BASE UL(0xA3000000) | ||
27 | #define SPEAR320_UART2_BASE UL(0xA4000000) | ||
28 | #define SPEAR320_SSP0_BASE UL(0xA5000000) | ||
29 | #define SPEAR320_SSP1_BASE UL(0xA6000000) | ||
30 | |||
31 | /* DMAC platform data's slave info */ | ||
32 | struct pl08x_channel_data spear320_dma_info[] = { | ||
33 | { | ||
34 | .bus_id = "uart0_rx", | ||
35 | .min_signal = 2, | ||
36 | .max_signal = 2, | ||
37 | .muxval = 0, | ||
38 | .periph_buses = PL08X_AHB1, | ||
39 | }, { | ||
40 | .bus_id = "uart0_tx", | ||
41 | .min_signal = 3, | ||
42 | .max_signal = 3, | ||
43 | .muxval = 0, | ||
44 | .periph_buses = PL08X_AHB1, | ||
45 | }, { | ||
46 | .bus_id = "ssp0_rx", | ||
47 | .min_signal = 8, | ||
48 | .max_signal = 8, | ||
49 | .muxval = 0, | ||
50 | .periph_buses = PL08X_AHB1, | ||
51 | }, { | ||
52 | .bus_id = "ssp0_tx", | ||
53 | .min_signal = 9, | ||
54 | .max_signal = 9, | ||
55 | .muxval = 0, | ||
56 | .periph_buses = PL08X_AHB1, | ||
57 | }, { | ||
58 | .bus_id = "i2c0_rx", | ||
59 | .min_signal = 10, | ||
60 | .max_signal = 10, | ||
61 | .muxval = 0, | ||
62 | .periph_buses = PL08X_AHB1, | ||
63 | }, { | ||
64 | .bus_id = "i2c0_tx", | ||
65 | .min_signal = 11, | ||
66 | .max_signal = 11, | ||
67 | .muxval = 0, | ||
68 | .periph_buses = PL08X_AHB1, | ||
69 | }, { | ||
70 | .bus_id = "irda", | ||
71 | .min_signal = 12, | ||
72 | .max_signal = 12, | ||
73 | .muxval = 0, | ||
74 | .periph_buses = PL08X_AHB1, | ||
75 | }, { | ||
76 | .bus_id = "adc", | ||
77 | .min_signal = 13, | ||
78 | .max_signal = 13, | ||
79 | .muxval = 0, | ||
80 | .periph_buses = PL08X_AHB1, | ||
81 | }, { | ||
82 | .bus_id = "to_jpeg", | ||
83 | .min_signal = 14, | ||
84 | .max_signal = 14, | ||
85 | .muxval = 0, | ||
86 | .periph_buses = PL08X_AHB1, | ||
87 | }, { | ||
88 | .bus_id = "from_jpeg", | ||
89 | .min_signal = 15, | ||
90 | .max_signal = 15, | ||
91 | .muxval = 0, | ||
92 | .periph_buses = PL08X_AHB1, | ||
93 | }, { | ||
94 | .bus_id = "ssp1_rx", | ||
95 | .min_signal = 0, | ||
96 | .max_signal = 0, | ||
97 | .muxval = 1, | ||
98 | .periph_buses = PL08X_AHB2, | ||
99 | }, { | ||
100 | .bus_id = "ssp1_tx", | ||
101 | .min_signal = 1, | ||
102 | .max_signal = 1, | ||
103 | .muxval = 1, | ||
104 | .periph_buses = PL08X_AHB2, | ||
105 | }, { | ||
106 | .bus_id = "ssp2_rx", | ||
107 | .min_signal = 2, | ||
108 | .max_signal = 2, | ||
109 | .muxval = 1, | ||
110 | .periph_buses = PL08X_AHB2, | ||
111 | }, { | ||
112 | .bus_id = "ssp2_tx", | ||
113 | .min_signal = 3, | ||
114 | .max_signal = 3, | ||
115 | .muxval = 1, | ||
116 | .periph_buses = PL08X_AHB2, | ||
117 | }, { | ||
118 | .bus_id = "uart1_rx", | ||
119 | .min_signal = 4, | ||
120 | .max_signal = 4, | ||
121 | .muxval = 1, | ||
122 | .periph_buses = PL08X_AHB2, | ||
123 | }, { | ||
124 | .bus_id = "uart1_tx", | ||
125 | .min_signal = 5, | ||
126 | .max_signal = 5, | ||
127 | .muxval = 1, | ||
128 | .periph_buses = PL08X_AHB2, | ||
129 | }, { | ||
130 | .bus_id = "uart2_rx", | ||
131 | .min_signal = 6, | ||
132 | .max_signal = 6, | ||
133 | .muxval = 1, | ||
134 | .periph_buses = PL08X_AHB2, | ||
135 | }, { | ||
136 | .bus_id = "uart2_tx", | ||
137 | .min_signal = 7, | ||
138 | .max_signal = 7, | ||
139 | .muxval = 1, | ||
140 | .periph_buses = PL08X_AHB2, | ||
141 | }, { | ||
142 | .bus_id = "i2c1_rx", | ||
143 | .min_signal = 8, | ||
144 | .max_signal = 8, | ||
145 | .muxval = 1, | ||
146 | .periph_buses = PL08X_AHB2, | ||
147 | }, { | ||
148 | .bus_id = "i2c1_tx", | ||
149 | .min_signal = 9, | ||
150 | .max_signal = 9, | ||
151 | .muxval = 1, | ||
152 | .periph_buses = PL08X_AHB2, | ||
153 | }, { | ||
154 | .bus_id = "i2c2_rx", | ||
155 | .min_signal = 10, | ||
156 | .max_signal = 10, | ||
157 | .muxval = 1, | ||
158 | .periph_buses = PL08X_AHB2, | ||
159 | }, { | ||
160 | .bus_id = "i2c2_tx", | ||
161 | .min_signal = 11, | ||
162 | .max_signal = 11, | ||
163 | .muxval = 1, | ||
164 | .periph_buses = PL08X_AHB2, | ||
165 | }, { | ||
166 | .bus_id = "i2s_rx", | ||
167 | .min_signal = 12, | ||
168 | .max_signal = 12, | ||
169 | .muxval = 1, | ||
170 | .periph_buses = PL08X_AHB2, | ||
171 | }, { | ||
172 | .bus_id = "i2s_tx", | ||
173 | .min_signal = 13, | ||
174 | .max_signal = 13, | ||
175 | .muxval = 1, | ||
176 | .periph_buses = PL08X_AHB2, | ||
177 | }, { | ||
178 | .bus_id = "rs485_rx", | ||
179 | .min_signal = 14, | ||
180 | .max_signal = 14, | ||
181 | .muxval = 1, | ||
182 | .periph_buses = PL08X_AHB2, | ||
183 | }, { | ||
184 | .bus_id = "rs485_tx", | ||
185 | .min_signal = 15, | ||
186 | .max_signal = 15, | ||
187 | .muxval = 1, | ||
188 | .periph_buses = PL08X_AHB2, | ||
189 | }, | ||
190 | }; | ||
191 | |||
192 | static struct pl022_ssp_controller spear320_ssp_data[] = { | ||
193 | { | ||
194 | .bus_id = 1, | ||
195 | .enable_dma = 1, | ||
196 | .dma_filter = pl08x_filter_id, | ||
197 | .dma_tx_param = "ssp1_tx", | ||
198 | .dma_rx_param = "ssp1_rx", | ||
199 | .num_chipselect = 2, | ||
200 | }, { | ||
201 | .bus_id = 2, | ||
202 | .enable_dma = 1, | ||
203 | .dma_filter = pl08x_filter_id, | ||
204 | .dma_tx_param = "ssp2_tx", | ||
205 | .dma_rx_param = "ssp2_rx", | ||
206 | .num_chipselect = 2, | ||
207 | } | ||
208 | }; | ||
209 | |||
210 | static struct amba_pl011_data spear320_uart_data[] = { | ||
211 | { | ||
212 | .dma_filter = pl08x_filter_id, | ||
213 | .dma_tx_param = "uart1_tx", | ||
214 | .dma_rx_param = "uart1_rx", | ||
215 | }, { | ||
216 | .dma_filter = pl08x_filter_id, | ||
217 | .dma_tx_param = "uart2_tx", | ||
218 | .dma_rx_param = "uart2_rx", | ||
219 | }, | ||
220 | }; | ||
221 | |||
222 | /* Add SPEAr310 auxdata to pass platform data */ | ||
223 | static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = { | ||
224 | OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL, | ||
225 | &pl022_plat_data), | ||
226 | OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL, | ||
227 | &pl080_plat_data), | ||
228 | OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP0_BASE, NULL, | ||
229 | &spear320_ssp_data[0]), | ||
230 | OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP1_BASE, NULL, | ||
231 | &spear320_ssp_data[1]), | ||
232 | OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART1_BASE, NULL, | ||
233 | &spear320_uart_data[0]), | ||
234 | OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART2_BASE, NULL, | ||
235 | &spear320_uart_data[1]), | ||
236 | {} | ||
237 | }; | ||
238 | |||
239 | static void __init spear320_dt_init(void) | ||
240 | { | ||
241 | pl080_plat_data.slave_channels = spear320_dma_info; | ||
242 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info); | ||
243 | |||
244 | of_platform_populate(NULL, of_default_bus_match_table, | ||
245 | spear320_auxdata_lookup, NULL); | ||
246 | } | ||
247 | |||
248 | static const char * const spear320_dt_board_compat[] = { | ||
249 | "st,spear320", | ||
250 | "st,spear320-evb", | ||
251 | "st,spear320-hmi", | ||
252 | NULL, | ||
253 | }; | ||
254 | |||
255 | struct map_desc spear320_io_desc[] __initdata = { | ||
256 | { | ||
257 | .virtual = (unsigned long)VA_SPEAR320_SOC_CONFIG_BASE, | ||
258 | .pfn = __phys_to_pfn(SPEAR320_SOC_CONFIG_BASE), | ||
259 | .length = SZ_16M, | ||
260 | .type = MT_DEVICE | ||
261 | }, | ||
262 | }; | ||
263 | |||
264 | static void __init spear320_map_io(void) | ||
265 | { | ||
266 | iotable_init(spear320_io_desc, ARRAY_SIZE(spear320_io_desc)); | ||
267 | spear3xx_map_io(); | ||
268 | } | ||
269 | |||
270 | DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree") | ||
271 | .map_io = spear320_map_io, | ||
272 | .init_irq = irqchip_init, | ||
273 | .init_time = spear3xx_timer_init, | ||
274 | .init_machine = spear320_dt_init, | ||
275 | .restart = spear_restart, | ||
276 | .dt_compat = spear320_dt_board_compat, | ||
277 | MACHINE_END | ||
diff --git a/arch/arm/mach-spear/spear3xx.c b/arch/arm/mach-spear/spear3xx.c new file mode 100644 index 000000000000..0227c97797cd --- /dev/null +++ b/arch/arm/mach-spear/spear3xx.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear3xx/spear3xx.c | ||
3 | * | ||
4 | * SPEAr3XX machines common source file | ||
5 | * | ||
6 | * Copyright (C) 2009-2012 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "SPEAr3xx: " fmt | ||
15 | |||
16 | #include <linux/amba/pl022.h> | ||
17 | #include <linux/amba/pl080.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <asm/mach/map.h> | ||
21 | #include "pl080.h" | ||
22 | #include "generic.h" | ||
23 | #include <mach/spear.h> | ||
24 | #include <mach/misc_regs.h> | ||
25 | |||
26 | /* ssp device registration */ | ||
27 | struct pl022_ssp_controller pl022_plat_data = { | ||
28 | .bus_id = 0, | ||
29 | .enable_dma = 1, | ||
30 | .dma_filter = pl08x_filter_id, | ||
31 | .dma_tx_param = "ssp0_tx", | ||
32 | .dma_rx_param = "ssp0_rx", | ||
33 | /* | ||
34 | * This is number of spi devices that can be connected to spi. There are | ||
35 | * two type of chipselects on which slave devices can work. One is chip | ||
36 | * select provided by spi masters other is controlled through external | ||
37 | * gpio's. We can't use chipselect provided from spi master (because as | ||
38 | * soon as FIFO becomes empty, CS is disabled and transfer ends). So | ||
39 | * this number now depends on number of gpios available for spi. each | ||
40 | * slave on each master requires a separate gpio pin. | ||
41 | */ | ||
42 | .num_chipselect = 2, | ||
43 | }; | ||
44 | |||
45 | /* dmac device registration */ | ||
46 | struct pl08x_platform_data pl080_plat_data = { | ||
47 | .memcpy_channel = { | ||
48 | .bus_id = "memcpy", | ||
49 | .cctl_memcpy = | ||
50 | (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ | ||
51 | PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ | ||
52 | PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ | ||
53 | PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ | ||
54 | PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \ | ||
55 | PL080_CONTROL_PROT_SYS), | ||
56 | }, | ||
57 | .lli_buses = PL08X_AHB1, | ||
58 | .mem_buses = PL08X_AHB1, | ||
59 | .get_signal = pl080_get_signal, | ||
60 | .put_signal = pl080_put_signal, | ||
61 | }; | ||
62 | |||
63 | /* | ||
64 | * Following will create 16MB static virtual/physical mappings | ||
65 | * PHYSICAL VIRTUAL | ||
66 | * 0xD0000000 0xFD000000 | ||
67 | * 0xFC000000 0xFC000000 | ||
68 | */ | ||
69 | struct map_desc spear3xx_io_desc[] __initdata = { | ||
70 | { | ||
71 | .virtual = (unsigned long)VA_SPEAR_ICM1_2_BASE, | ||
72 | .pfn = __phys_to_pfn(SPEAR_ICM1_2_BASE), | ||
73 | .length = SZ_16M, | ||
74 | .type = MT_DEVICE | ||
75 | }, { | ||
76 | .virtual = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE, | ||
77 | .pfn = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE), | ||
78 | .length = SZ_16M, | ||
79 | .type = MT_DEVICE | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | /* This will create static memory mapping for selected devices */ | ||
84 | void __init spear3xx_map_io(void) | ||
85 | { | ||
86 | iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc)); | ||
87 | } | ||
88 | |||
89 | void __init spear3xx_timer_init(void) | ||
90 | { | ||
91 | char pclk_name[] = "pll3_clk"; | ||
92 | struct clk *gpt_clk, *pclk; | ||
93 | |||
94 | spear3xx_clk_init(MISC_BASE, VA_SPEAR320_SOC_CONFIG_BASE); | ||
95 | |||
96 | /* get the system timer clock */ | ||
97 | gpt_clk = clk_get_sys("gpt0", NULL); | ||
98 | if (IS_ERR(gpt_clk)) { | ||
99 | pr_err("%s:couldn't get clk for gpt\n", __func__); | ||
100 | BUG(); | ||
101 | } | ||
102 | |||
103 | /* get the suitable parent clock for timer*/ | ||
104 | pclk = clk_get(NULL, pclk_name); | ||
105 | if (IS_ERR(pclk)) { | ||
106 | pr_err("%s:couldn't get %s as parent for gpt\n", | ||
107 | __func__, pclk_name); | ||
108 | BUG(); | ||
109 | } | ||
110 | |||
111 | clk_set_parent(gpt_clk, pclk); | ||
112 | clk_put(gpt_clk); | ||
113 | clk_put(pclk); | ||
114 | |||
115 | spear_setup_of_timer(); | ||
116 | } | ||
diff --git a/arch/arm/mach-spear/spear6xx.c b/arch/arm/mach-spear/spear6xx.c new file mode 100644 index 000000000000..ec8eefbbdfad --- /dev/null +++ b/arch/arm/mach-spear/spear6xx.c | |||
@@ -0,0 +1,431 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-spear6xx/spear6xx.c | ||
3 | * | ||
4 | * SPEAr6XX machines common source file | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Rajeev Kumar<rajeev-dlh.kumar@st.com> | ||
8 | * | ||
9 | * Copyright 2012 Stefan Roese <sr@denx.de> | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | #include <linux/amba/pl08x.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/irqchip.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_address.h> | ||
22 | #include <linux/of_platform.h> | ||
23 | #include <linux/amba/pl080.h> | ||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/mach/time.h> | ||
26 | #include <asm/mach/map.h> | ||
27 | #include "pl080.h" | ||
28 | #include "generic.h" | ||
29 | #include <mach/spear.h> | ||
30 | #include <mach/misc_regs.h> | ||
31 | |||
32 | /* dmac device registration */ | ||
33 | static struct pl08x_channel_data spear600_dma_info[] = { | ||
34 | { | ||
35 | .bus_id = "ssp1_rx", | ||
36 | .min_signal = 0, | ||
37 | .max_signal = 0, | ||
38 | .muxval = 0, | ||
39 | .periph_buses = PL08X_AHB1, | ||
40 | }, { | ||
41 | .bus_id = "ssp1_tx", | ||
42 | .min_signal = 1, | ||
43 | .max_signal = 1, | ||
44 | .muxval = 0, | ||
45 | .periph_buses = PL08X_AHB1, | ||
46 | }, { | ||
47 | .bus_id = "uart0_rx", | ||
48 | .min_signal = 2, | ||
49 | .max_signal = 2, | ||
50 | .muxval = 0, | ||
51 | .periph_buses = PL08X_AHB1, | ||
52 | }, { | ||
53 | .bus_id = "uart0_tx", | ||
54 | .min_signal = 3, | ||
55 | .max_signal = 3, | ||
56 | .muxval = 0, | ||
57 | .periph_buses = PL08X_AHB1, | ||
58 | }, { | ||
59 | .bus_id = "uart1_rx", | ||
60 | .min_signal = 4, | ||
61 | .max_signal = 4, | ||
62 | .muxval = 0, | ||
63 | .periph_buses = PL08X_AHB1, | ||
64 | }, { | ||
65 | .bus_id = "uart1_tx", | ||
66 | .min_signal = 5, | ||
67 | .max_signal = 5, | ||
68 | .muxval = 0, | ||
69 | .periph_buses = PL08X_AHB1, | ||
70 | }, { | ||
71 | .bus_id = "ssp2_rx", | ||
72 | .min_signal = 6, | ||
73 | .max_signal = 6, | ||
74 | .muxval = 0, | ||
75 | .periph_buses = PL08X_AHB2, | ||
76 | }, { | ||
77 | .bus_id = "ssp2_tx", | ||
78 | .min_signal = 7, | ||
79 | .max_signal = 7, | ||
80 | .muxval = 0, | ||
81 | .periph_buses = PL08X_AHB2, | ||
82 | }, { | ||
83 | .bus_id = "ssp0_rx", | ||
84 | .min_signal = 8, | ||
85 | .max_signal = 8, | ||
86 | .muxval = 0, | ||
87 | .periph_buses = PL08X_AHB1, | ||
88 | }, { | ||
89 | .bus_id = "ssp0_tx", | ||
90 | .min_signal = 9, | ||
91 | .max_signal = 9, | ||
92 | .muxval = 0, | ||
93 | .periph_buses = PL08X_AHB1, | ||
94 | }, { | ||
95 | .bus_id = "i2c_rx", | ||
96 | .min_signal = 10, | ||
97 | .max_signal = 10, | ||
98 | .muxval = 0, | ||
99 | .periph_buses = PL08X_AHB1, | ||
100 | }, { | ||
101 | .bus_id = "i2c_tx", | ||
102 | .min_signal = 11, | ||
103 | .max_signal = 11, | ||
104 | .muxval = 0, | ||
105 | .periph_buses = PL08X_AHB1, | ||
106 | }, { | ||
107 | .bus_id = "irda", | ||
108 | .min_signal = 12, | ||
109 | .max_signal = 12, | ||
110 | .muxval = 0, | ||
111 | .periph_buses = PL08X_AHB1, | ||
112 | }, { | ||
113 | .bus_id = "adc", | ||
114 | .min_signal = 13, | ||
115 | .max_signal = 13, | ||
116 | .muxval = 0, | ||
117 | .periph_buses = PL08X_AHB2, | ||
118 | }, { | ||
119 | .bus_id = "to_jpeg", | ||
120 | .min_signal = 14, | ||
121 | .max_signal = 14, | ||
122 | .muxval = 0, | ||
123 | .periph_buses = PL08X_AHB1, | ||
124 | }, { | ||
125 | .bus_id = "from_jpeg", | ||
126 | .min_signal = 15, | ||
127 | .max_signal = 15, | ||
128 | .muxval = 0, | ||
129 | .periph_buses = PL08X_AHB1, | ||
130 | }, { | ||
131 | .bus_id = "ras0_rx", | ||
132 | .min_signal = 0, | ||
133 | .max_signal = 0, | ||
134 | .muxval = 1, | ||
135 | .periph_buses = PL08X_AHB1, | ||
136 | }, { | ||
137 | .bus_id = "ras0_tx", | ||
138 | .min_signal = 1, | ||
139 | .max_signal = 1, | ||
140 | .muxval = 1, | ||
141 | .periph_buses = PL08X_AHB1, | ||
142 | }, { | ||
143 | .bus_id = "ras1_rx", | ||
144 | .min_signal = 2, | ||
145 | .max_signal = 2, | ||
146 | .muxval = 1, | ||
147 | .periph_buses = PL08X_AHB1, | ||
148 | }, { | ||
149 | .bus_id = "ras1_tx", | ||
150 | .min_signal = 3, | ||
151 | .max_signal = 3, | ||
152 | .muxval = 1, | ||
153 | .periph_buses = PL08X_AHB1, | ||
154 | }, { | ||
155 | .bus_id = "ras2_rx", | ||
156 | .min_signal = 4, | ||
157 | .max_signal = 4, | ||
158 | .muxval = 1, | ||
159 | .periph_buses = PL08X_AHB1, | ||
160 | }, { | ||
161 | .bus_id = "ras2_tx", | ||
162 | .min_signal = 5, | ||
163 | .max_signal = 5, | ||
164 | .muxval = 1, | ||
165 | .periph_buses = PL08X_AHB1, | ||
166 | }, { | ||
167 | .bus_id = "ras3_rx", | ||
168 | .min_signal = 6, | ||
169 | .max_signal = 6, | ||
170 | .muxval = 1, | ||
171 | .periph_buses = PL08X_AHB1, | ||
172 | }, { | ||
173 | .bus_id = "ras3_tx", | ||
174 | .min_signal = 7, | ||
175 | .max_signal = 7, | ||
176 | .muxval = 1, | ||
177 | .periph_buses = PL08X_AHB1, | ||
178 | }, { | ||
179 | .bus_id = "ras4_rx", | ||
180 | .min_signal = 8, | ||
181 | .max_signal = 8, | ||
182 | .muxval = 1, | ||
183 | .periph_buses = PL08X_AHB1, | ||
184 | }, { | ||
185 | .bus_id = "ras4_tx", | ||
186 | .min_signal = 9, | ||
187 | .max_signal = 9, | ||
188 | .muxval = 1, | ||
189 | .periph_buses = PL08X_AHB1, | ||
190 | }, { | ||
191 | .bus_id = "ras5_rx", | ||
192 | .min_signal = 10, | ||
193 | .max_signal = 10, | ||
194 | .muxval = 1, | ||
195 | .periph_buses = PL08X_AHB1, | ||
196 | }, { | ||
197 | .bus_id = "ras5_tx", | ||
198 | .min_signal = 11, | ||
199 | .max_signal = 11, | ||
200 | .muxval = 1, | ||
201 | .periph_buses = PL08X_AHB1, | ||
202 | }, { | ||
203 | .bus_id = "ras6_rx", | ||
204 | .min_signal = 12, | ||
205 | .max_signal = 12, | ||
206 | .muxval = 1, | ||
207 | .periph_buses = PL08X_AHB1, | ||
208 | }, { | ||
209 | .bus_id = "ras6_tx", | ||
210 | .min_signal = 13, | ||
211 | .max_signal = 13, | ||
212 | .muxval = 1, | ||
213 | .periph_buses = PL08X_AHB1, | ||
214 | }, { | ||
215 | .bus_id = "ras7_rx", | ||
216 | .min_signal = 14, | ||
217 | .max_signal = 14, | ||
218 | .muxval = 1, | ||
219 | .periph_buses = PL08X_AHB1, | ||
220 | }, { | ||
221 | .bus_id = "ras7_tx", | ||
222 | .min_signal = 15, | ||
223 | .max_signal = 15, | ||
224 | .muxval = 1, | ||
225 | .periph_buses = PL08X_AHB1, | ||
226 | }, { | ||
227 | .bus_id = "ext0_rx", | ||
228 | .min_signal = 0, | ||
229 | .max_signal = 0, | ||
230 | .muxval = 2, | ||
231 | .periph_buses = PL08X_AHB2, | ||
232 | }, { | ||
233 | .bus_id = "ext0_tx", | ||
234 | .min_signal = 1, | ||
235 | .max_signal = 1, | ||
236 | .muxval = 2, | ||
237 | .periph_buses = PL08X_AHB2, | ||
238 | }, { | ||
239 | .bus_id = "ext1_rx", | ||
240 | .min_signal = 2, | ||
241 | .max_signal = 2, | ||
242 | .muxval = 2, | ||
243 | .periph_buses = PL08X_AHB2, | ||
244 | }, { | ||
245 | .bus_id = "ext1_tx", | ||
246 | .min_signal = 3, | ||
247 | .max_signal = 3, | ||
248 | .muxval = 2, | ||
249 | .periph_buses = PL08X_AHB2, | ||
250 | }, { | ||
251 | .bus_id = "ext2_rx", | ||
252 | .min_signal = 4, | ||
253 | .max_signal = 4, | ||
254 | .muxval = 2, | ||
255 | .periph_buses = PL08X_AHB2, | ||
256 | }, { | ||
257 | .bus_id = "ext2_tx", | ||
258 | .min_signal = 5, | ||
259 | .max_signal = 5, | ||
260 | .muxval = 2, | ||
261 | .periph_buses = PL08X_AHB2, | ||
262 | }, { | ||
263 | .bus_id = "ext3_rx", | ||
264 | .min_signal = 6, | ||
265 | .max_signal = 6, | ||
266 | .muxval = 2, | ||
267 | .periph_buses = PL08X_AHB2, | ||
268 | }, { | ||
269 | .bus_id = "ext3_tx", | ||
270 | .min_signal = 7, | ||
271 | .max_signal = 7, | ||
272 | .muxval = 2, | ||
273 | .periph_buses = PL08X_AHB2, | ||
274 | }, { | ||
275 | .bus_id = "ext4_rx", | ||
276 | .min_signal = 8, | ||
277 | .max_signal = 8, | ||
278 | .muxval = 2, | ||
279 | .periph_buses = PL08X_AHB2, | ||
280 | }, { | ||
281 | .bus_id = "ext4_tx", | ||
282 | .min_signal = 9, | ||
283 | .max_signal = 9, | ||
284 | .muxval = 2, | ||
285 | .periph_buses = PL08X_AHB2, | ||
286 | }, { | ||
287 | .bus_id = "ext5_rx", | ||
288 | .min_signal = 10, | ||
289 | .max_signal = 10, | ||
290 | .muxval = 2, | ||
291 | .periph_buses = PL08X_AHB2, | ||
292 | }, { | ||
293 | .bus_id = "ext5_tx", | ||
294 | .min_signal = 11, | ||
295 | .max_signal = 11, | ||
296 | .muxval = 2, | ||
297 | .periph_buses = PL08X_AHB2, | ||
298 | }, { | ||
299 | .bus_id = "ext6_rx", | ||
300 | .min_signal = 12, | ||
301 | .max_signal = 12, | ||
302 | .muxval = 2, | ||
303 | .periph_buses = PL08X_AHB2, | ||
304 | }, { | ||
305 | .bus_id = "ext6_tx", | ||
306 | .min_signal = 13, | ||
307 | .max_signal = 13, | ||
308 | .muxval = 2, | ||
309 | .periph_buses = PL08X_AHB2, | ||
310 | }, { | ||
311 | .bus_id = "ext7_rx", | ||
312 | .min_signal = 14, | ||
313 | .max_signal = 14, | ||
314 | .muxval = 2, | ||
315 | .periph_buses = PL08X_AHB2, | ||
316 | }, { | ||
317 | .bus_id = "ext7_tx", | ||
318 | .min_signal = 15, | ||
319 | .max_signal = 15, | ||
320 | .muxval = 2, | ||
321 | .periph_buses = PL08X_AHB2, | ||
322 | }, | ||
323 | }; | ||
324 | |||
325 | static struct pl08x_platform_data spear6xx_pl080_plat_data = { | ||
326 | .memcpy_channel = { | ||
327 | .bus_id = "memcpy", | ||
328 | .cctl_memcpy = | ||
329 | (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ | ||
330 | PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ | ||
331 | PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ | ||
332 | PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ | ||
333 | PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \ | ||
334 | PL080_CONTROL_PROT_SYS), | ||
335 | }, | ||
336 | .lli_buses = PL08X_AHB1, | ||
337 | .mem_buses = PL08X_AHB1, | ||
338 | .get_signal = pl080_get_signal, | ||
339 | .put_signal = pl080_put_signal, | ||
340 | .slave_channels = spear600_dma_info, | ||
341 | .num_slave_channels = ARRAY_SIZE(spear600_dma_info), | ||
342 | }; | ||
343 | |||
344 | /* | ||
345 | * Following will create 16MB static virtual/physical mappings | ||
346 | * PHYSICAL VIRTUAL | ||
347 | * 0xF0000000 0xF0000000 | ||
348 | * 0xF1000000 0xF1000000 | ||
349 | * 0xD0000000 0xFD000000 | ||
350 | * 0xFC000000 0xFC000000 | ||
351 | */ | ||
352 | struct map_desc spear6xx_io_desc[] __initdata = { | ||
353 | { | ||
354 | .virtual = (unsigned long)VA_SPEAR6XX_ML_CPU_BASE, | ||
355 | .pfn = __phys_to_pfn(SPEAR_ICM3_ML1_2_BASE), | ||
356 | .length = 2 * SZ_16M, | ||
357 | .type = MT_DEVICE | ||
358 | }, { | ||
359 | .virtual = (unsigned long)VA_SPEAR_ICM1_2_BASE, | ||
360 | .pfn = __phys_to_pfn(SPEAR_ICM1_2_BASE), | ||
361 | .length = SZ_16M, | ||
362 | .type = MT_DEVICE | ||
363 | }, { | ||
364 | .virtual = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE, | ||
365 | .pfn = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE), | ||
366 | .length = SZ_16M, | ||
367 | .type = MT_DEVICE | ||
368 | }, | ||
369 | }; | ||
370 | |||
371 | /* This will create static memory mapping for selected devices */ | ||
372 | void __init spear6xx_map_io(void) | ||
373 | { | ||
374 | iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc)); | ||
375 | } | ||
376 | |||
377 | void __init spear6xx_timer_init(void) | ||
378 | { | ||
379 | char pclk_name[] = "pll3_clk"; | ||
380 | struct clk *gpt_clk, *pclk; | ||
381 | |||
382 | spear6xx_clk_init(MISC_BASE); | ||
383 | |||
384 | /* get the system timer clock */ | ||
385 | gpt_clk = clk_get_sys("gpt0", NULL); | ||
386 | if (IS_ERR(gpt_clk)) { | ||
387 | pr_err("%s:couldn't get clk for gpt\n", __func__); | ||
388 | BUG(); | ||
389 | } | ||
390 | |||
391 | /* get the suitable parent clock for timer*/ | ||
392 | pclk = clk_get(NULL, pclk_name); | ||
393 | if (IS_ERR(pclk)) { | ||
394 | pr_err("%s:couldn't get %s as parent for gpt\n", | ||
395 | __func__, pclk_name); | ||
396 | BUG(); | ||
397 | } | ||
398 | |||
399 | clk_set_parent(gpt_clk, pclk); | ||
400 | clk_put(gpt_clk); | ||
401 | clk_put(pclk); | ||
402 | |||
403 | spear_setup_of_timer(); | ||
404 | } | ||
405 | |||
406 | /* Add auxdata to pass platform data */ | ||
407 | struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = { | ||
408 | OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL, | ||
409 | &spear6xx_pl080_plat_data), | ||
410 | {} | ||
411 | }; | ||
412 | |||
413 | static void __init spear600_dt_init(void) | ||
414 | { | ||
415 | of_platform_populate(NULL, of_default_bus_match_table, | ||
416 | spear6xx_auxdata_lookup, NULL); | ||
417 | } | ||
418 | |||
419 | static const char *spear600_dt_board_compat[] = { | ||
420 | "st,spear600", | ||
421 | NULL | ||
422 | }; | ||
423 | |||
424 | DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)") | ||
425 | .map_io = spear6xx_map_io, | ||
426 | .init_irq = irqchip_init, | ||
427 | .init_time = spear6xx_timer_init, | ||
428 | .init_machine = spear600_dt_init, | ||
429 | .restart = spear_restart, | ||
430 | .dt_compat = spear600_dt_board_compat, | ||
431 | MACHINE_END | ||
diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c new file mode 100644 index 000000000000..d449673e40f7 --- /dev/null +++ b/arch/arm/mach-spear/time.c | |||
@@ -0,0 +1,245 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/time.c | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Shiraz Hashim<shiraz.hashim@st.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/clockchips.h> | ||
14 | #include <linux/clocksource.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/of_irq.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/time.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <asm/mach/time.h> | ||
26 | #include "generic.h" | ||
27 | |||
28 | /* | ||
29 | * We would use TIMER0 and TIMER1 as clockevent and clocksource. | ||
30 | * Timer0 and Timer1 both belong to same gpt block in cpu subbsystem. Further | ||
31 | * they share same functional clock. Any change in one's functional clock will | ||
32 | * also affect other timer. | ||
33 | */ | ||
34 | |||
35 | #define CLKEVT 0 /* gpt0, channel0 as clockevent */ | ||
36 | #define CLKSRC 1 /* gpt0, channel1 as clocksource */ | ||
37 | |||
38 | /* Register offsets, x is channel number */ | ||
39 | #define CR(x) ((x) * 0x80 + 0x80) | ||
40 | #define IR(x) ((x) * 0x80 + 0x84) | ||
41 | #define LOAD(x) ((x) * 0x80 + 0x88) | ||
42 | #define COUNT(x) ((x) * 0x80 + 0x8C) | ||
43 | |||
44 | /* Reg bit definitions */ | ||
45 | #define CTRL_INT_ENABLE 0x0100 | ||
46 | #define CTRL_ENABLE 0x0020 | ||
47 | #define CTRL_ONE_SHOT 0x0010 | ||
48 | |||
49 | #define CTRL_PRESCALER1 0x0 | ||
50 | #define CTRL_PRESCALER2 0x1 | ||
51 | #define CTRL_PRESCALER4 0x2 | ||
52 | #define CTRL_PRESCALER8 0x3 | ||
53 | #define CTRL_PRESCALER16 0x4 | ||
54 | #define CTRL_PRESCALER32 0x5 | ||
55 | #define CTRL_PRESCALER64 0x6 | ||
56 | #define CTRL_PRESCALER128 0x7 | ||
57 | #define CTRL_PRESCALER256 0x8 | ||
58 | |||
59 | #define INT_STATUS 0x1 | ||
60 | |||
61 | /* | ||
62 | * Minimum clocksource/clockevent timer range in seconds | ||
63 | */ | ||
64 | #define SPEAR_MIN_RANGE 4 | ||
65 | |||
66 | static __iomem void *gpt_base; | ||
67 | static struct clk *gpt_clk; | ||
68 | |||
69 | static void clockevent_set_mode(enum clock_event_mode mode, | ||
70 | struct clock_event_device *clk_event_dev); | ||
71 | static int clockevent_next_event(unsigned long evt, | ||
72 | struct clock_event_device *clk_event_dev); | ||
73 | |||
74 | static void spear_clocksource_init(void) | ||
75 | { | ||
76 | u32 tick_rate; | ||
77 | u16 val; | ||
78 | |||
79 | /* program the prescaler (/256)*/ | ||
80 | writew(CTRL_PRESCALER256, gpt_base + CR(CLKSRC)); | ||
81 | |||
82 | /* find out actual clock driving Timer */ | ||
83 | tick_rate = clk_get_rate(gpt_clk); | ||
84 | tick_rate >>= CTRL_PRESCALER256; | ||
85 | |||
86 | writew(0xFFFF, gpt_base + LOAD(CLKSRC)); | ||
87 | |||
88 | val = readw(gpt_base + CR(CLKSRC)); | ||
89 | val &= ~CTRL_ONE_SHOT; /* autoreload mode */ | ||
90 | val |= CTRL_ENABLE ; | ||
91 | writew(val, gpt_base + CR(CLKSRC)); | ||
92 | |||
93 | /* register the clocksource */ | ||
94 | clocksource_mmio_init(gpt_base + COUNT(CLKSRC), "tmr1", tick_rate, | ||
95 | 200, 16, clocksource_mmio_readw_up); | ||
96 | } | ||
97 | |||
98 | static struct clock_event_device clkevt = { | ||
99 | .name = "tmr0", | ||
100 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
101 | .set_mode = clockevent_set_mode, | ||
102 | .set_next_event = clockevent_next_event, | ||
103 | .shift = 0, /* to be computed */ | ||
104 | }; | ||
105 | |||
106 | static void clockevent_set_mode(enum clock_event_mode mode, | ||
107 | struct clock_event_device *clk_event_dev) | ||
108 | { | ||
109 | u32 period; | ||
110 | u16 val; | ||
111 | |||
112 | /* stop the timer */ | ||
113 | val = readw(gpt_base + CR(CLKEVT)); | ||
114 | val &= ~CTRL_ENABLE; | ||
115 | writew(val, gpt_base + CR(CLKEVT)); | ||
116 | |||
117 | switch (mode) { | ||
118 | case CLOCK_EVT_MODE_PERIODIC: | ||
119 | period = clk_get_rate(gpt_clk) / HZ; | ||
120 | period >>= CTRL_PRESCALER16; | ||
121 | writew(period, gpt_base + LOAD(CLKEVT)); | ||
122 | |||
123 | val = readw(gpt_base + CR(CLKEVT)); | ||
124 | val &= ~CTRL_ONE_SHOT; | ||
125 | val |= CTRL_ENABLE | CTRL_INT_ENABLE; | ||
126 | writew(val, gpt_base + CR(CLKEVT)); | ||
127 | |||
128 | break; | ||
129 | case CLOCK_EVT_MODE_ONESHOT: | ||
130 | val = readw(gpt_base + CR(CLKEVT)); | ||
131 | val |= CTRL_ONE_SHOT; | ||
132 | writew(val, gpt_base + CR(CLKEVT)); | ||
133 | |||
134 | break; | ||
135 | case CLOCK_EVT_MODE_UNUSED: | ||
136 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
137 | case CLOCK_EVT_MODE_RESUME: | ||
138 | |||
139 | break; | ||
140 | default: | ||
141 | pr_err("Invalid mode requested\n"); | ||
142 | break; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static int clockevent_next_event(unsigned long cycles, | ||
147 | struct clock_event_device *clk_event_dev) | ||
148 | { | ||
149 | u16 val = readw(gpt_base + CR(CLKEVT)); | ||
150 | |||
151 | if (val & CTRL_ENABLE) | ||
152 | writew(val & ~CTRL_ENABLE, gpt_base + CR(CLKEVT)); | ||
153 | |||
154 | writew(cycles, gpt_base + LOAD(CLKEVT)); | ||
155 | |||
156 | val |= CTRL_ENABLE | CTRL_INT_ENABLE; | ||
157 | writew(val, gpt_base + CR(CLKEVT)); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static irqreturn_t spear_timer_interrupt(int irq, void *dev_id) | ||
163 | { | ||
164 | struct clock_event_device *evt = &clkevt; | ||
165 | |||
166 | writew(INT_STATUS, gpt_base + IR(CLKEVT)); | ||
167 | |||
168 | evt->event_handler(evt); | ||
169 | |||
170 | return IRQ_HANDLED; | ||
171 | } | ||
172 | |||
173 | static struct irqaction spear_timer_irq = { | ||
174 | .name = "timer", | ||
175 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
176 | .handler = spear_timer_interrupt | ||
177 | }; | ||
178 | |||
179 | static void __init spear_clockevent_init(int irq) | ||
180 | { | ||
181 | u32 tick_rate; | ||
182 | |||
183 | /* program the prescaler */ | ||
184 | writew(CTRL_PRESCALER16, gpt_base + CR(CLKEVT)); | ||
185 | |||
186 | tick_rate = clk_get_rate(gpt_clk); | ||
187 | tick_rate >>= CTRL_PRESCALER16; | ||
188 | |||
189 | clkevt.cpumask = cpumask_of(0); | ||
190 | |||
191 | clockevents_config_and_register(&clkevt, tick_rate, 3, 0xfff0); | ||
192 | |||
193 | setup_irq(irq, &spear_timer_irq); | ||
194 | } | ||
195 | |||
196 | const static struct of_device_id timer_of_match[] __initconst = { | ||
197 | { .compatible = "st,spear-timer", }, | ||
198 | { }, | ||
199 | }; | ||
200 | |||
201 | void __init spear_setup_of_timer(void) | ||
202 | { | ||
203 | struct device_node *np; | ||
204 | int irq, ret; | ||
205 | |||
206 | np = of_find_matching_node(NULL, timer_of_match); | ||
207 | if (!np) { | ||
208 | pr_err("%s: No timer passed via DT\n", __func__); | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | irq = irq_of_parse_and_map(np, 0); | ||
213 | if (!irq) { | ||
214 | pr_err("%s: No irq passed for timer via DT\n", __func__); | ||
215 | return; | ||
216 | } | ||
217 | |||
218 | gpt_base = of_iomap(np, 0); | ||
219 | if (!gpt_base) { | ||
220 | pr_err("%s: of iomap failed\n", __func__); | ||
221 | return; | ||
222 | } | ||
223 | |||
224 | gpt_clk = clk_get_sys("gpt0", NULL); | ||
225 | if (!gpt_clk) { | ||
226 | pr_err("%s:couldn't get clk for gpt\n", __func__); | ||
227 | goto err_iomap; | ||
228 | } | ||
229 | |||
230 | ret = clk_prepare_enable(gpt_clk); | ||
231 | if (ret < 0) { | ||
232 | pr_err("%s:couldn't prepare-enable gpt clock\n", __func__); | ||
233 | goto err_prepare_enable_clk; | ||
234 | } | ||
235 | |||
236 | spear_clockevent_init(irq); | ||
237 | spear_clocksource_init(); | ||
238 | |||
239 | return; | ||
240 | |||
241 | err_prepare_enable_clk: | ||
242 | clk_put(gpt_clk); | ||
243 | err_iomap: | ||
244 | iounmap(gpt_base); | ||
245 | } | ||