Commit 4980f9bc2cec0f8ff0e0f2b021d46c7606ae1849
Committed by
Russell King
1 parent
dc81df520b
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ARM: 7517/1: integrator: initial device tree support
This is initial device tree support for the ARM Integrator family, we create a very basic device tree, #ifdef out the non-DT machines when compiling for device tree. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 6 changed files with 360 additions and 68 deletions Inline Diff
Documentation/devicetree/bindings/arm/arm-boards
1 | ARM Integrator/AP (Application Platform) and Integrator/CP (Compact Platform) | ||
2 | ----------------------------------------------------------------------------- | ||
3 | ARM's oldest Linux-supported platform with connectors for different core | ||
4 | tiles of ARMv4, ARMv5 and ARMv6 type. | ||
5 | |||
6 | Required properties (in root node): | ||
7 | compatible = "arm,integrator-ap"; /* Application Platform */ | ||
8 | compatible = "arm,integrator-cp"; /* Compact Platform */ | ||
9 | |||
10 | FPGA type interrupt controllers, see the versatile-fpga-irq binding doc. | ||
11 | |||
12 | |||
1 | ARM Versatile Application and Platform Baseboards | 13 | ARM Versatile Application and Platform Baseboards |
2 | ------------------------------------------------- | 14 | ------------------------------------------------- |
3 | ARM's development hardware platform with connectors for customizable | 15 | ARM's development hardware platform with connectors for customizable |
4 | core tiles. The hardware configuration of the Versatile boards is | 16 | core tiles. The hardware configuration of the Versatile boards is |
5 | highly customizable. | 17 | highly customizable. |
6 | 18 | ||
7 | Required properties (in root node): | 19 | Required properties (in root node): |
8 | compatible = "arm,versatile-ab"; /* Application baseboard */ | 20 | compatible = "arm,versatile-ab"; /* Application baseboard */ |
9 | compatible = "arm,versatile-pb"; /* Platform baseboard */ | 21 | compatible = "arm,versatile-pb"; /* Platform baseboard */ |
10 | 22 | ||
11 | Interrupt controllers: | 23 | Interrupt controllers: |
12 | - VIC required properties: | 24 | - VIC required properties: |
13 | compatible = "arm,versatile-vic"; | 25 | compatible = "arm,versatile-vic"; |
14 | interrupt-controller; | 26 | interrupt-controller; |
15 | #interrupt-cells = <1>; | 27 | #interrupt-cells = <1>; |
16 | 28 | ||
17 | - SIC required properties: | 29 | - SIC required properties: |
18 | compatible = "arm,versatile-sic"; | 30 | compatible = "arm,versatile-sic"; |
19 | interrupt-controller; | 31 | interrupt-controller; |
20 | #interrupt-cells = <1>; | 32 | #interrupt-cells = <1>; |
21 | 33 |
arch/arm/boot/dts/integrator.dtsi
File was created | 1 | /* | |
2 | * SoC core Device Tree for the ARM Integrator platforms | ||
3 | */ | ||
4 | |||
5 | /include/ "skeleton.dtsi" | ||
6 | |||
7 | / { | ||
8 | timer@13000000 { | ||
9 | reg = <0x13000000 0x100>; | ||
10 | interrupt-parent = <&pic>; | ||
11 | interrupts = <5>; | ||
12 | }; | ||
13 | |||
14 | timer@13000100 { | ||
15 | reg = <0x13000100 0x100>; | ||
16 | interrupt-parent = <&pic>; | ||
17 | interrupts = <6>; | ||
18 | }; | ||
19 | |||
20 | timer@13000200 { | ||
21 | reg = <0x13000200 0x100>; | ||
22 | interrupt-parent = <&pic>; | ||
23 | interrupts = <7>; | ||
24 | }; | ||
25 | |||
26 | pic@14000000 { | ||
27 | compatible = "arm,versatile-fpga-irq"; | ||
28 | #interrupt-cells = <1>; | ||
29 | interrupt-controller; | ||
30 | reg = <0x14000000 0x100>; | ||
31 | clear-mask = <0xffffffff>; | ||
32 | }; | ||
33 | }; | ||
34 |
arch/arm/boot/dts/integratorap.dts
File was created | 1 | /* | |
2 | * Device Tree for the ARM Integrator/AP platform | ||
3 | */ | ||
4 | |||
5 | /dts-v1/; | ||
6 | /include/ "integrator.dtsi" | ||
7 | |||
8 | / { | ||
9 | model = "ARM Integrator/AP"; | ||
10 | compatible = "arm,integrator-ap"; | ||
11 | |||
12 | aliases { | ||
13 | arm,timer-primary = &timer2; | ||
14 | arm,timer-secondary = &timer1; | ||
15 | }; | ||
16 | |||
17 | chosen { | ||
18 | bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; | ||
19 | }; | ||
20 | |||
21 | timer0: timer@13000000 { | ||
22 | compatible = "arm,integrator-timer"; | ||
23 | }; | ||
24 | |||
25 | timer1: timer@13000100 { | ||
26 | compatible = "arm,integrator-timer"; | ||
27 | }; | ||
28 | |||
29 | timer2: timer@13000200 { | ||
30 | compatible = "arm,integrator-timer"; | ||
31 | }; | ||
32 | |||
33 | pic: pic@14000000 { | ||
34 | valid-mask = <0x003fffff>; | ||
35 | }; | ||
36 | }; | ||
37 |
arch/arm/boot/dts/integratorcp.dts
File was created | 1 | /* | |
2 | * Device Tree for the ARM Integrator/CP platform | ||
3 | */ | ||
4 | |||
5 | /dts-v1/; | ||
6 | /include/ "integrator.dtsi" | ||
7 | |||
8 | / { | ||
9 | model = "ARM Integrator/CP"; | ||
10 | compatible = "arm,integrator-cp"; | ||
11 | |||
12 | aliases { | ||
13 | arm,timer-primary = &timer2; | ||
14 | arm,timer-secondary = &timer1; | ||
15 | }; | ||
16 | |||
17 | chosen { | ||
18 | bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; | ||
19 | }; | ||
20 | |||
21 | timer0: timer@13000000 { | ||
22 | compatible = "arm,sp804", "arm,primecell"; | ||
23 | }; | ||
24 | |||
25 | timer1: timer@13000100 { | ||
26 | compatible = "arm,sp804", "arm,primecell"; | ||
27 | }; | ||
28 | |||
29 | timer2: timer@13000200 { | ||
30 | compatible = "arm,sp804", "arm,primecell"; | ||
31 | }; | ||
32 | |||
33 | pic: pic@14000000 { | ||
34 | valid-mask = <0x1fc003ff>; | ||
35 | }; | ||
36 | |||
37 | cic: cic@10000040 { | ||
38 | compatible = "arm,versatile-fpga-irq"; | ||
39 | #interrupt-cells = <1>; | ||
40 | interrupt-controller; | ||
41 | reg = <0x10000040 0x100>; | ||
42 | clear-mask = <0xffffffff>; | ||
43 | valid-mask = <0x00000007>; | ||
44 | }; | ||
45 | |||
46 | sic: sic@ca000000 { | ||
47 | compatible = "arm,versatile-fpga-irq"; | ||
48 | #interrupt-cells = <1>; | ||
49 | interrupt-controller; | ||
50 | reg = <0xca000000 0x100>; | ||
51 | clear-mask = <0x00000fff>; | ||
52 | valid-mask = <0x00000fff>; | ||
53 | }; | ||
54 | }; | ||
55 |
arch/arm/mach-integrator/integrator_ap.c
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-integrator/integrator_ap.c | 2 | * linux/arch/arm/mach-integrator/integrator_ap.c |
3 | * | 3 | * |
4 | * Copyright (C) 2000-2003 Deep Blue Solutions Ltd | 4 | * Copyright (C) 2000-2003 Deep Blue Solutions Ltd |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/syscore_ops.h> | 27 | #include <linux/syscore_ops.h> |
28 | #include <linux/amba/bus.h> | 28 | #include <linux/amba/bus.h> |
29 | #include <linux/amba/kmi.h> | 29 | #include <linux/amba/kmi.h> |
30 | #include <linux/clocksource.h> | 30 | #include <linux/clocksource.h> |
31 | #include <linux/clockchips.h> | 31 | #include <linux/clockchips.h> |
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/mtd/physmap.h> | 34 | #include <linux/mtd/physmap.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/platform_data/clk-integrator.h> | 36 | #include <linux/platform_data/clk-integrator.h> |
37 | #include <linux/of_irq.h> | ||
38 | #include <linux/of_address.h> | ||
37 | #include <video/vga.h> | 39 | #include <video/vga.h> |
38 | 40 | ||
39 | #include <mach/hardware.h> | 41 | #include <mach/hardware.h> |
40 | #include <mach/platform.h> | 42 | #include <mach/platform.h> |
41 | #include <asm/hardware/arm_timer.h> | 43 | #include <asm/hardware/arm_timer.h> |
42 | #include <asm/setup.h> | 44 | #include <asm/setup.h> |
43 | #include <asm/param.h> /* HZ */ | 45 | #include <asm/param.h> /* HZ */ |
44 | #include <asm/mach-types.h> | 46 | #include <asm/mach-types.h> |
45 | #include <asm/sched_clock.h> | 47 | #include <asm/sched_clock.h> |
46 | 48 | ||
47 | #include <mach/lm.h> | 49 | #include <mach/lm.h> |
48 | #include <mach/irqs.h> | 50 | #include <mach/irqs.h> |
49 | 51 | ||
50 | #include <asm/mach/arch.h> | 52 | #include <asm/mach/arch.h> |
51 | #include <asm/mach/irq.h> | 53 | #include <asm/mach/irq.h> |
52 | #include <asm/mach/map.h> | 54 | #include <asm/mach/map.h> |
53 | #include <asm/mach/time.h> | 55 | #include <asm/mach/time.h> |
54 | 56 | ||
55 | #include <plat/fpga-irq.h> | 57 | #include <plat/fpga-irq.h> |
56 | 58 | ||
57 | #include "common.h" | 59 | #include "common.h" |
58 | 60 | ||
59 | /* | 61 | /* |
60 | * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx | 62 | * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx |
61 | * is the (PA >> 12). | 63 | * is the (PA >> 12). |
62 | * | 64 | * |
63 | * Setup a VA for the Integrator interrupt controller (for header #0, | 65 | * Setup a VA for the Integrator interrupt controller (for header #0, |
64 | * just for now). | 66 | * just for now). |
65 | */ | 67 | */ |
66 | #define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE) | 68 | #define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE) |
67 | #define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE) | 69 | #define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE) |
68 | #define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE) | 70 | #define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE) |
69 | #define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC) | 71 | #define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC) |
70 | 72 | ||
71 | /* | 73 | /* |
72 | * Logical Physical | 74 | * Logical Physical |
73 | * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M) | 75 | * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M) |
74 | * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M) | 76 | * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M) |
75 | * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k) | 77 | * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k) |
76 | * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M) | 78 | * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M) |
77 | * ef000000 Cache flush | 79 | * ef000000 Cache flush |
78 | * f1000000 10000000 Core module registers | 80 | * f1000000 10000000 Core module registers |
79 | * f1100000 11000000 System controller registers | 81 | * f1100000 11000000 System controller registers |
80 | * f1200000 12000000 EBI registers | 82 | * f1200000 12000000 EBI registers |
81 | * f1300000 13000000 Counter/Timer | 83 | * f1300000 13000000 Counter/Timer |
82 | * f1400000 14000000 Interrupt controller | 84 | * f1400000 14000000 Interrupt controller |
83 | * f1600000 16000000 UART 0 | 85 | * f1600000 16000000 UART 0 |
84 | * f1700000 17000000 UART 1 | 86 | * f1700000 17000000 UART 1 |
85 | * f1a00000 1a000000 Debug LEDs | 87 | * f1a00000 1a000000 Debug LEDs |
86 | * f1b00000 1b000000 GPIO | 88 | * f1b00000 1b000000 GPIO |
87 | */ | 89 | */ |
88 | 90 | ||
89 | static struct map_desc ap_io_desc[] __initdata = { | 91 | static struct map_desc ap_io_desc[] __initdata = { |
90 | { | 92 | { |
91 | .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), | 93 | .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), |
92 | .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), | 94 | .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), |
93 | .length = SZ_4K, | 95 | .length = SZ_4K, |
94 | .type = MT_DEVICE | 96 | .type = MT_DEVICE |
95 | }, { | 97 | }, { |
96 | .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), | 98 | .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), |
97 | .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), | 99 | .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), |
98 | .length = SZ_4K, | 100 | .length = SZ_4K, |
99 | .type = MT_DEVICE | 101 | .type = MT_DEVICE |
100 | }, { | 102 | }, { |
101 | .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), | 103 | .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), |
102 | .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), | 104 | .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), |
103 | .length = SZ_4K, | 105 | .length = SZ_4K, |
104 | .type = MT_DEVICE | 106 | .type = MT_DEVICE |
105 | }, { | 107 | }, { |
106 | .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), | 108 | .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), |
107 | .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), | 109 | .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), |
108 | .length = SZ_4K, | 110 | .length = SZ_4K, |
109 | .type = MT_DEVICE | 111 | .type = MT_DEVICE |
110 | }, { | 112 | }, { |
111 | .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), | 113 | .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), |
112 | .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), | 114 | .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), |
113 | .length = SZ_4K, | 115 | .length = SZ_4K, |
114 | .type = MT_DEVICE | 116 | .type = MT_DEVICE |
115 | }, { | 117 | }, { |
116 | .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), | 118 | .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), |
117 | .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), | 119 | .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), |
118 | .length = SZ_4K, | 120 | .length = SZ_4K, |
119 | .type = MT_DEVICE | 121 | .type = MT_DEVICE |
120 | }, { | 122 | }, { |
121 | .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE), | 123 | .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE), |
122 | .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE), | 124 | .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE), |
123 | .length = SZ_4K, | 125 | .length = SZ_4K, |
124 | .type = MT_DEVICE | 126 | .type = MT_DEVICE |
125 | }, { | 127 | }, { |
126 | .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE), | 128 | .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE), |
127 | .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE), | 129 | .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE), |
128 | .length = SZ_4K, | 130 | .length = SZ_4K, |
129 | .type = MT_DEVICE | 131 | .type = MT_DEVICE |
130 | }, { | 132 | }, { |
131 | .virtual = IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE), | 133 | .virtual = IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE), |
132 | .pfn = __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE), | 134 | .pfn = __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE), |
133 | .length = SZ_4K, | 135 | .length = SZ_4K, |
134 | .type = MT_DEVICE | 136 | .type = MT_DEVICE |
135 | }, { | 137 | }, { |
136 | .virtual = PCI_MEMORY_VADDR, | 138 | .virtual = PCI_MEMORY_VADDR, |
137 | .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE), | 139 | .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE), |
138 | .length = SZ_16M, | 140 | .length = SZ_16M, |
139 | .type = MT_DEVICE | 141 | .type = MT_DEVICE |
140 | }, { | 142 | }, { |
141 | .virtual = PCI_CONFIG_VADDR, | 143 | .virtual = PCI_CONFIG_VADDR, |
142 | .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE), | 144 | .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE), |
143 | .length = SZ_16M, | 145 | .length = SZ_16M, |
144 | .type = MT_DEVICE | 146 | .type = MT_DEVICE |
145 | }, { | 147 | }, { |
146 | .virtual = PCI_V3_VADDR, | 148 | .virtual = PCI_V3_VADDR, |
147 | .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE), | 149 | .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE), |
148 | .length = SZ_64K, | 150 | .length = SZ_64K, |
149 | .type = MT_DEVICE | 151 | .type = MT_DEVICE |
150 | }, { | 152 | }, { |
151 | .virtual = PCI_IO_VADDR, | 153 | .virtual = PCI_IO_VADDR, |
152 | .pfn = __phys_to_pfn(PHYS_PCI_IO_BASE), | 154 | .pfn = __phys_to_pfn(PHYS_PCI_IO_BASE), |
153 | .length = SZ_64K, | 155 | .length = SZ_64K, |
154 | .type = MT_DEVICE | 156 | .type = MT_DEVICE |
155 | } | 157 | } |
156 | }; | 158 | }; |
157 | 159 | ||
158 | static void __init ap_map_io(void) | 160 | static void __init ap_map_io(void) |
159 | { | 161 | { |
160 | iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc)); | 162 | iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc)); |
161 | vga_base = PCI_MEMORY_VADDR; | 163 | vga_base = PCI_MEMORY_VADDR; |
162 | } | 164 | } |
163 | 165 | ||
164 | #define INTEGRATOR_SC_VALID_INT 0x003fffff | ||
165 | |||
166 | static void __init ap_init_irq(void) | ||
167 | { | ||
168 | /* Disable all interrupts initially. */ | ||
169 | /* Do the core module ones */ | ||
170 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
171 | |||
172 | /* do the header card stuff next */ | ||
173 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | ||
174 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | ||
175 | |||
176 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, | ||
177 | -1, INTEGRATOR_SC_VALID_INT, NULL); | ||
178 | integrator_clk_init(false); | ||
179 | } | ||
180 | |||
181 | #ifdef CONFIG_PM | 166 | #ifdef CONFIG_PM |
182 | static unsigned long ic_irq_enable; | 167 | static unsigned long ic_irq_enable; |
183 | 168 | ||
184 | static int irq_suspend(void) | 169 | static int irq_suspend(void) |
185 | { | 170 | { |
186 | ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE); | 171 | ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE); |
187 | return 0; | 172 | return 0; |
188 | } | 173 | } |
189 | 174 | ||
190 | static void irq_resume(void) | 175 | static void irq_resume(void) |
191 | { | 176 | { |
192 | /* disable all irq sources */ | 177 | /* disable all irq sources */ |
193 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | 178 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); |
194 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | 179 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); |
195 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | 180 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); |
196 | 181 | ||
197 | writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET); | 182 | writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET); |
198 | } | 183 | } |
199 | #else | 184 | #else |
200 | #define irq_suspend NULL | 185 | #define irq_suspend NULL |
201 | #define irq_resume NULL | 186 | #define irq_resume NULL |
202 | #endif | 187 | #endif |
203 | 188 | ||
204 | static struct syscore_ops irq_syscore_ops = { | 189 | static struct syscore_ops irq_syscore_ops = { |
205 | .suspend = irq_suspend, | 190 | .suspend = irq_suspend, |
206 | .resume = irq_resume, | 191 | .resume = irq_resume, |
207 | }; | 192 | }; |
208 | 193 | ||
209 | static int __init irq_syscore_init(void) | 194 | static int __init irq_syscore_init(void) |
210 | { | 195 | { |
211 | register_syscore_ops(&irq_syscore_ops); | 196 | register_syscore_ops(&irq_syscore_ops); |
212 | 197 | ||
213 | return 0; | 198 | return 0; |
214 | } | 199 | } |
215 | 200 | ||
216 | device_initcall(irq_syscore_init); | 201 | device_initcall(irq_syscore_init); |
217 | 202 | ||
218 | /* | 203 | /* |
219 | * Flash handling. | 204 | * Flash handling. |
220 | */ | 205 | */ |
221 | #define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET) | 206 | #define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET) |
222 | #define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET) | 207 | #define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET) |
223 | #define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET) | 208 | #define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET) |
224 | #define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET) | 209 | #define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET) |
225 | 210 | ||
226 | static int ap_flash_init(struct platform_device *dev) | 211 | static int ap_flash_init(struct platform_device *dev) |
227 | { | 212 | { |
228 | u32 tmp; | 213 | u32 tmp; |
229 | 214 | ||
230 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); | 215 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); |
231 | 216 | ||
232 | tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; | 217 | tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; |
233 | writel(tmp, EBI_CSR1); | 218 | writel(tmp, EBI_CSR1); |
234 | 219 | ||
235 | if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { | 220 | if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { |
236 | writel(0xa05f, EBI_LOCK); | 221 | writel(0xa05f, EBI_LOCK); |
237 | writel(tmp, EBI_CSR1); | 222 | writel(tmp, EBI_CSR1); |
238 | writel(0, EBI_LOCK); | 223 | writel(0, EBI_LOCK); |
239 | } | 224 | } |
240 | return 0; | 225 | return 0; |
241 | } | 226 | } |
242 | 227 | ||
243 | static void ap_flash_exit(struct platform_device *dev) | 228 | static void ap_flash_exit(struct platform_device *dev) |
244 | { | 229 | { |
245 | u32 tmp; | 230 | u32 tmp; |
246 | 231 | ||
247 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); | 232 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); |
248 | 233 | ||
249 | tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; | 234 | tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; |
250 | writel(tmp, EBI_CSR1); | 235 | writel(tmp, EBI_CSR1); |
251 | 236 | ||
252 | if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { | 237 | if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { |
253 | writel(0xa05f, EBI_LOCK); | 238 | writel(0xa05f, EBI_LOCK); |
254 | writel(tmp, EBI_CSR1); | 239 | writel(tmp, EBI_CSR1); |
255 | writel(0, EBI_LOCK); | 240 | writel(0, EBI_LOCK); |
256 | } | 241 | } |
257 | } | 242 | } |
258 | 243 | ||
259 | static void ap_flash_set_vpp(struct platform_device *pdev, int on) | 244 | static void ap_flash_set_vpp(struct platform_device *pdev, int on) |
260 | { | 245 | { |
261 | void __iomem *reg = on ? SC_CTRLS : SC_CTRLC; | 246 | void __iomem *reg = on ? SC_CTRLS : SC_CTRLC; |
262 | 247 | ||
263 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); | 248 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); |
264 | } | 249 | } |
265 | 250 | ||
266 | static struct physmap_flash_data ap_flash_data = { | 251 | static struct physmap_flash_data ap_flash_data = { |
267 | .width = 4, | 252 | .width = 4, |
268 | .init = ap_flash_init, | 253 | .init = ap_flash_init, |
269 | .exit = ap_flash_exit, | 254 | .exit = ap_flash_exit, |
270 | .set_vpp = ap_flash_set_vpp, | 255 | .set_vpp = ap_flash_set_vpp, |
271 | }; | 256 | }; |
272 | 257 | ||
273 | static struct resource cfi_flash_resource = { | 258 | static struct resource cfi_flash_resource = { |
274 | .start = INTEGRATOR_FLASH_BASE, | 259 | .start = INTEGRATOR_FLASH_BASE, |
275 | .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, | 260 | .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, |
276 | .flags = IORESOURCE_MEM, | 261 | .flags = IORESOURCE_MEM, |
277 | }; | 262 | }; |
278 | 263 | ||
279 | static struct platform_device cfi_flash_device = { | 264 | static struct platform_device cfi_flash_device = { |
280 | .name = "physmap-flash", | 265 | .name = "physmap-flash", |
281 | .id = 0, | 266 | .id = 0, |
282 | .dev = { | 267 | .dev = { |
283 | .platform_data = &ap_flash_data, | 268 | .platform_data = &ap_flash_data, |
284 | }, | 269 | }, |
285 | .num_resources = 1, | 270 | .num_resources = 1, |
286 | .resource = &cfi_flash_resource, | 271 | .resource = &cfi_flash_resource, |
287 | }; | 272 | }; |
288 | 273 | ||
289 | static void __init ap_init(void) | 274 | static void __init ap_init(void) |
290 | { | 275 | { |
291 | unsigned long sc_dec; | 276 | unsigned long sc_dec; |
292 | int i; | 277 | int i; |
293 | 278 | ||
294 | platform_device_register(&cfi_flash_device); | 279 | platform_device_register(&cfi_flash_device); |
295 | 280 | ||
296 | sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); | 281 | sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); |
297 | for (i = 0; i < 4; i++) { | 282 | for (i = 0; i < 4; i++) { |
298 | struct lm_device *lmdev; | 283 | struct lm_device *lmdev; |
299 | 284 | ||
300 | if ((sc_dec & (16 << i)) == 0) | 285 | if ((sc_dec & (16 << i)) == 0) |
301 | continue; | 286 | continue; |
302 | 287 | ||
303 | lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); | 288 | lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); |
304 | if (!lmdev) | 289 | if (!lmdev) |
305 | continue; | 290 | continue; |
306 | 291 | ||
307 | lmdev->resource.start = 0xc0000000 + 0x10000000 * i; | 292 | lmdev->resource.start = 0xc0000000 + 0x10000000 * i; |
308 | lmdev->resource.end = lmdev->resource.start + 0x0fffffff; | 293 | lmdev->resource.end = lmdev->resource.start + 0x0fffffff; |
309 | lmdev->resource.flags = IORESOURCE_MEM; | 294 | lmdev->resource.flags = IORESOURCE_MEM; |
310 | lmdev->irq = IRQ_AP_EXPINT0 + i; | 295 | lmdev->irq = IRQ_AP_EXPINT0 + i; |
311 | lmdev->id = i; | 296 | lmdev->id = i; |
312 | 297 | ||
313 | lm_device_register(lmdev); | 298 | lm_device_register(lmdev); |
314 | } | 299 | } |
315 | 300 | ||
316 | integrator_init(false); | 301 | integrator_init(false); |
317 | } | 302 | } |
318 | 303 | ||
319 | /* | 304 | /* |
320 | * Where is the timer (VA)? | 305 | * Where is the timer (VA)? |
321 | */ | 306 | */ |
322 | #define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE) | 307 | #define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE) |
323 | #define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE) | 308 | #define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE) |
324 | #define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE) | 309 | #define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE) |
325 | 310 | ||
326 | static unsigned long timer_reload; | 311 | static unsigned long timer_reload; |
327 | 312 | ||
328 | static u32 notrace integrator_read_sched_clock(void) | 313 | static u32 notrace integrator_read_sched_clock(void) |
329 | { | 314 | { |
330 | return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); | 315 | return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); |
331 | } | 316 | } |
332 | 317 | ||
333 | static void integrator_clocksource_init(unsigned long inrate) | 318 | static void integrator_clocksource_init(unsigned long inrate, |
319 | void __iomem *base) | ||
334 | { | 320 | { |
335 | void __iomem *base = (void __iomem *)TIMER2_VA_BASE; | ||
336 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; | 321 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; |
337 | unsigned long rate = inrate; | 322 | unsigned long rate = inrate; |
338 | 323 | ||
339 | if (rate >= 1500000) { | 324 | if (rate >= 1500000) { |
340 | rate /= 16; | 325 | rate /= 16; |
341 | ctrl |= TIMER_CTRL_DIV16; | 326 | ctrl |= TIMER_CTRL_DIV16; |
342 | } | 327 | } |
343 | 328 | ||
344 | writel(0xffff, base + TIMER_LOAD); | 329 | writel(0xffff, base + TIMER_LOAD); |
345 | writel(ctrl, base + TIMER_CTRL); | 330 | writel(ctrl, base + TIMER_CTRL); |
346 | 331 | ||
347 | clocksource_mmio_init(base + TIMER_VALUE, "timer2", | 332 | clocksource_mmio_init(base + TIMER_VALUE, "timer2", |
348 | rate, 200, 16, clocksource_mmio_readl_down); | 333 | rate, 200, 16, clocksource_mmio_readl_down); |
349 | setup_sched_clock(integrator_read_sched_clock, 16, rate); | 334 | setup_sched_clock(integrator_read_sched_clock, 16, rate); |
350 | } | 335 | } |
351 | 336 | ||
352 | static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; | 337 | static void __iomem * clkevt_base; |
353 | 338 | ||
354 | /* | 339 | /* |
355 | * IRQ handler for the timer | 340 | * IRQ handler for the timer |
356 | */ | 341 | */ |
357 | static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) | 342 | static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) |
358 | { | 343 | { |
359 | struct clock_event_device *evt = dev_id; | 344 | struct clock_event_device *evt = dev_id; |
360 | 345 | ||
361 | /* clear the interrupt */ | 346 | /* clear the interrupt */ |
362 | writel(1, clkevt_base + TIMER_INTCLR); | 347 | writel(1, clkevt_base + TIMER_INTCLR); |
363 | 348 | ||
364 | evt->event_handler(evt); | 349 | evt->event_handler(evt); |
365 | 350 | ||
366 | return IRQ_HANDLED; | 351 | return IRQ_HANDLED; |
367 | } | 352 | } |
368 | 353 | ||
369 | static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) | 354 | static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) |
370 | { | 355 | { |
371 | u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; | 356 | u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; |
372 | 357 | ||
373 | /* Disable timer */ | 358 | /* Disable timer */ |
374 | writel(ctrl, clkevt_base + TIMER_CTRL); | 359 | writel(ctrl, clkevt_base + TIMER_CTRL); |
375 | 360 | ||
376 | switch (mode) { | 361 | switch (mode) { |
377 | case CLOCK_EVT_MODE_PERIODIC: | 362 | case CLOCK_EVT_MODE_PERIODIC: |
378 | /* Enable the timer and start the periodic tick */ | 363 | /* Enable the timer and start the periodic tick */ |
379 | writel(timer_reload, clkevt_base + TIMER_LOAD); | 364 | writel(timer_reload, clkevt_base + TIMER_LOAD); |
380 | ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; | 365 | ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; |
381 | writel(ctrl, clkevt_base + TIMER_CTRL); | 366 | writel(ctrl, clkevt_base + TIMER_CTRL); |
382 | break; | 367 | break; |
383 | case CLOCK_EVT_MODE_ONESHOT: | 368 | case CLOCK_EVT_MODE_ONESHOT: |
384 | /* Leave the timer disabled, .set_next_event will enable it */ | 369 | /* Leave the timer disabled, .set_next_event will enable it */ |
385 | ctrl &= ~TIMER_CTRL_PERIODIC; | 370 | ctrl &= ~TIMER_CTRL_PERIODIC; |
386 | writel(ctrl, clkevt_base + TIMER_CTRL); | 371 | writel(ctrl, clkevt_base + TIMER_CTRL); |
387 | break; | 372 | break; |
388 | case CLOCK_EVT_MODE_UNUSED: | 373 | case CLOCK_EVT_MODE_UNUSED: |
389 | case CLOCK_EVT_MODE_SHUTDOWN: | 374 | case CLOCK_EVT_MODE_SHUTDOWN: |
390 | case CLOCK_EVT_MODE_RESUME: | 375 | case CLOCK_EVT_MODE_RESUME: |
391 | default: | 376 | default: |
392 | /* Just leave in disabled state */ | 377 | /* Just leave in disabled state */ |
393 | break; | 378 | break; |
394 | } | 379 | } |
395 | 380 | ||
396 | } | 381 | } |
397 | 382 | ||
398 | static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) | 383 | static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) |
399 | { | 384 | { |
400 | unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); | 385 | unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); |
401 | 386 | ||
402 | writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | 387 | writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); |
403 | writel(next, clkevt_base + TIMER_LOAD); | 388 | writel(next, clkevt_base + TIMER_LOAD); |
404 | writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | 389 | writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); |
405 | 390 | ||
406 | return 0; | 391 | return 0; |
407 | } | 392 | } |
408 | 393 | ||
409 | static struct clock_event_device integrator_clockevent = { | 394 | static struct clock_event_device integrator_clockevent = { |
410 | .name = "timer1", | 395 | .name = "timer1", |
411 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 396 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
412 | .set_mode = clkevt_set_mode, | 397 | .set_mode = clkevt_set_mode, |
413 | .set_next_event = clkevt_set_next_event, | 398 | .set_next_event = clkevt_set_next_event, |
414 | .rating = 300, | 399 | .rating = 300, |
415 | }; | 400 | }; |
416 | 401 | ||
417 | static struct irqaction integrator_timer_irq = { | 402 | static struct irqaction integrator_timer_irq = { |
418 | .name = "timer", | 403 | .name = "timer", |
419 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 404 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
420 | .handler = integrator_timer_interrupt, | 405 | .handler = integrator_timer_interrupt, |
421 | .dev_id = &integrator_clockevent, | 406 | .dev_id = &integrator_clockevent, |
422 | }; | 407 | }; |
423 | 408 | ||
424 | static void integrator_clockevent_init(unsigned long inrate) | 409 | static void integrator_clockevent_init(unsigned long inrate, |
410 | void __iomem *base, int irq) | ||
425 | { | 411 | { |
426 | unsigned long rate = inrate; | 412 | unsigned long rate = inrate; |
427 | unsigned int ctrl = 0; | 413 | unsigned int ctrl = 0; |
428 | 414 | ||
415 | clkevt_base = base; | ||
429 | /* Calculate and program a divisor */ | 416 | /* Calculate and program a divisor */ |
430 | if (rate > 0x100000 * HZ) { | 417 | if (rate > 0x100000 * HZ) { |
431 | rate /= 256; | 418 | rate /= 256; |
432 | ctrl |= TIMER_CTRL_DIV256; | 419 | ctrl |= TIMER_CTRL_DIV256; |
433 | } else if (rate > 0x10000 * HZ) { | 420 | } else if (rate > 0x10000 * HZ) { |
434 | rate /= 16; | 421 | rate /= 16; |
435 | ctrl |= TIMER_CTRL_DIV16; | 422 | ctrl |= TIMER_CTRL_DIV16; |
436 | } | 423 | } |
437 | timer_reload = rate / HZ; | 424 | timer_reload = rate / HZ; |
438 | writel(ctrl, clkevt_base + TIMER_CTRL); | 425 | writel(ctrl, clkevt_base + TIMER_CTRL); |
439 | 426 | ||
440 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); | 427 | setup_irq(irq, &integrator_timer_irq); |
441 | clockevents_config_and_register(&integrator_clockevent, | 428 | clockevents_config_and_register(&integrator_clockevent, |
442 | rate, | 429 | rate, |
443 | 1, | 430 | 1, |
444 | 0xffffU); | 431 | 0xffffU); |
445 | } | 432 | } |
446 | 433 | ||
447 | void __init ap_init_early(void) | 434 | void __init ap_init_early(void) |
448 | { | 435 | { |
449 | } | 436 | } |
450 | 437 | ||
438 | #ifdef CONFIG_OF | ||
439 | |||
440 | static void __init ap_init_timer_of(void) | ||
441 | { | ||
442 | struct device_node *node; | ||
443 | const char *path; | ||
444 | void __iomem *base; | ||
445 | int err; | ||
446 | int irq; | ||
447 | struct clk *clk; | ||
448 | unsigned long rate; | ||
449 | |||
450 | clk = clk_get_sys("ap_timer", NULL); | ||
451 | BUG_ON(IS_ERR(clk)); | ||
452 | clk_prepare_enable(clk); | ||
453 | rate = clk_get_rate(clk); | ||
454 | |||
455 | err = of_property_read_string(of_aliases, | ||
456 | "arm,timer-primary", &path); | ||
457 | if (WARN_ON(err)) | ||
458 | return; | ||
459 | node = of_find_node_by_path(path); | ||
460 | base = of_iomap(node, 0); | ||
461 | if (WARN_ON(!base)) | ||
462 | return; | ||
463 | writel(0, base + TIMER_CTRL); | ||
464 | integrator_clocksource_init(rate, base); | ||
465 | |||
466 | err = of_property_read_string(of_aliases, | ||
467 | "arm,timer-secondary", &path); | ||
468 | if (WARN_ON(err)) | ||
469 | return; | ||
470 | node = of_find_node_by_path(path); | ||
471 | base = of_iomap(node, 0); | ||
472 | if (WARN_ON(!base)) | ||
473 | return; | ||
474 | irq = irq_of_parse_and_map(node, 0); | ||
475 | writel(0, base + TIMER_CTRL); | ||
476 | integrator_clockevent_init(rate, base, irq); | ||
477 | } | ||
478 | |||
479 | static struct sys_timer ap_of_timer = { | ||
480 | .init = ap_init_timer_of, | ||
481 | }; | ||
482 | |||
483 | static const struct of_device_id fpga_irq_of_match[] __initconst = { | ||
484 | { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, | ||
485 | { /* Sentinel */ } | ||
486 | }; | ||
487 | |||
488 | static void __init ap_init_irq_of(void) | ||
489 | { | ||
490 | /* disable core module IRQs */ | ||
491 | writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
492 | of_irq_init(fpga_irq_of_match); | ||
493 | integrator_clk_init(false); | ||
494 | } | ||
495 | |||
496 | static const char * ap_dt_board_compat[] = { | ||
497 | "arm,integrator-ap", | ||
498 | NULL, | ||
499 | }; | ||
500 | |||
501 | DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)") | ||
502 | .reserve = integrator_reserve, | ||
503 | .map_io = ap_map_io, | ||
504 | .nr_irqs = NR_IRQS_INTEGRATOR_AP, | ||
505 | .init_early = ap_init_early, | ||
506 | .init_irq = ap_init_irq_of, | ||
507 | .handle_irq = fpga_handle_irq, | ||
508 | .timer = &ap_of_timer, | ||
509 | .init_machine = ap_init, | ||
510 | .restart = integrator_restart, | ||
511 | .dt_compat = ap_dt_board_compat, | ||
512 | MACHINE_END | ||
513 | |||
514 | #endif | ||
515 | |||
516 | #ifdef CONFIG_ATAGS | ||
517 | |||
451 | /* | 518 | /* |
452 | * Set up timer(s). | 519 | * This is where non-devicetree initialization code is collected and stashed |
520 | * for eventual deletion. | ||
453 | */ | 521 | */ |
522 | |||
454 | static void __init ap_init_timer(void) | 523 | static void __init ap_init_timer(void) |
455 | { | 524 | { |
456 | struct clk *clk; | 525 | struct clk *clk; |
457 | unsigned long rate; | 526 | unsigned long rate; |
458 | 527 | ||
459 | clk = clk_get_sys("ap_timer", NULL); | 528 | clk = clk_get_sys("ap_timer", NULL); |
460 | BUG_ON(IS_ERR(clk)); | 529 | BUG_ON(IS_ERR(clk)); |
461 | clk_prepare_enable(clk); | 530 | clk_prepare_enable(clk); |
462 | rate = clk_get_rate(clk); | 531 | rate = clk_get_rate(clk); |
463 | 532 | ||
464 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); | 533 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); |
465 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); | 534 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); |
466 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); | 535 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); |
467 | 536 | ||
468 | integrator_clocksource_init(rate); | 537 | integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE); |
469 | integrator_clockevent_init(rate); | 538 | integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE, |
539 | IRQ_TIMERINT1); | ||
470 | } | 540 | } |
471 | 541 | ||
472 | static struct sys_timer ap_timer = { | 542 | static struct sys_timer ap_timer = { |
473 | .init = ap_init_timer, | 543 | .init = ap_init_timer, |
474 | }; | 544 | }; |
475 | 545 | ||
546 | #define INTEGRATOR_SC_VALID_INT 0x003fffff | ||
547 | |||
548 | static void __init ap_init_irq(void) | ||
549 | { | ||
550 | /* Disable all interrupts initially. */ | ||
551 | /* Do the core module ones */ | ||
552 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
553 | |||
554 | /* do the header card stuff next */ | ||
555 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | ||
556 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | ||
557 | |||
558 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, | ||
559 | -1, INTEGRATOR_SC_VALID_INT, NULL); | ||
560 | integrator_clk_init(false); |
arch/arm/mach-integrator/integrator_cp.c
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-integrator/integrator_cp.c | 2 | * linux/arch/arm/mach-integrator/integrator_cp.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Deep Blue Solutions Ltd | 4 | * Copyright (C) 2003 Deep Blue Solutions Ltd |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License. | 8 | * the Free Software Foundation; either version 2 of the License. |
9 | */ | 9 | */ |
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/list.h> | 13 | #include <linux/list.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/amba/bus.h> | 18 | #include <linux/amba/bus.h> |
19 | #include <linux/amba/kmi.h> | 19 | #include <linux/amba/kmi.h> |
20 | #include <linux/amba/clcd.h> | 20 | #include <linux/amba/clcd.h> |
21 | #include <linux/amba/mmci.h> | 21 | #include <linux/amba/mmci.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/gfp.h> | 23 | #include <linux/gfp.h> |
24 | #include <linux/mtd/physmap.h> | 24 | #include <linux/mtd/physmap.h> |
25 | #include <linux/platform_data/clk-integrator.h> | 25 | #include <linux/platform_data/clk-integrator.h> |
26 | #include <linux/of_irq.h> | ||
27 | #include <linux/of_address.h> | ||
26 | 28 | ||
27 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
28 | #include <mach/platform.h> | 30 | #include <mach/platform.h> |
29 | #include <asm/setup.h> | 31 | #include <asm/setup.h> |
30 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
31 | #include <asm/hardware/arm_timer.h> | 33 | #include <asm/hardware/arm_timer.h> |
32 | #include <asm/hardware/icst.h> | 34 | #include <asm/hardware/icst.h> |
33 | 35 | ||
34 | #include <mach/cm.h> | 36 | #include <mach/cm.h> |
35 | #include <mach/lm.h> | 37 | #include <mach/lm.h> |
36 | #include <mach/irqs.h> | 38 | #include <mach/irqs.h> |
37 | 39 | ||
38 | #include <asm/mach/arch.h> | 40 | #include <asm/mach/arch.h> |
39 | #include <asm/mach/irq.h> | 41 | #include <asm/mach/irq.h> |
40 | #include <asm/mach/map.h> | 42 | #include <asm/mach/map.h> |
41 | #include <asm/mach/time.h> | 43 | #include <asm/mach/time.h> |
42 | 44 | ||
43 | #include <asm/hardware/timer-sp.h> | 45 | #include <asm/hardware/timer-sp.h> |
44 | 46 | ||
45 | #include <plat/clcd.h> | 47 | #include <plat/clcd.h> |
46 | #include <plat/fpga-irq.h> | 48 | #include <plat/fpga-irq.h> |
47 | #include <plat/sched_clock.h> | 49 | #include <plat/sched_clock.h> |
48 | 50 | ||
49 | #include "common.h" | 51 | #include "common.h" |
50 | 52 | ||
51 | #define INTCP_PA_FLASH_BASE 0x24000000 | 53 | #define INTCP_PA_FLASH_BASE 0x24000000 |
52 | #define INTCP_FLASH_SIZE SZ_32M | 54 | #define INTCP_FLASH_SIZE SZ_32M |
53 | 55 | ||
54 | #define INTCP_PA_CLCD_BASE 0xc0000000 | 56 | #define INTCP_PA_CLCD_BASE 0xc0000000 |
55 | 57 | ||
56 | #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) | ||
57 | #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) | ||
58 | #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) | ||
59 | |||
60 | #define INTCP_ETH_SIZE 0x10 | 58 | #define INTCP_ETH_SIZE 0x10 |
61 | 59 | ||
62 | #define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) | 60 | #define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) |
63 | #define INTCP_FLASHPROG 0x04 | 61 | #define INTCP_FLASHPROG 0x04 |
64 | #define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) | 62 | #define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) |
65 | #define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) | 63 | #define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) |
66 | 64 | ||
67 | /* | 65 | /* |
68 | * Logical Physical | 66 | * Logical Physical |
69 | * f1000000 10000000 Core module registers | 67 | * f1000000 10000000 Core module registers |
70 | * f1100000 11000000 System controller registers | 68 | * f1100000 11000000 System controller registers |
71 | * f1200000 12000000 EBI registers | 69 | * f1200000 12000000 EBI registers |
72 | * f1300000 13000000 Counter/Timer | 70 | * f1300000 13000000 Counter/Timer |
73 | * f1400000 14000000 Interrupt controller | 71 | * f1400000 14000000 Interrupt controller |
74 | * f1600000 16000000 UART 0 | 72 | * f1600000 16000000 UART 0 |
75 | * f1700000 17000000 UART 1 | 73 | * f1700000 17000000 UART 1 |
76 | * f1a00000 1a000000 Debug LEDs | 74 | * f1a00000 1a000000 Debug LEDs |
77 | * fc900000 c9000000 GPIO | 75 | * fc900000 c9000000 GPIO |
78 | * fca00000 ca000000 SIC | 76 | * fca00000 ca000000 SIC |
79 | * fcb00000 cb000000 CP system control | 77 | * fcb00000 cb000000 CP system control |
80 | */ | 78 | */ |
81 | 79 | ||
82 | static struct map_desc intcp_io_desc[] __initdata = { | 80 | static struct map_desc intcp_io_desc[] __initdata = { |
83 | { | 81 | { |
84 | .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), | 82 | .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), |
85 | .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), | 83 | .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), |
86 | .length = SZ_4K, | 84 | .length = SZ_4K, |
87 | .type = MT_DEVICE | 85 | .type = MT_DEVICE |
88 | }, { | 86 | }, { |
89 | .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), | 87 | .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), |
90 | .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), | 88 | .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), |
91 | .length = SZ_4K, | 89 | .length = SZ_4K, |
92 | .type = MT_DEVICE | 90 | .type = MT_DEVICE |
93 | }, { | 91 | }, { |
94 | .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), | 92 | .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), |
95 | .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), | 93 | .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), |
96 | .length = SZ_4K, | 94 | .length = SZ_4K, |
97 | .type = MT_DEVICE | 95 | .type = MT_DEVICE |
98 | }, { | 96 | }, { |
99 | .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), | 97 | .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), |
100 | .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), | 98 | .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), |
101 | .length = SZ_4K, | 99 | .length = SZ_4K, |
102 | .type = MT_DEVICE | 100 | .type = MT_DEVICE |
103 | }, { | 101 | }, { |
104 | .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), | 102 | .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), |
105 | .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), | 103 | .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), |
106 | .length = SZ_4K, | 104 | .length = SZ_4K, |
107 | .type = MT_DEVICE | 105 | .type = MT_DEVICE |
108 | }, { | 106 | }, { |
109 | .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), | 107 | .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), |
110 | .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), | 108 | .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), |
111 | .length = SZ_4K, | 109 | .length = SZ_4K, |
112 | .type = MT_DEVICE | 110 | .type = MT_DEVICE |
113 | }, { | 111 | }, { |
114 | .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE), | 112 | .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE), |
115 | .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE), | 113 | .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE), |
116 | .length = SZ_4K, | 114 | .length = SZ_4K, |
117 | .type = MT_DEVICE | 115 | .type = MT_DEVICE |
118 | }, { | 116 | }, { |
119 | .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE), | 117 | .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE), |
120 | .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE), | 118 | .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE), |
121 | .length = SZ_4K, | 119 | .length = SZ_4K, |
122 | .type = MT_DEVICE | 120 | .type = MT_DEVICE |
123 | }, { | 121 | }, { |
124 | .virtual = IO_ADDRESS(INTEGRATOR_CP_GPIO_BASE), | 122 | .virtual = IO_ADDRESS(INTEGRATOR_CP_GPIO_BASE), |
125 | .pfn = __phys_to_pfn(INTEGRATOR_CP_GPIO_BASE), | 123 | .pfn = __phys_to_pfn(INTEGRATOR_CP_GPIO_BASE), |
126 | .length = SZ_4K, | 124 | .length = SZ_4K, |
127 | .type = MT_DEVICE | 125 | .type = MT_DEVICE |
128 | }, { | 126 | }, { |
129 | .virtual = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE), | 127 | .virtual = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE), |
130 | .pfn = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE), | 128 | .pfn = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE), |
131 | .length = SZ_4K, | 129 | .length = SZ_4K, |
132 | .type = MT_DEVICE | 130 | .type = MT_DEVICE |
133 | }, { | 131 | }, { |
134 | .virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE), | 132 | .virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE), |
135 | .pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE), | 133 | .pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE), |
136 | .length = SZ_4K, | 134 | .length = SZ_4K, |
137 | .type = MT_DEVICE | 135 | .type = MT_DEVICE |
138 | } | 136 | } |
139 | }; | 137 | }; |
140 | 138 | ||
141 | static void __init intcp_map_io(void) | 139 | static void __init intcp_map_io(void) |
142 | { | 140 | { |
143 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); | 141 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); |
144 | } | 142 | } |
145 | 143 | ||
146 | static void __init intcp_init_irq(void) | ||
147 | { | ||
148 | u32 pic_mask, cic_mask, sic_mask; | ||
149 | |||
150 | /* These masks are for the HW IRQ registers */ | ||
151 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | ||
152 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | ||
153 | cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); | ||
154 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | ||
155 | |||
156 | /* | ||
157 | * Disable all interrupt sources | ||
158 | */ | ||
159 | writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | ||
160 | writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); | ||
161 | writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | ||
162 | writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); | ||
163 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | ||
164 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | ||
165 | |||
166 | fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, | ||
167 | -1, pic_mask, NULL); | ||
168 | |||
169 | fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, | ||
170 | -1, cic_mask, NULL); | ||
171 | |||
172 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, | ||
173 | IRQ_CP_CPPLDINT, sic_mask, NULL); | ||
174 | integrator_clk_init(true); | ||
175 | } | ||
176 | |||
177 | /* | 144 | /* |
178 | * Flash handling. | 145 | * Flash handling. |
179 | */ | 146 | */ |
180 | static int intcp_flash_init(struct platform_device *dev) | 147 | static int intcp_flash_init(struct platform_device *dev) |
181 | { | 148 | { |
182 | u32 val; | 149 | u32 val; |
183 | 150 | ||
184 | val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); | 151 | val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); |
185 | val |= CINTEGRATOR_FLASHPROG_FLWREN; | 152 | val |= CINTEGRATOR_FLASHPROG_FLWREN; |
186 | writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); | 153 | writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); |
187 | 154 | ||
188 | return 0; | 155 | return 0; |
189 | } | 156 | } |
190 | 157 | ||
191 | static void intcp_flash_exit(struct platform_device *dev) | 158 | static void intcp_flash_exit(struct platform_device *dev) |
192 | { | 159 | { |
193 | u32 val; | 160 | u32 val; |
194 | 161 | ||
195 | val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); | 162 | val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); |
196 | val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN); | 163 | val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN); |
197 | writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); | 164 | writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); |
198 | } | 165 | } |
199 | 166 | ||
200 | static void intcp_flash_set_vpp(struct platform_device *pdev, int on) | 167 | static void intcp_flash_set_vpp(struct platform_device *pdev, int on) |
201 | { | 168 | { |
202 | u32 val; | 169 | u32 val; |
203 | 170 | ||
204 | val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); | 171 | val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); |
205 | if (on) | 172 | if (on) |
206 | val |= CINTEGRATOR_FLASHPROG_FLVPPEN; | 173 | val |= CINTEGRATOR_FLASHPROG_FLVPPEN; |
207 | else | 174 | else |
208 | val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN; | 175 | val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN; |
209 | writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); | 176 | writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); |
210 | } | 177 | } |
211 | 178 | ||
212 | static struct physmap_flash_data intcp_flash_data = { | 179 | static struct physmap_flash_data intcp_flash_data = { |
213 | .width = 4, | 180 | .width = 4, |
214 | .init = intcp_flash_init, | 181 | .init = intcp_flash_init, |
215 | .exit = intcp_flash_exit, | 182 | .exit = intcp_flash_exit, |
216 | .set_vpp = intcp_flash_set_vpp, | 183 | .set_vpp = intcp_flash_set_vpp, |
217 | }; | 184 | }; |
218 | 185 | ||
219 | static struct resource intcp_flash_resource = { | 186 | static struct resource intcp_flash_resource = { |
220 | .start = INTCP_PA_FLASH_BASE, | 187 | .start = INTCP_PA_FLASH_BASE, |
221 | .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, | 188 | .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, |
222 | .flags = IORESOURCE_MEM, | 189 | .flags = IORESOURCE_MEM, |
223 | }; | 190 | }; |
224 | 191 | ||
225 | static struct platform_device intcp_flash_device = { | 192 | static struct platform_device intcp_flash_device = { |
226 | .name = "physmap-flash", | 193 | .name = "physmap-flash", |
227 | .id = 0, | 194 | .id = 0, |
228 | .dev = { | 195 | .dev = { |
229 | .platform_data = &intcp_flash_data, | 196 | .platform_data = &intcp_flash_data, |
230 | }, | 197 | }, |
231 | .num_resources = 1, | 198 | .num_resources = 1, |
232 | .resource = &intcp_flash_resource, | 199 | .resource = &intcp_flash_resource, |
233 | }; | 200 | }; |
234 | 201 | ||
235 | static struct resource smc91x_resources[] = { | 202 | static struct resource smc91x_resources[] = { |
236 | [0] = { | 203 | [0] = { |
237 | .start = INTEGRATOR_CP_ETH_BASE, | 204 | .start = INTEGRATOR_CP_ETH_BASE, |
238 | .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, | 205 | .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, |
239 | .flags = IORESOURCE_MEM, | 206 | .flags = IORESOURCE_MEM, |
240 | }, | 207 | }, |
241 | [1] = { | 208 | [1] = { |
242 | .start = IRQ_CP_ETHINT, | 209 | .start = IRQ_CP_ETHINT, |
243 | .end = IRQ_CP_ETHINT, | 210 | .end = IRQ_CP_ETHINT, |
244 | .flags = IORESOURCE_IRQ, | 211 | .flags = IORESOURCE_IRQ, |
245 | }, | 212 | }, |
246 | }; | 213 | }; |
247 | 214 | ||
248 | static struct platform_device smc91x_device = { | 215 | static struct platform_device smc91x_device = { |
249 | .name = "smc91x", | 216 | .name = "smc91x", |
250 | .id = 0, | 217 | .id = 0, |
251 | .num_resources = ARRAY_SIZE(smc91x_resources), | 218 | .num_resources = ARRAY_SIZE(smc91x_resources), |
252 | .resource = smc91x_resources, | 219 | .resource = smc91x_resources, |
253 | }; | 220 | }; |
254 | 221 | ||
255 | static struct platform_device *intcp_devs[] __initdata = { | 222 | static struct platform_device *intcp_devs[] __initdata = { |
256 | &intcp_flash_device, | 223 | &intcp_flash_device, |
257 | &smc91x_device, | 224 | &smc91x_device, |
258 | }; | 225 | }; |
259 | 226 | ||
260 | /* | 227 | /* |
261 | * It seems that the card insertion interrupt remains active after | 228 | * It seems that the card insertion interrupt remains active after |
262 | * we've acknowledged it. We therefore ignore the interrupt, and | 229 | * we've acknowledged it. We therefore ignore the interrupt, and |
263 | * rely on reading it from the SIC. This also means that we must | 230 | * rely on reading it from the SIC. This also means that we must |
264 | * clear the latched interrupt. | 231 | * clear the latched interrupt. |
265 | */ | 232 | */ |
266 | static unsigned int mmc_status(struct device *dev) | 233 | static unsigned int mmc_status(struct device *dev) |
267 | { | 234 | { |
268 | unsigned int status = readl(IO_ADDRESS(0xca000000 + 4)); | 235 | unsigned int status = readl(IO_ADDRESS(0xca000000 + 4)); |
269 | writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8)); | 236 | writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8)); |
270 | 237 | ||
271 | return status & 8; | 238 | return status & 8; |
272 | } | 239 | } |
273 | 240 | ||
274 | static struct mmci_platform_data mmc_data = { | 241 | static struct mmci_platform_data mmc_data = { |
275 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 242 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
276 | .status = mmc_status, | 243 | .status = mmc_status, |
277 | .gpio_wp = -1, | 244 | .gpio_wp = -1, |
278 | .gpio_cd = -1, | 245 | .gpio_cd = -1, |
279 | }; | 246 | }; |
280 | 247 | ||
281 | #define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } | 248 | #define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } |
282 | #define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } | 249 | #define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } |
283 | 250 | ||
284 | static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, | 251 | static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, |
285 | INTEGRATOR_CP_MMC_IRQS, &mmc_data); | 252 | INTEGRATOR_CP_MMC_IRQS, &mmc_data); |
286 | 253 | ||
287 | static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, | 254 | static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, |
288 | INTEGRATOR_CP_AACI_IRQS, NULL); | 255 | INTEGRATOR_CP_AACI_IRQS, NULL); |
289 | 256 | ||
290 | 257 | ||
291 | /* | 258 | /* |
292 | * CLCD support | 259 | * CLCD support |
293 | */ | 260 | */ |
294 | /* | 261 | /* |
295 | * Ensure VGA is selected. | 262 | * Ensure VGA is selected. |
296 | */ | 263 | */ |
297 | static void cp_clcd_enable(struct clcd_fb *fb) | 264 | static void cp_clcd_enable(struct clcd_fb *fb) |
298 | { | 265 | { |
299 | struct fb_var_screeninfo *var = &fb->fb.var; | 266 | struct fb_var_screeninfo *var = &fb->fb.var; |
300 | u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2; | 267 | u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2; |
301 | 268 | ||
302 | if (var->bits_per_pixel <= 8 || | 269 | if (var->bits_per_pixel <= 8 || |
303 | (var->bits_per_pixel == 16 && var->green.length == 5)) | 270 | (var->bits_per_pixel == 16 && var->green.length == 5)) |
304 | /* Pseudocolor, RGB555, BGR555 */ | 271 | /* Pseudocolor, RGB555, BGR555 */ |
305 | val |= CM_CTRL_LCDMUXSEL_VGA555_TFT555; | 272 | val |= CM_CTRL_LCDMUXSEL_VGA555_TFT555; |
306 | else if (fb->fb.var.bits_per_pixel <= 16) | 273 | else if (fb->fb.var.bits_per_pixel <= 16) |
307 | /* truecolor RGB565 */ | 274 | /* truecolor RGB565 */ |
308 | val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555; | 275 | val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555; |
309 | else | 276 | else |
310 | val = 0; /* no idea for this, don't trust the docs */ | 277 | val = 0; /* no idea for this, don't trust the docs */ |
311 | 278 | ||
312 | cm_control(CM_CTRL_LCDMUXSEL_MASK| | 279 | cm_control(CM_CTRL_LCDMUXSEL_MASK| |
313 | CM_CTRL_LCDEN0| | 280 | CM_CTRL_LCDEN0| |
314 | CM_CTRL_LCDEN1| | 281 | CM_CTRL_LCDEN1| |
315 | CM_CTRL_STATIC1| | 282 | CM_CTRL_STATIC1| |
316 | CM_CTRL_STATIC2| | 283 | CM_CTRL_STATIC2| |
317 | CM_CTRL_STATIC| | 284 | CM_CTRL_STATIC| |
318 | CM_CTRL_n24BITEN, val); | 285 | CM_CTRL_n24BITEN, val); |
319 | } | 286 | } |
320 | 287 | ||
321 | static int cp_clcd_setup(struct clcd_fb *fb) | 288 | static int cp_clcd_setup(struct clcd_fb *fb) |
322 | { | 289 | { |
323 | fb->panel = versatile_clcd_get_panel("VGA"); | 290 | fb->panel = versatile_clcd_get_panel("VGA"); |
324 | if (!fb->panel) | 291 | if (!fb->panel) |
325 | return -EINVAL; | 292 | return -EINVAL; |
326 | 293 | ||
327 | return versatile_clcd_setup_dma(fb, SZ_1M); | 294 | return versatile_clcd_setup_dma(fb, SZ_1M); |
328 | } | 295 | } |
329 | 296 | ||
330 | static struct clcd_board clcd_data = { | 297 | static struct clcd_board clcd_data = { |
331 | .name = "Integrator/CP", | 298 | .name = "Integrator/CP", |
332 | .caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888, | 299 | .caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888, |
333 | .check = clcdfb_check, | 300 | .check = clcdfb_check, |
334 | .decode = clcdfb_decode, | 301 | .decode = clcdfb_decode, |
335 | .enable = cp_clcd_enable, | 302 | .enable = cp_clcd_enable, |
336 | .setup = cp_clcd_setup, | 303 | .setup = cp_clcd_setup, |
337 | .mmap = versatile_clcd_mmap_dma, | 304 | .mmap = versatile_clcd_mmap_dma, |
338 | .remove = versatile_clcd_remove_dma, | 305 | .remove = versatile_clcd_remove_dma, |
339 | }; | 306 | }; |
340 | 307 | ||
341 | static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, | 308 | static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, |
342 | { IRQ_CP_CLCDCINT }, &clcd_data); | 309 | { IRQ_CP_CLCDCINT }, &clcd_data); |
343 | 310 | ||
344 | static struct amba_device *amba_devs[] __initdata = { | 311 | static struct amba_device *amba_devs[] __initdata = { |
345 | &mmc_device, | 312 | &mmc_device, |
346 | &aaci_device, | 313 | &aaci_device, |
347 | &clcd_device, | 314 | &clcd_device, |
348 | }; | 315 | }; |
349 | 316 | ||
350 | #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28) | 317 | #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28) |
351 | 318 | ||
352 | static void __init intcp_init_early(void) | 319 | static void __init intcp_init_early(void) |
353 | { | 320 | { |
354 | #ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK | 321 | #ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK |
355 | versatile_sched_clock_init(REFCOUNTER, 24000000); | 322 | versatile_sched_clock_init(REFCOUNTER, 24000000); |
356 | #endif | 323 | #endif |
357 | } | 324 | } |
358 | 325 | ||
359 | static void __init intcp_init(void) | 326 | static void __init intcp_timer_init_of(void) |
360 | { | 327 | { |
361 | int i; | 328 | struct device_node *node; |
329 | const char *path; | ||
330 | void __iomem *base; | ||
331 | int err; | ||
332 | int irq; | ||
362 | 333 | ||
363 | platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); | 334 | err = of_property_read_string(of_aliases, |
335 | "arm,timer-primary", &path); | ||
336 | if (WARN_ON(err)) | ||
337 | return; | ||
338 | node = of_find_node_by_path(path); | ||
339 | base = of_iomap(node, 0); | ||
340 | if (WARN_ON(!base)) | ||
341 | return; | ||
342 | writel(0, base + TIMER_CTRL); | ||
343 | sp804_clocksource_init(base, node->name); | ||
364 | 344 | ||
365 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 345 | err = of_property_read_string(of_aliases, |
366 | struct amba_device *d = amba_devs[i]; | 346 | "arm,timer-secondary", &path); |
367 | amba_device_register(d, &iomem_resource); | 347 | if (WARN_ON(err)) |
368 | } | 348 | return; |
369 | integrator_init(true); | 349 | node = of_find_node_by_path(path); |
350 | base = of_iomap(node, 0); | ||
351 | if (WARN_ON(!base)) | ||
352 | return; | ||
353 | irq = irq_of_parse_and_map(node, 0); | ||
354 | writel(0, base + TIMER_CTRL); | ||
355 | sp804_clockevents_init(base, irq, node->name); | ||
370 | } | 356 | } |
371 | 357 | ||
358 | static struct sys_timer cp_of_timer = { | ||
359 | .init = intcp_timer_init_of, | ||
360 | }; | ||
361 | |||
362 | #ifdef CONFIG_OF | ||
363 | |||
364 | static const struct of_device_id fpga_irq_of_match[] __initconst = { | ||
365 | { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, | ||
366 | { /* Sentinel */ } | ||
367 | }; | ||
368 | |||
369 | static void __init intcp_init_irq_of(void) | ||
370 | { | ||
371 | of_irq_init(fpga_irq_of_match); | ||
372 | integrator_clk_init(true); | ||
373 | } | ||
374 | |||
375 | static const char * intcp_dt_board_compat[] = { | ||
376 | "arm,integrator-cp", | ||
377 | NULL, | ||
378 | }; | ||
379 | |||
380 | DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") | ||
381 | .reserve = integrator_reserve, | ||
382 | .map_io = intcp_map_io, | ||
383 | .nr_irqs = NR_IRQS_INTEGRATOR_CP, | ||
384 | .init_early = intcp_init_early, | ||
385 | .init_irq = intcp_init_irq_of, | ||
386 | .handle_irq = fpga_handle_irq, | ||
387 | .timer = &cp_of_timer, | ||
388 | .init_machine = intcp_init, | ||
389 | .restart = integrator_restart, | ||
390 | .dt_compat = intcp_dt_board_compat, | ||
391 | MACHINE_END | ||
392 | |||
393 | #endif | ||
394 | |||
395 | #ifdef CONFIG_ATAGS | ||
396 | |||
397 | /* | ||
398 | * This is where non-devicetree initialization code is collected and stashed | ||
399 | * for eventual deletion. | ||
400 | */ | ||
401 | |||
402 | #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) | ||
403 | #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) | ||
404 | #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) | ||
405 | |||
406 | static void __init intcp_init_irq(void) | ||
407 | { | ||
408 | u32 pic_mask, cic_mask, sic_mask; | ||
409 | |||
410 | /* These masks are for the HW IRQ registers */ | ||
411 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | ||
412 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | ||
413 | cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); | ||
414 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | ||
415 | |||
416 | /* | ||
417 | * Disable all interrupt sources | ||
418 | */ | ||
419 | writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | ||
420 | writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); | ||
421 | writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | ||
422 | writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); | ||
423 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | ||
424 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | ||
425 | |||
426 | fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, | ||
427 | -1, pic_mask, NULL); | ||
428 | |||
429 | fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, | ||
430 | -1, cic_mask, NULL); | ||
431 | |||
432 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, | ||
433 | IRQ_CP_CPPLDINT, sic_mask, NULL); | ||
434 | |||
435 | integrator_clk_init(true); | ||
436 | } |