summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/vexpress-sysreg.txt50
-rw-r--r--Documentation/devicetree/bindings/arm/vexpress.txt98
-rw-r--r--arch/arm/boot/dts/vexpress-v2m-rs1.dtsi146
-rw-r--r--arch/arm/boot/dts/vexpress-v2m.dtsi146
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts121
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts186
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca5s.dts84
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca9.dts136
-rw-r--r--arch/arm/include/asm/hardware/sp810.h6
-rw-r--r--arch/arm/mach-vexpress/Kconfig4
-rw-r--r--arch/arm/mach-vexpress/Makefile2
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c41
-rw-r--r--arch/arm/mach-vexpress/include/mach/motherboard.h81
-rw-r--r--arch/arm/mach-vexpress/platsmp.c3
-rw-r--r--arch/arm/mach-vexpress/v2m.c349
-rw-r--r--drivers/mfd/Kconfig6
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/vexpress-config.c277
-rw-r--r--drivers/mfd/vexpress-sysreg.c552
-rw-r--r--include/linux/vexpress.h121
20 files changed, 1993 insertions, 417 deletions
diff --git a/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
new file mode 100644
index 000000000000..9cf3f25544c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
@@ -0,0 +1,50 @@
1ARM Versatile Express system registers
2--------------------------------------
3
4This is a system control registers block, providing multiple low level
5platform functions like board detection and identification, software
6interrupt generation, MMC and NOR Flash control etc.
7
8Required node properties:
9- compatible value : = "arm,vexpress,sysreg";
10- reg : physical base address and the size of the registers window
11- gpio-controller : specifies that the node is a GPIO controller
12- #gpio-cells : size of the GPIO specifier, should be 2:
13 - first cell is the pseudo-GPIO line number:
14 0 - MMC CARDIN
15 1 - MMC WPROT
16 2 - NOR FLASH WPn
17 - second cell can take standard GPIO flags (currently ignored).
18
19Example:
20 v2m_sysreg: sysreg@10000000 {
21 compatible = "arm,vexpress-sysreg";
22 reg = <0x10000000 0x1000>;
23 gpio-controller;
24 #gpio-cells = <2>;
25 };
26
27This block also can also act a bridge to the platform's configuration
28bus via "system control" interface, addressing devices with site number,
29position in the board stack, config controller, function and device
30numbers - see motherboard's TRM for more details.
31
32The node describing a config device must refer to the sysreg node via
33"arm,vexpress,config-bridge" phandle (can be also defined in the node's
34parent) and relies on the board topology properties - see main vexpress
35node documentation for more details. It must must also define the
36following property:
37- arm,vexpress-sysreg,func : must contain two cells:
38 - first cell defines function number (eg. 1 for clock generator,
39 2 for voltage regulators etc.)
40 - device number (eg. osc 0, osc 1 etc.)
41
42Example:
43 mcc {
44 arm,vexpress,config-bridge = <&v2m_sysreg>;
45
46 osc@0 {
47 compatible = "arm,vexpress-osc";
48 arm,vexpress-sysreg,func = <1 0>;
49 };
50 };
diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
index ec8b50cbb2e8..ae49161e478a 100644
--- a/Documentation/devicetree/bindings/arm/vexpress.txt
+++ b/Documentation/devicetree/bindings/arm/vexpress.txt
@@ -11,6 +11,10 @@ the motherboard file using a /include/ directive. As the motherboard
11can be initialized in one of two different configurations ("memory 11can be initialized in one of two different configurations ("memory
12maps"), care must be taken to include the correct one. 12maps"), care must be taken to include the correct one.
13 13
14
15Root node
16---------
17
14Required properties in the root node: 18Required properties in the root node:
15- compatible value: 19- compatible value:
16 compatible = "arm,vexpress,<model>", "arm,vexpress"; 20 compatible = "arm,vexpress,<model>", "arm,vexpress";
@@ -45,6 +49,10 @@ Optional properties in the root node:
45 - Coretile Express A9x4 (V2P-CA9) HBI-0225: 49 - Coretile Express A9x4 (V2P-CA9) HBI-0225:
46 arm,hbi = <0x225>; 50 arm,hbi = <0x225>;
47 51
52
53CPU nodes
54---------
55
48Top-level standard "cpus" node is required. It must contain a node 56Top-level standard "cpus" node is required. It must contain a node
49with device_type = "cpu" property for every available core, eg.: 57with device_type = "cpu" property for every available core, eg.:
50 58
@@ -59,6 +67,52 @@ with device_type = "cpu" property for every available core, eg.:
59 }; 67 };
60 }; 68 };
61 69
70
71Configuration infrastructure
72----------------------------
73
74The platform has an elaborated configuration system, consisting of
75microcontrollers residing on the mother- and daughterboards known
76as Motherboard/Daughterboard Configuration Controller (MCC and DCC).
77The controllers are responsible for the platform initialization
78(reset generation, flash programming, FPGA bitfiles loading etc.)
79but also control clock generators, voltage regulators, gather
80environmental data like temperature, power consumption etc. Even
81the video output switch (FPGA) is controlled that way.
82
83Nodes describing devices controlled by this infrastructure should
84point at the bridge device node:
85- bridge phandle:
86 arm,vexpress,config-bridge = <phandle>;
87This property can be also defined in a parent node (eg. for a DCC)
88and is effective for all children.
89
90
91Platform topology
92-----------------
93
94As Versatile Express can be configured in number of physically
95different setups, the device tree should describe platform topology.
96Root node and main motherboard node must define the following
97property, describing physical location of the children nodes:
98- site number:
99 arm,vexpress,site = <number>;
100 where 0 means motherboard, 1 or 2 are daugtherboard sites,
101 0xf means "master" site (site containing main CPU tile)
102- when daughterboards are stacked on one site, their position
103 in the stack be be described with:
104 arm,vexpress,position = <number>;
105- when describing tiles consisting more than one DCC, its number
106 can be described with:
107 arm,vexpress,dcc = <number>;
108
109Any of the numbers above defaults to zero if not defined in
110the node or any of its parent.
111
112
113Motherboard
114-----------
115
62The motherboard description file provides a single "motherboard" node 116The motherboard description file provides a single "motherboard" node
63using 2 address cells corresponding to the Static Memory Bus used 117using 2 address cells corresponding to the Static Memory Bus used
64between the motherboard and the tile. The first cell defines the Chip 118between the motherboard and the tile. The first cell defines the Chip
@@ -87,22 +141,30 @@ can be used to obtain required phandle in the tile's "aliases" node:
87- SP804 timers: 141- SP804 timers:
88 v2m_timer01 and v2m_timer23 142 v2m_timer01 and v2m_timer23
89 143
90Current Linux implementation requires a "arm,v2m_timer" alias 144The tile description should define a "smb" node, describing the
91pointing at one of the motherboard's SP804 timers, if it is to be 145Static Memory Bus between the tile and motherboard. It must define
92used as the system timer. This alias should be defined in the 146the following properties:
93motherboard files. 147- "simple-bus" compatible value (to ensure creation of the children)
148 compatible = "simple-bus";
149- mapping of the SMB CS/offset addresses into main address space:
150 #address-cells = <2>;
151 #size-cells = <1>;
152 ranges = <...>;
153- interrupts mapping:
154 #interrupt-cells = <1>;
155 interrupt-map-mask = <0 0 63>;
156 interrupt-map = <...>;
94 157
95The tile description must define "ranges", "interrupt-map-mask" and
96"interrupt-map" properties to translate the motherboard's address
97and interrupt space into one used by the tile's processor.
98 158
99Abbreviated example: 159Example of a VE tile description (simplified)
160---------------------------------------------
100 161
101/dts-v1/; 162/dts-v1/;
102 163
103/ { 164/ {
104 model = "V2P-CA5s"; 165 model = "V2P-CA5s";
105 arm,hbi = <0x225>; 166 arm,hbi = <0x225>;
167 arm,vexpress,site = <0xf>;
106 compatible = "arm,vexpress-v2p-ca5s", "arm,vexpress"; 168 compatible = "arm,vexpress-v2p-ca5s", "arm,vexpress";
107 interrupt-parent = <&gic>; 169 interrupt-parent = <&gic>;
108 #address-cells = <1>; 170 #address-cells = <1>;
@@ -134,13 +196,29 @@ Abbreviated example:
134 <0x2c000100 0x100>; 196 <0x2c000100 0x100>;
135 }; 197 };
136 198
137 motherboard { 199 dcc {
200 compatible = "simple-bus";
201 arm,vexpress,config-bridge = <&v2m_sysreg>;
202
203 osc@0 {
204 compatible = "arm,vexpress-osc";
205 };
206 };
207
208 smb {
209 compatible = "simple-bus";
210
211 #address-cells = <2>;
212 #size-cells = <1>;
138 /* CS0 is visible at 0x08000000 */ 213 /* CS0 is visible at 0x08000000 */
139 ranges = <0 0 0x08000000 0x04000000>; 214 ranges = <0 0 0x08000000 0x04000000>;
215
216 #interrupt-cells = <1>;
140 interrupt-map-mask = <0 0 63>; 217 interrupt-map-mask = <0 0 63>;
141 /* Active high IRQ 0 is connected to GIC's SPI0 */ 218 /* Active high IRQ 0 is connected to GIC's SPI0 */
142 interrupt-map = <0 0 0 &gic 0 0 4>; 219 interrupt-map = <0 0 0 &gic 0 0 4>;
220
221 /include/ "vexpress-v2m-rs1.dtsi"
143 }; 222 };
144}; 223};
145 224
146/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index d8a827bd2bf3..ac870fb3fa0d 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -17,17 +17,16 @@
17 * CHANGES TO vexpress-v2m.dtsi! 17 * CHANGES TO vexpress-v2m.dtsi!
18 */ 18 */
19 19
20/ {
21 aliases {
22 arm,v2m_timer = &v2m_timer01;
23 };
24
25 motherboard { 20 motherboard {
26 compatible = "simple-bus"; 21 model = "V2M-P1";
22 arm,hbi = <0x190>;
23 arm,vexpress,site = <0>;
27 arm,v2m-memory-map = "rs1"; 24 arm,v2m-memory-map = "rs1";
25 compatible = "arm,vexpress,v2m-p1", "simple-bus";
28 #address-cells = <2>; /* SMB chipselect number and offset */ 26 #address-cells = <2>; /* SMB chipselect number and offset */
29 #size-cells = <1>; 27 #size-cells = <1>;
30 #interrupt-cells = <1>; 28 #interrupt-cells = <1>;
29 ranges;
31 30
32 flash@0,00000000 { 31 flash@0,00000000 {
33 compatible = "arm,vexpress-flash", "cfi-flash"; 32 compatible = "arm,vexpress-flash", "cfi-flash";
@@ -72,14 +71,20 @@
72 #size-cells = <1>; 71 #size-cells = <1>;
73 ranges = <0 3 0 0x200000>; 72 ranges = <0 3 0 0x200000>;
74 73
75 sysreg@010000 { 74 v2m_sysreg: sysreg@010000 {
76 compatible = "arm,vexpress-sysreg"; 75 compatible = "arm,vexpress-sysreg";
77 reg = <0x010000 0x1000>; 76 reg = <0x010000 0x1000>;
77 gpio-controller;
78 #gpio-cells = <2>;
78 }; 79 };
79 80
80 sysctl@020000 { 81 v2m_sysctl: sysctl@020000 {
81 compatible = "arm,sp810", "arm,primecell"; 82 compatible = "arm,sp810", "arm,primecell";
82 reg = <0x020000 0x1000>; 83 reg = <0x020000 0x1000>;
84 clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
85 clock-names = "refclk", "timclk", "apb_pclk";
86 #clock-cells = <1>;
87 clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
83 }; 88 };
84 89
85 /* PCI-E I2C bus */ 90 /* PCI-E I2C bus */
@@ -100,66 +105,92 @@
100 compatible = "arm,pl041", "arm,primecell"; 105 compatible = "arm,pl041", "arm,primecell";
101 reg = <0x040000 0x1000>; 106 reg = <0x040000 0x1000>;
102 interrupts = <11>; 107 interrupts = <11>;
108 clocks = <&smbclk>;
109 clock-names = "apb_pclk";
103 }; 110 };
104 111
105 mmci@050000 { 112 mmci@050000 {
106 compatible = "arm,pl180", "arm,primecell"; 113 compatible = "arm,pl180", "arm,primecell";
107 reg = <0x050000 0x1000>; 114 reg = <0x050000 0x1000>;
108 interrupts = <9 10>; 115 interrupts = <9 10>;
116 cd-gpios = <&v2m_sysreg 0 0>;
117 wp-gpios = <&v2m_sysreg 1 0>;
118 max-frequency = <12000000>;
119 vmmc-supply = <&v2m_fixed_3v3>;
120 clocks = <&v2m_clk24mhz>, <&smbclk>;
121 clock-names = "mclk", "apb_pclk";
109 }; 122 };
110 123
111 kmi@060000 { 124 kmi@060000 {
112 compatible = "arm,pl050", "arm,primecell"; 125 compatible = "arm,pl050", "arm,primecell";
113 reg = <0x060000 0x1000>; 126 reg = <0x060000 0x1000>;
114 interrupts = <12>; 127 interrupts = <12>;
128 clocks = <&v2m_clk24mhz>, <&smbclk>;
129 clock-names = "KMIREFCLK", "apb_pclk";
115 }; 130 };
116 131
117 kmi@070000 { 132 kmi@070000 {
118 compatible = "arm,pl050", "arm,primecell"; 133 compatible = "arm,pl050", "arm,primecell";
119 reg = <0x070000 0x1000>; 134 reg = <0x070000 0x1000>;
120 interrupts = <13>; 135 interrupts = <13>;
136 clocks = <&v2m_clk24mhz>, <&smbclk>;
137 clock-names = "KMIREFCLK", "apb_pclk";
121 }; 138 };
122 139
123 v2m_serial0: uart@090000 { 140 v2m_serial0: uart@090000 {
124 compatible = "arm,pl011", "arm,primecell"; 141 compatible = "arm,pl011", "arm,primecell";
125 reg = <0x090000 0x1000>; 142 reg = <0x090000 0x1000>;
126 interrupts = <5>; 143 interrupts = <5>;
144 clocks = <&v2m_oscclk2>, <&smbclk>;
145 clock-names = "uartclk", "apb_pclk";
127 }; 146 };
128 147
129 v2m_serial1: uart@0a0000 { 148 v2m_serial1: uart@0a0000 {
130 compatible = "arm,pl011", "arm,primecell"; 149 compatible = "arm,pl011", "arm,primecell";
131 reg = <0x0a0000 0x1000>; 150 reg = <0x0a0000 0x1000>;
132 interrupts = <6>; 151 interrupts = <6>;
152 clocks = <&v2m_oscclk2>, <&smbclk>;
153 clock-names = "uartclk", "apb_pclk";
133 }; 154 };
134 155
135 v2m_serial2: uart@0b0000 { 156 v2m_serial2: uart@0b0000 {
136 compatible = "arm,pl011", "arm,primecell"; 157 compatible = "arm,pl011", "arm,primecell";
137 reg = <0x0b0000 0x1000>; 158 reg = <0x0b0000 0x1000>;
138 interrupts = <7>; 159 interrupts = <7>;
160 clocks = <&v2m_oscclk2>, <&smbclk>;
161 clock-names = "uartclk", "apb_pclk";
139 }; 162 };
140 163
141 v2m_serial3: uart@0c0000 { 164 v2m_serial3: uart@0c0000 {
142 compatible = "arm,pl011", "arm,primecell"; 165 compatible = "arm,pl011", "arm,primecell";
143 reg = <0x0c0000 0x1000>; 166 reg = <0x0c0000 0x1000>;
144 interrupts = <8>; 167 interrupts = <8>;
168 clocks = <&v2m_oscclk2>, <&smbclk>;
169 clock-names = "uartclk", "apb_pclk";
145 }; 170 };
146 171
147 wdt@0f0000 { 172 wdt@0f0000 {
148 compatible = "arm,sp805", "arm,primecell"; 173 compatible = "arm,sp805", "arm,primecell";
149 reg = <0x0f0000 0x1000>; 174 reg = <0x0f0000 0x1000>;
150 interrupts = <0>; 175 interrupts = <0>;
176 clocks = <&v2m_refclk32khz>, <&smbclk>;
177 clock-names = "wdogclk", "apb_pclk";
151 }; 178 };
152 179
153 v2m_timer01: timer@110000 { 180 v2m_timer01: timer@110000 {
154 compatible = "arm,sp804", "arm,primecell"; 181 compatible = "arm,sp804", "arm,primecell";
155 reg = <0x110000 0x1000>; 182 reg = <0x110000 0x1000>;
156 interrupts = <2>; 183 interrupts = <2>;
184 clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
185 clock-names = "timclken1", "timclken2", "apb_pclk";
157 }; 186 };
158 187
159 v2m_timer23: timer@120000 { 188 v2m_timer23: timer@120000 {
160 compatible = "arm,sp804", "arm,primecell"; 189 compatible = "arm,sp804", "arm,primecell";
161 reg = <0x120000 0x1000>; 190 reg = <0x120000 0x1000>;
162 interrupts = <3>; 191 interrupts = <3>;
192 clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
193 clock-names = "timclken1", "timclken2", "apb_pclk";
163 }; 194 };
164 195
165 /* DVI I2C bus */ 196 /* DVI I2C bus */
@@ -185,6 +216,8 @@
185 compatible = "arm,pl031", "arm,primecell"; 216 compatible = "arm,pl031", "arm,primecell";
186 reg = <0x170000 0x1000>; 217 reg = <0x170000 0x1000>;
187 interrupts = <4>; 218 interrupts = <4>;
219 clocks = <&smbclk>;
220 clock-names = "apb_pclk";
188 }; 221 };
189 222
190 compact-flash@1a0000 { 223 compact-flash@1a0000 {
@@ -198,6 +231,8 @@
198 compatible = "arm,pl111", "arm,primecell"; 231 compatible = "arm,pl111", "arm,primecell";
199 reg = <0x1f0000 0x1000>; 232 reg = <0x1f0000 0x1000>;
200 interrupts = <14>; 233 interrupts = <14>;
234 clocks = <&v2m_oscclk1>, <&smbclk>;
235 clock-names = "clcdclk", "apb_pclk";
201 }; 236 };
202 }; 237 };
203 238
@@ -208,5 +243,98 @@
208 regulator-max-microvolt = <3300000>; 243 regulator-max-microvolt = <3300000>;
209 regulator-always-on; 244 regulator-always-on;
210 }; 245 };
246
247 v2m_clk24mhz: clk24mhz {
248 compatible = "fixed-clock";
249 #clock-cells = <0>;
250 clock-frequency = <24000000>;
251 clock-output-names = "v2m:clk24mhz";
252 };
253
254 v2m_refclk1mhz: refclk1mhz {
255 compatible = "fixed-clock";
256 #clock-cells = <0>;
257 clock-frequency = <1000000>;
258 clock-output-names = "v2m:refclk1mhz";
259 };
260
261 v2m_refclk32khz: refclk32khz {
262 compatible = "fixed-clock";
263 #clock-cells = <0>;
264 clock-frequency = <32768>;
265 clock-output-names = "v2m:refclk32khz";
266 };
267
268 mcc {
269 compatible = "arm,vexpress,config-bus";
270 arm,vexpress,config-bridge = <&v2m_sysreg>;
271
272 osc@0 {
273 /* MCC static memory clock */
274 compatible = "arm,vexpress-osc";
275 arm,vexpress-sysreg,func = <1 0>;
276 freq-range = <25000000 60000000>;
277 #clock-cells = <0>;
278 clock-output-names = "v2m:oscclk0";
279 };
280
281 v2m_oscclk1: osc@1 {
282 /* CLCD clock */
283 compatible = "arm,vexpress-osc";
284 arm,vexpress-sysreg,func = <1 1>;
285 freq-range = <23750000 63500000>;
286 #clock-cells = <0>;
287 clock-output-names = "v2m:oscclk1";
288 };
289
290 v2m_oscclk2: osc@2 {
291 /* IO FPGA peripheral clock */
292 compatible = "arm,vexpress-osc";
293 arm,vexpress-sysreg,func = <1 2>;
294 freq-range = <24000000 24000000>;
295 #clock-cells = <0>;
296 clock-output-names = "v2m:oscclk2";
297 };
298
299 volt@0 {
300 /* Logic level voltage */
301 compatible = "arm,vexpress-volt";
302 arm,vexpress-sysreg,func = <2 0>;
303 regulator-name = "VIO";
304 regulator-always-on;
305 label = "VIO";
306 };
307
308 temp@0 {
309 /* MCC internal operating temperature */
310 compatible = "arm,vexpress-temp";
311 arm,vexpress-sysreg,func = <4 0>;
312 label = "MCC";
313 };
314
315 reset@0 {
316 compatible = "arm,vexpress-reset";
317 arm,vexpress-sysreg,func = <5 0>;
318 };
319
320 muxfpga@0 {
321 compatible = "arm,vexpress-muxfpga";
322 arm,vexpress-sysreg,func = <7 0>;
323 };
324
325 shutdown@0 {
326 compatible = "arm,vexpress-shutdown";
327 arm,vexpress-sysreg,func = <8 0>;
328 };
329
330 reboot@0 {
331 compatible = "arm,vexpress-reboot";
332 arm,vexpress-sysreg,func = <9 0>;
333 };
334
335 dvimode@0 {
336 compatible = "arm,vexpress-dvimode";
337 arm,vexpress-sysreg,func = <11 0>;
338 };
339 };
211 }; 340 };
212};
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index dba53fd026bb..f1420368355b 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -17,16 +17,15 @@
17 * CHANGES TO vexpress-v2m-rs1.dtsi! 17 * CHANGES TO vexpress-v2m-rs1.dtsi!
18 */ 18 */
19 19
20/ {
21 aliases {
22 arm,v2m_timer = &v2m_timer01;
23 };
24
25 motherboard { 20 motherboard {
26 compatible = "simple-bus"; 21 model = "V2M-P1";
22 arm,hbi = <0x190>;
23 arm,vexpress,site = <0>;
24 compatible = "arm,vexpress,v2m-p1", "simple-bus";
27 #address-cells = <2>; /* SMB chipselect number and offset */ 25 #address-cells = <2>; /* SMB chipselect number and offset */
28 #size-cells = <1>; 26 #size-cells = <1>;
29 #interrupt-cells = <1>; 27 #interrupt-cells = <1>;
28 ranges;
30 29
31 flash@0,00000000 { 30 flash@0,00000000 {
32 compatible = "arm,vexpress-flash", "cfi-flash"; 31 compatible = "arm,vexpress-flash", "cfi-flash";
@@ -71,14 +70,20 @@
71 #size-cells = <1>; 70 #size-cells = <1>;
72 ranges = <0 7 0 0x20000>; 71 ranges = <0 7 0 0x20000>;
73 72
74 sysreg@00000 { 73 v2m_sysreg: sysreg@00000 {
75 compatible = "arm,vexpress-sysreg"; 74 compatible = "arm,vexpress-sysreg";
76 reg = <0x00000 0x1000>; 75 reg = <0x00000 0x1000>;
76 gpio-controller;
77 #gpio-cells = <2>;
77 }; 78 };
78 79
79 sysctl@01000 { 80 v2m_sysctl: sysctl@01000 {
80 compatible = "arm,sp810", "arm,primecell"; 81 compatible = "arm,sp810", "arm,primecell";
81 reg = <0x01000 0x1000>; 82 reg = <0x01000 0x1000>;
83 clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
84 clock-names = "refclk", "timclk", "apb_pclk";
85 #clock-cells = <1>;
86 clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
82 }; 87 };
83 88
84 /* PCI-E I2C bus */ 89 /* PCI-E I2C bus */
@@ -99,66 +104,92 @@
99 compatible = "arm,pl041", "arm,primecell"; 104 compatible = "arm,pl041", "arm,primecell";
100 reg = <0x04000 0x1000>; 105 reg = <0x04000 0x1000>;
101 interrupts = <11>; 106 interrupts = <11>;
107 clocks = <&smbclk>;
108 clock-names = "apb_pclk";
102 }; 109 };
103 110
104 mmci@05000 { 111 mmci@05000 {
105 compatible = "arm,pl180", "arm,primecell"; 112 compatible = "arm,pl180", "arm,primecell";
106 reg = <0x05000 0x1000>; 113 reg = <0x05000 0x1000>;
107 interrupts = <9 10>; 114 interrupts = <9 10>;
115 cd-gpios = <&v2m_sysreg 0 0>;
116 wp-gpios = <&v2m_sysreg 1 0>;
117 max-frequency = <12000000>;
118 vmmc-supply = <&v2m_fixed_3v3>;
119 clocks = <&v2m_clk24mhz>, <&smbclk>;
120 clock-names = "mclk", "apb_pclk";
108 }; 121 };
109 122
110 kmi@06000 { 123 kmi@06000 {
111 compatible = "arm,pl050", "arm,primecell"; 124 compatible = "arm,pl050", "arm,primecell";
112 reg = <0x06000 0x1000>; 125 reg = <0x06000 0x1000>;
113 interrupts = <12>; 126 interrupts = <12>;
127 clocks = <&v2m_clk24mhz>, <&smbclk>;
128 clock-names = "KMIREFCLK", "apb_pclk";
114 }; 129 };
115 130
116 kmi@07000 { 131 kmi@07000 {
117 compatible = "arm,pl050", "arm,primecell"; 132 compatible = "arm,pl050", "arm,primecell";
118 reg = <0x07000 0x1000>; 133 reg = <0x07000 0x1000>;
119 interrupts = <13>; 134 interrupts = <13>;
135 clocks = <&v2m_clk24mhz>, <&smbclk>;
136 clock-names = "KMIREFCLK", "apb_pclk";
120 }; 137 };
121 138
122 v2m_serial0: uart@09000 { 139 v2m_serial0: uart@09000 {
123 compatible = "arm,pl011", "arm,primecell"; 140 compatible = "arm,pl011", "arm,primecell";
124 reg = <0x09000 0x1000>; 141 reg = <0x09000 0x1000>;
125 interrupts = <5>; 142 interrupts = <5>;
143 clocks = <&v2m_oscclk2>, <&smbclk>;
144 clock-names = "uartclk", "apb_pclk";
126 }; 145 };
127 146
128 v2m_serial1: uart@0a000 { 147 v2m_serial1: uart@0a000 {
129 compatible = "arm,pl011", "arm,primecell"; 148 compatible = "arm,pl011", "arm,primecell";
130 reg = <0x0a000 0x1000>; 149 reg = <0x0a000 0x1000>;
131 interrupts = <6>; 150 interrupts = <6>;
151 clocks = <&v2m_oscclk2>, <&smbclk>;
152 clock-names = "uartclk", "apb_pclk";
132 }; 153 };
133 154
134 v2m_serial2: uart@0b000 { 155 v2m_serial2: uart@0b000 {
135 compatible = "arm,pl011", "arm,primecell"; 156 compatible = "arm,pl011", "arm,primecell";
136 reg = <0x0b000 0x1000>; 157 reg = <0x0b000 0x1000>;
137 interrupts = <7>; 158 interrupts = <7>;
159 clocks = <&v2m_oscclk2>, <&smbclk>;
160 clock-names = "uartclk", "apb_pclk";
138 }; 161 };
139 162
140 v2m_serial3: uart@0c000 { 163 v2m_serial3: uart@0c000 {
141 compatible = "arm,pl011", "arm,primecell"; 164 compatible = "arm,pl011", "arm,primecell";
142 reg = <0x0c000 0x1000>; 165 reg = <0x0c000 0x1000>;
143 interrupts = <8>; 166 interrupts = <8>;
167 clocks = <&v2m_oscclk2>, <&smbclk>;
168 clock-names = "uartclk", "apb_pclk";
144 }; 169 };
145 170
146 wdt@0f000 { 171 wdt@0f000 {
147 compatible = "arm,sp805", "arm,primecell"; 172 compatible = "arm,sp805", "arm,primecell";
148 reg = <0x0f000 0x1000>; 173 reg = <0x0f000 0x1000>;
149 interrupts = <0>; 174 interrupts = <0>;
175 clocks = <&v2m_refclk32khz>, <&smbclk>;
176 clock-names = "wdogclk", "apb_pclk";
150 }; 177 };
151 178
152 v2m_timer01: timer@11000 { 179 v2m_timer01: timer@11000 {
153 compatible = "arm,sp804", "arm,primecell"; 180 compatible = "arm,sp804", "arm,primecell";
154 reg = <0x11000 0x1000>; 181 reg = <0x11000 0x1000>;
155 interrupts = <2>; 182 interrupts = <2>;
183 clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
184 clock-names = "timclken1", "timclken2", "apb_pclk";
156 }; 185 };
157 186
158 v2m_timer23: timer@12000 { 187 v2m_timer23: timer@12000 {
159 compatible = "arm,sp804", "arm,primecell"; 188 compatible = "arm,sp804", "arm,primecell";
160 reg = <0x12000 0x1000>; 189 reg = <0x12000 0x1000>;
161 interrupts = <3>; 190 interrupts = <3>;
191 clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
192 clock-names = "timclken1", "timclken2", "apb_pclk";
162 }; 193 };
163 194
164 /* DVI I2C bus */ 195 /* DVI I2C bus */
@@ -184,6 +215,8 @@
184 compatible = "arm,pl031", "arm,primecell"; 215 compatible = "arm,pl031", "arm,primecell";
185 reg = <0x17000 0x1000>; 216 reg = <0x17000 0x1000>;
186 interrupts = <4>; 217 interrupts = <4>;
218 clocks = <&smbclk>;
219 clock-names = "apb_pclk";
187 }; 220 };
188 221
189 compact-flash@1a000 { 222 compact-flash@1a000 {
@@ -197,6 +230,8 @@
197 compatible = "arm,pl111", "arm,primecell"; 230 compatible = "arm,pl111", "arm,primecell";
198 reg = <0x1f000 0x1000>; 231 reg = <0x1f000 0x1000>;
199 interrupts = <14>; 232 interrupts = <14>;
233 clocks = <&v2m_oscclk1>, <&smbclk>;
234 clock-names = "clcdclk", "apb_pclk";
200 }; 235 };
201 }; 236 };
202 237
@@ -207,5 +242,98 @@
207 regulator-max-microvolt = <3300000>; 242 regulator-max-microvolt = <3300000>;
208 regulator-always-on; 243 regulator-always-on;
209 }; 244 };
245
246 v2m_clk24mhz: clk24mhz {
247 compatible = "fixed-clock";
248 #clock-cells = <0>;
249 clock-frequency = <24000000>;
250 clock-output-names = "v2m:clk24mhz";
251 };
252
253 v2m_refclk1mhz: refclk1mhz {
254 compatible = "fixed-clock";
255 #clock-cells = <0>;
256 clock-frequency = <1000000>;
257 clock-output-names = "v2m:refclk1mhz";
258 };
259
260 v2m_refclk32khz: refclk32khz {
261 compatible = "fixed-clock";
262 #clock-cells = <0>;
263 clock-frequency = <32768>;
264 clock-output-names = "v2m:refclk32khz";
265 };
266
267 mcc {
268 compatible = "arm,vexpress,config-bus";
269 arm,vexpress,config-bridge = <&v2m_sysreg>;
270
271 osc@0 {
272 /* MCC static memory clock */
273 compatible = "arm,vexpress-osc";
274 arm,vexpress-sysreg,func = <1 0>;
275 freq-range = <25000000 60000000>;
276 #clock-cells = <0>;
277 clock-output-names = "v2m:oscclk0";
278 };
279
280 v2m_oscclk1: osc@1 {
281 /* CLCD clock */
282 compatible = "arm,vexpress-osc";
283 arm,vexpress-sysreg,func = <1 1>;
284 freq-range = <23750000 63500000>;
285 #clock-cells = <0>;
286 clock-output-names = "v2m:oscclk1";
287 };
288
289 v2m_oscclk2: osc@2 {
290 /* IO FPGA peripheral clock */
291 compatible = "arm,vexpress-osc";
292 arm,vexpress-sysreg,func = <1 2>;
293 freq-range = <24000000 24000000>;
294 #clock-cells = <0>;
295 clock-output-names = "v2m:oscclk2";
296 };
297
298 volt@0 {
299 /* Logic level voltage */
300 compatible = "arm,vexpress-volt";
301 arm,vexpress-sysreg,func = <2 0>;
302 regulator-name = "VIO";
303 regulator-always-on;
304 label = "VIO";
305 };
306
307 temp@0 {
308 /* MCC internal operating temperature */
309 compatible = "arm,vexpress-temp";
310 arm,vexpress-sysreg,func = <4 0>;
311 label = "MCC";
312 };
313
314 reset@0 {
315 compatible = "arm,vexpress-reset";
316 arm,vexpress-sysreg,func = <5 0>;
317 };
318
319 muxfpga@0 {
320 compatible = "arm,vexpress-muxfpga";
321 arm,vexpress-sysreg,func = <7 0>;
322 };
323
324 shutdown@0 {
325 compatible = "arm,vexpress-shutdown";
326 arm,vexpress-sysreg,func = <8 0>;
327 };
328
329 reboot@0 {
330 compatible = "arm,vexpress-reboot";
331 arm,vexpress-sysreg,func = <9 0>;
332 };
333
334 dvimode@0 {
335 compatible = "arm,vexpress-dvimode";
336 arm,vexpress-sysreg,func = <11 0>;
337 };
338 };
210 }; 339 };
211};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index d12b34ca0568..a3d37ec2655d 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -12,6 +12,7 @@
12/ { 12/ {
13 model = "V2P-CA15"; 13 model = "V2P-CA15";
14 arm,hbi = <0x237>; 14 arm,hbi = <0x237>;
15 arm,vexpress,site = <0xf>;
15 compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress"; 16 compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress";
16 interrupt-parent = <&gic>; 17 interrupt-parent = <&gic>;
17 #address-cells = <2>; 18 #address-cells = <2>;
@@ -54,17 +55,24 @@
54 compatible = "arm,hdlcd"; 55 compatible = "arm,hdlcd";
55 reg = <0 0x2b000000 0 0x1000>; 56 reg = <0 0x2b000000 0 0x1000>;
56 interrupts = <0 85 4>; 57 interrupts = <0 85 4>;
58 clocks = <&oscclk5>;
59 clock-names = "pxlclk";
57 }; 60 };
58 61
59 memory-controller@2b0a0000 { 62 memory-controller@2b0a0000 {
60 compatible = "arm,pl341", "arm,primecell"; 63 compatible = "arm,pl341", "arm,primecell";
61 reg = <0 0x2b0a0000 0 0x1000>; 64 reg = <0 0x2b0a0000 0 0x1000>;
65 clocks = <&oscclk7>;
66 clock-names = "apb_pclk";
62 }; 67 };
63 68
64 wdt@2b060000 { 69 wdt@2b060000 {
65 compatible = "arm,sp805", "arm,primecell"; 70 compatible = "arm,sp805", "arm,primecell";
71 status = "disabled";
66 reg = <0 0x2b060000 0 0x1000>; 72 reg = <0 0x2b060000 0 0x1000>;
67 interrupts = <98>; 73 interrupts = <98>;
74 clocks = <&oscclk7>;
75 clock-names = "apb_pclk";
68 }; 76 };
69 77
70 gic: interrupt-controller@2c001000 { 78 gic: interrupt-controller@2c001000 {
@@ -84,6 +92,8 @@
84 reg = <0 0x7ffd0000 0 0x1000>; 92 reg = <0 0x7ffd0000 0 0x1000>;
85 interrupts = <0 86 4>, 93 interrupts = <0 86 4>,
86 <0 87 4>; 94 <0 87 4>;
95 clocks = <&oscclk7>;
96 clock-names = "apb_pclk";
87 }; 97 };
88 98
89 dma@7ffb0000 { 99 dma@7ffb0000 {
@@ -94,6 +104,8 @@
94 <0 89 4>, 104 <0 89 4>,
95 <0 90 4>, 105 <0 90 4>,
96 <0 91 4>; 106 <0 91 4>;
107 clocks = <&oscclk7>;
108 clock-names = "apb_pclk";
97 }; 109 };
98 110
99 timer { 111 timer {
@@ -110,7 +122,109 @@
110 <0 69 4>; 122 <0 69 4>;
111 }; 123 };
112 124
113 motherboard { 125 dcc {
126 compatible = "arm,vexpress,config-bus";
127 arm,vexpress,config-bridge = <&v2m_sysreg>;
128
129 osc@0 {
130 /* CPU PLL reference clock */
131 compatible = "arm,vexpress-osc";
132 arm,vexpress-sysreg,func = <1 0>;
133 freq-range = <50000000 60000000>;
134 #clock-cells = <0>;
135 clock-output-names = "oscclk0";
136 };
137
138 osc@4 {
139 /* Multiplexed AXI master clock */
140 compatible = "arm,vexpress-osc";
141 arm,vexpress-sysreg,func = <1 4>;
142 freq-range = <20000000 40000000>;
143 #clock-cells = <0>;
144 clock-output-names = "oscclk4";
145 };
146
147 oscclk5: osc@5 {
148 /* HDLCD PLL reference clock */
149 compatible = "arm,vexpress-osc";
150 arm,vexpress-sysreg,func = <1 5>;
151 freq-range = <23750000 165000000>;
152 #clock-cells = <0>;
153 clock-output-names = "oscclk5";
154 };
155
156 smbclk: osc@6 {
157 /* SMB clock */
158 compatible = "arm,vexpress-osc";
159 arm,vexpress-sysreg,func = <1 6>;
160 freq-range = <20000000 50000000>;
161 #clock-cells = <0>;
162 clock-output-names = "oscclk6";
163 };
164
165 oscclk7: osc@7 {
166 /* SYS PLL reference clock */
167 compatible = "arm,vexpress-osc";
168 arm,vexpress-sysreg,func = <1 7>;
169 freq-range = <20000000 60000000>;
170 #clock-cells = <0>;
171 clock-output-names = "oscclk7";
172 };
173
174 osc@8 {
175 /* DDR2 PLL reference clock */
176 compatible = "arm,vexpress-osc";
177 arm,vexpress-sysreg,func = <1 8>;
178 freq-range = <40000000 40000000>;
179 #clock-cells = <0>;
180 clock-output-names = "oscclk8";
181 };
182
183 volt@0 {
184 /* CPU core voltage */
185 compatible = "arm,vexpress-volt";
186 arm,vexpress-sysreg,func = <2 0>;
187 regulator-name = "Cores";
188 regulator-min-microvolt = <800000>;
189 regulator-max-microvolt = <1050000>;
190 regulator-always-on;
191 label = "Cores";
192 };
193
194 amp@0 {
195 /* Total current for the two cores */
196 compatible = "arm,vexpress-amp";
197 arm,vexpress-sysreg,func = <3 0>;
198 label = "Cores";
199 };
200
201 temp@0 {
202 /* DCC internal temperature */
203 compatible = "arm,vexpress-temp";
204 arm,vexpress-sysreg,func = <4 0>;
205 label = "DCC";
206 };
207
208 power@0 {
209 /* Total power */
210 compatible = "arm,vexpress-power";
211 arm,vexpress-sysreg,func = <12 0>;
212 label = "Cores";
213 };
214
215 energy@0 {
216 /* Total energy */
217 compatible = "arm,vexpress-energy";
218 arm,vexpress-sysreg,func = <13 0>;
219 label = "Cores";
220 };
221 };
222
223 smb {
224 compatible = "simple-bus";
225
226 #address-cells = <2>;
227 #size-cells = <1>;
114 ranges = <0 0 0 0x08000000 0x04000000>, 228 ranges = <0 0 0 0x08000000 0x04000000>,
115 <1 0 0 0x14000000 0x04000000>, 229 <1 0 0 0x14000000 0x04000000>,
116 <2 0 0 0x18000000 0x04000000>, 230 <2 0 0 0x18000000 0x04000000>,
@@ -118,6 +232,7 @@
118 <4 0 0 0x0c000000 0x04000000>, 232 <4 0 0 0x0c000000 0x04000000>,
119 <5 0 0 0x10000000 0x04000000>; 233 <5 0 0 0x10000000 0x04000000>;
120 234
235 #interrupt-cells = <1>;
121 interrupt-map-mask = <0 0 63>; 236 interrupt-map-mask = <0 0 63>;
122 interrupt-map = <0 0 0 &gic 0 0 4>, 237 interrupt-map = <0 0 0 &gic 0 0 4>,
123 <0 0 1 &gic 0 1 4>, 238 <0 0 1 &gic 0 1 4>,
@@ -162,7 +277,7 @@
162 <0 0 40 &gic 0 40 4>, 277 <0 0 40 &gic 0 40 4>,
163 <0 0 41 &gic 0 41 4>, 278 <0 0 41 &gic 0 41 4>,
164 <0 0 42 &gic 0 42 4>; 279 <0 0 42 &gic 0 42 4>;
280
281 /include/ "vexpress-v2m-rs1.dtsi"
165 }; 282 };
166}; 283};
167
168/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 4890a81c5467..1fc405a9ecfb 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -12,6 +12,7 @@
12/ { 12/ {
13 model = "V2P-CA15_CA7"; 13 model = "V2P-CA15_CA7";
14 arm,hbi = <0x249>; 14 arm,hbi = <0x249>;
15 arm,vexpress,site = <0xf>;
15 compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress"; 16 compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress";
16 interrupt-parent = <&gic>; 17 interrupt-parent = <&gic>;
17 #address-cells = <2>; 18 #address-cells = <2>;
@@ -74,17 +75,23 @@
74 compatible = "arm,sp805", "arm,primecell"; 75 compatible = "arm,sp805", "arm,primecell";
75 reg = <0 0x2a490000 0 0x1000>; 76 reg = <0 0x2a490000 0 0x1000>;
76 interrupts = <98>; 77 interrupts = <98>;
78 clocks = <&oscclk6a>, <&oscclk6a>;
79 clock-names = "wdogclk", "apb_pclk";
77 }; 80 };
78 81
79 hdlcd@2b000000 { 82 hdlcd@2b000000 {
80 compatible = "arm,hdlcd"; 83 compatible = "arm,hdlcd";
81 reg = <0 0x2b000000 0 0x1000>; 84 reg = <0 0x2b000000 0 0x1000>;
82 interrupts = <0 85 4>; 85 interrupts = <0 85 4>;
86 clocks = <&oscclk5>;
87 clock-names = "pxlclk";
83 }; 88 };
84 89
85 memory-controller@2b0a0000 { 90 memory-controller@2b0a0000 {
86 compatible = "arm,pl341", "arm,primecell"; 91 compatible = "arm,pl341", "arm,primecell";
87 reg = <0 0x2b0a0000 0 0x1000>; 92 reg = <0 0x2b0a0000 0 0x1000>;
93 clocks = <&oscclk6a>;
94 clock-names = "apb_pclk";
88 }; 95 };
89 96
90 gic: interrupt-controller@2c001000 { 97 gic: interrupt-controller@2c001000 {
@@ -104,6 +111,8 @@
104 reg = <0 0x7ffd0000 0 0x1000>; 111 reg = <0 0x7ffd0000 0 0x1000>;
105 interrupts = <0 86 4>, 112 interrupts = <0 86 4>,
106 <0 87 4>; 113 <0 87 4>;
114 clocks = <&oscclk6a>;
115 clock-names = "apb_pclk";
107 }; 116 };
108 117
109 dma@7ff00000 { 118 dma@7ff00000 {
@@ -114,6 +123,8 @@
114 <0 89 4>, 123 <0 89 4>,
115 <0 90 4>, 124 <0 90 4>,
116 <0 91 4>; 125 <0 91 4>;
126 clocks = <&oscclk6a>;
127 clock-names = "apb_pclk";
117 }; 128 };
118 129
119 timer { 130 timer {
@@ -130,7 +141,175 @@
130 <0 69 4>; 141 <0 69 4>;
131 }; 142 };
132 143
133 motherboard { 144 oscclk6a: oscclk6a {
145 /* Reference 24MHz clock */
146 compatible = "fixed-clock";
147 #clock-cells = <0>;
148 clock-frequency = <24000000>;
149 clock-output-names = "oscclk6a";
150 };
151
152 dcc {
153 compatible = "arm,vexpress,config-bus";
154 arm,vexpress,config-bridge = <&v2m_sysreg>;
155
156 osc@0 {
157 /* A15 PLL 0 reference clock */
158 compatible = "arm,vexpress-osc";
159 arm,vexpress-sysreg,func = <1 0>;
160 freq-range = <17000000 50000000>;
161 #clock-cells = <0>;
162 clock-output-names = "oscclk0";
163 };
164
165 osc@1 {
166 /* A15 PLL 1 reference clock */
167 compatible = "arm,vexpress-osc";
168 arm,vexpress-sysreg,func = <1 1>;
169 freq-range = <17000000 50000000>;
170 #clock-cells = <0>;
171 clock-output-names = "oscclk1";
172 };
173
174 osc@2 {
175 /* A7 PLL 0 reference clock */
176 compatible = "arm,vexpress-osc";
177 arm,vexpress-sysreg,func = <1 2>;
178 freq-range = <17000000 50000000>;
179 #clock-cells = <0>;
180 clock-output-names = "oscclk2";
181 };
182
183 osc@3 {
184 /* A7 PLL 1 reference clock */
185 compatible = "arm,vexpress-osc";
186 arm,vexpress-sysreg,func = <1 3>;
187 freq-range = <17000000 50000000>;
188 #clock-cells = <0>;
189 clock-output-names = "oscclk3";
190 };
191
192 osc@4 {
193 /* External AXI master clock */
194 compatible = "arm,vexpress-osc";
195 arm,vexpress-sysreg,func = <1 4>;
196 freq-range = <20000000 40000000>;
197 #clock-cells = <0>;
198 clock-output-names = "oscclk4";
199 };
200
201 oscclk5: osc@5 {
202 /* HDLCD PLL reference clock */
203 compatible = "arm,vexpress-osc";
204 arm,vexpress-sysreg,func = <1 5>;
205 freq-range = <23750000 165000000>;
206 #clock-cells = <0>;
207 clock-output-names = "oscclk5";
208 };
209
210 smbclk: osc@6 {
211 /* Static memory controller clock */
212 compatible = "arm,vexpress-osc";
213 arm,vexpress-sysreg,func = <1 6>;
214 freq-range = <20000000 40000000>;
215 #clock-cells = <0>;
216 clock-output-names = "oscclk6";
217 };
218
219 osc@7 {
220 /* SYS PLL reference clock */
221 compatible = "arm,vexpress-osc";
222 arm,vexpress-sysreg,func = <1 7>;
223 freq-range = <17000000 50000000>;
224 #clock-cells = <0>;
225 clock-output-names = "oscclk7";
226 };
227
228 osc@8 {
229 /* DDR2 PLL reference clock */
230 compatible = "arm,vexpress-osc";
231 arm,vexpress-sysreg,func = <1 8>;
232 freq-range = <20000000 50000000>;
233 #clock-cells = <0>;
234 clock-output-names = "oscclk8";
235 };
236
237 volt@0 {
238 /* A15 CPU core voltage */
239 compatible = "arm,vexpress-volt";
240 arm,vexpress-sysreg,func = <2 0>;
241 regulator-name = "A15 Vcore";
242 regulator-min-microvolt = <800000>;
243 regulator-max-microvolt = <1050000>;
244 regulator-always-on;
245 label = "A15 Vcore";
246 };
247
248 volt@1 {
249 /* A7 CPU core voltage */
250 compatible = "arm,vexpress-volt";
251 arm,vexpress-sysreg,func = <2 1>;
252 regulator-name = "A7 Vcore";
253 regulator-min-microvolt = <800000>;
254 regulator-max-microvolt = <1050000>;
255 regulator-always-on;
256 label = "A7 Vcore";
257 };
258
259 amp@0 {
260 /* Total current for the two A15 cores */
261 compatible = "arm,vexpress-amp";
262 arm,vexpress-sysreg,func = <3 0>;
263 label = "A15 Icore";
264 };
265
266 amp@1 {
267 /* Total current for the three A7 cores */
268 compatible = "arm,vexpress-amp";
269 arm,vexpress-sysreg,func = <3 1>;
270 label = "A7 Icore";
271 };
272
273 temp@0 {
274 /* DCC internal temperature */
275 compatible = "arm,vexpress-temp";
276 arm,vexpress-sysreg,func = <4 0>;
277 label = "DCC";
278 };
279
280 power@0 {
281 /* Total power for the two A15 cores */
282 compatible = "arm,vexpress-power";
283 arm,vexpress-sysreg,func = <12 0>;
284 label = "A15 Pcore";
285 };
286 power@1 {
287 /* Total power for the three A7 cores */
288 compatible = "arm,vexpress-power";
289 arm,vexpress-sysreg,func = <12 1>;
290 label = "A7 Pcore";
291 };
292
293 energy@0 {
294 /* Total energy for the two A15 cores */
295 compatible = "arm,vexpress-energy";
296 arm,vexpress-sysreg,func = <13 0>;
297 label = "A15 Jcore";
298 };
299
300 energy@2 {
301 /* Total energy for the three A7 cores */
302 compatible = "arm,vexpress-energy";
303 arm,vexpress-sysreg,func = <13 2>;
304 label = "A7 Jcore";
305 };
306 };
307
308 smb {
309 compatible = "simple-bus";
310
311 #address-cells = <2>;
312 #size-cells = <1>;
134 ranges = <0 0 0 0x08000000 0x04000000>, 313 ranges = <0 0 0 0x08000000 0x04000000>,
135 <1 0 0 0x14000000 0x04000000>, 314 <1 0 0 0x14000000 0x04000000>,
136 <2 0 0 0x18000000 0x04000000>, 315 <2 0 0 0x18000000 0x04000000>,
@@ -138,6 +317,7 @@
138 <4 0 0 0x0c000000 0x04000000>, 317 <4 0 0 0x0c000000 0x04000000>,
139 <5 0 0 0x10000000 0x04000000>; 318 <5 0 0 0x10000000 0x04000000>;
140 319
320 #interrupt-cells = <1>;
141 interrupt-map-mask = <0 0 63>; 321 interrupt-map-mask = <0 0 63>;
142 interrupt-map = <0 0 0 &gic 0 0 4>, 322 interrupt-map = <0 0 0 &gic 0 0 4>,
143 <0 0 1 &gic 0 1 4>, 323 <0 0 1 &gic 0 1 4>,
@@ -182,7 +362,7 @@
182 <0 0 40 &gic 0 40 4>, 362 <0 0 40 &gic 0 40 4>,
183 <0 0 41 &gic 0 41 4>, 363 <0 0 41 &gic 0 41 4>,
184 <0 0 42 &gic 0 42 4>; 364 <0 0 42 &gic 0 42 4>;
365
366 /include/ "vexpress-v2m-rs1.dtsi"
185 }; 367 };
186}; 368};
187
188/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index 18917a0f8604..6328cbc71d30 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -12,6 +12,7 @@
12/ { 12/ {
13 model = "V2P-CA5s"; 13 model = "V2P-CA5s";
14 arm,hbi = <0x225>; 14 arm,hbi = <0x225>;
15 arm,vexpress,site = <0xf>;
15 compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress"; 16 compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
16 interrupt-parent = <&gic>; 17 interrupt-parent = <&gic>;
17 #address-cells = <1>; 18 #address-cells = <1>;
@@ -56,11 +57,15 @@
56 compatible = "arm,hdlcd"; 57 compatible = "arm,hdlcd";
57 reg = <0x2a110000 0x1000>; 58 reg = <0x2a110000 0x1000>;
58 interrupts = <0 85 4>; 59 interrupts = <0 85 4>;
60 clocks = <&oscclk3>;
61 clock-names = "pxlclk";
59 }; 62 };
60 63
61 memory-controller@2a150000 { 64 memory-controller@2a150000 {
62 compatible = "arm,pl341", "arm,primecell"; 65 compatible = "arm,pl341", "arm,primecell";
63 reg = <0x2a150000 0x1000>; 66 reg = <0x2a150000 0x1000>;
67 clocks = <&oscclk1>;
68 clock-names = "apb_pclk";
64 }; 69 };
65 70
66 memory-controller@2a190000 { 71 memory-controller@2a190000 {
@@ -68,6 +73,8 @@
68 reg = <0x2a190000 0x1000>; 73 reg = <0x2a190000 0x1000>;
69 interrupts = <0 86 4>, 74 interrupts = <0 86 4>,
70 <0 87 4>; 75 <0 87 4>;
76 clocks = <&oscclk1>;
77 clock-names = "apb_pclk";
71 }; 78 };
72 79
73 scu@2c000000 { 80 scu@2c000000 {
@@ -109,7 +116,77 @@
109 <0 69 4>; 116 <0 69 4>;
110 }; 117 };
111 118
112 motherboard { 119 dcc {
120 compatible = "arm,vexpress,config-bus";
121 arm,vexpress,config-bridge = <&v2m_sysreg>;
122
123 osc@0 {
124 /* CPU and internal AXI reference clock */
125 compatible = "arm,vexpress-osc";
126 arm,vexpress-sysreg,func = <1 0>;
127 freq-range = <50000000 100000000>;
128 #clock-cells = <0>;
129 clock-output-names = "oscclk0";
130 };
131
132 oscclk1: osc@1 {
133 /* Multiplexed AXI master clock */
134 compatible = "arm,vexpress-osc";
135 arm,vexpress-sysreg,func = <1 1>;
136 freq-range = <5000000 50000000>;
137 #clock-cells = <0>;
138 clock-output-names = "oscclk1";
139 };
140
141 osc@2 {
142 /* DDR2 */
143 compatible = "arm,vexpress-osc";
144 arm,vexpress-sysreg,func = <1 2>;
145 freq-range = <80000000 120000000>;
146 #clock-cells = <0>;
147 clock-output-names = "oscclk2";
148 };
149
150 oscclk3: osc@3 {
151 /* HDLCD */
152 compatible = "arm,vexpress-osc";
153 arm,vexpress-sysreg,func = <1 3>;
154 freq-range = <23750000 165000000>;
155 #clock-cells = <0>;
156 clock-output-names = "oscclk3";
157 };
158
159 osc@4 {
160 /* Test chip gate configuration */
161 compatible = "arm,vexpress-osc";
162 arm,vexpress-sysreg,func = <1 4>;
163 freq-range = <80000000 80000000>;
164 #clock-cells = <0>;
165 clock-output-names = "oscclk4";
166 };
167
168 smbclk: osc@5 {
169 /* SMB clock */
170 compatible = "arm,vexpress-osc";
171 arm,vexpress-sysreg,func = <1 5>;
172 freq-range = <25000000 60000000>;
173 #clock-cells = <0>;
174 clock-output-names = "oscclk5";
175 };
176
177 temp@0 {
178 /* DCC internal operating temperature */
179 compatible = "arm,vexpress-temp";
180 arm,vexpress-sysreg,func = <4 0>;
181 label = "DCC";
182 };
183 };
184
185 smb {
186 compatible = "simple-bus";
187
188 #address-cells = <2>;
189 #size-cells = <1>;
113 ranges = <0 0 0x08000000 0x04000000>, 190 ranges = <0 0 0x08000000 0x04000000>,
114 <1 0 0x14000000 0x04000000>, 191 <1 0 0x14000000 0x04000000>,
115 <2 0 0x18000000 0x04000000>, 192 <2 0 0x18000000 0x04000000>,
@@ -117,6 +194,7 @@
117 <4 0 0x0c000000 0x04000000>, 194 <4 0 0x0c000000 0x04000000>,
118 <5 0 0x10000000 0x04000000>; 195 <5 0 0x10000000 0x04000000>;
119 196
197 #interrupt-cells = <1>;
120 interrupt-map-mask = <0 0 63>; 198 interrupt-map-mask = <0 0 63>;
121 interrupt-map = <0 0 0 &gic 0 0 4>, 199 interrupt-map = <0 0 0 &gic 0 0 4>,
122 <0 0 1 &gic 0 1 4>, 200 <0 0 1 &gic 0 1 4>,
@@ -161,7 +239,7 @@
161 <0 0 40 &gic 0 40 4>, 239 <0 0 40 &gic 0 40 4>,
162 <0 0 41 &gic 0 41 4>, 240 <0 0 41 &gic 0 41 4>,
163 <0 0 42 &gic 0 42 4>; 241 <0 0 42 &gic 0 42 4>;
242
243 /include/ "vexpress-v2m-rs1.dtsi"
164 }; 244 };
165}; 245};
166
167/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 3f0c736d31d6..1420bb14d95c 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -12,6 +12,7 @@
12/ { 12/ {
13 model = "V2P-CA9"; 13 model = "V2P-CA9";
14 arm,hbi = <0x191>; 14 arm,hbi = <0x191>;
15 arm,vexpress,site = <0xf>;
15 compatible = "arm,vexpress,v2p-ca9", "arm,vexpress"; 16 compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
16 interrupt-parent = <&gic>; 17 interrupt-parent = <&gic>;
17 #address-cells = <1>; 18 #address-cells = <1>;
@@ -70,11 +71,15 @@
70 compatible = "arm,pl111", "arm,primecell"; 71 compatible = "arm,pl111", "arm,primecell";
71 reg = <0x10020000 0x1000>; 72 reg = <0x10020000 0x1000>;
72 interrupts = <0 44 4>; 73 interrupts = <0 44 4>;
74 clocks = <&oscclk1>, <&oscclk2>;
75 clock-names = "clcdclk", "apb_pclk";
73 }; 76 };
74 77
75 memory-controller@100e0000 { 78 memory-controller@100e0000 {
76 compatible = "arm,pl341", "arm,primecell"; 79 compatible = "arm,pl341", "arm,primecell";
77 reg = <0x100e0000 0x1000>; 80 reg = <0x100e0000 0x1000>;
81 clocks = <&oscclk2>;
82 clock-names = "apb_pclk";
78 }; 83 };
79 84
80 memory-controller@100e1000 { 85 memory-controller@100e1000 {
@@ -82,6 +87,8 @@
82 reg = <0x100e1000 0x1000>; 87 reg = <0x100e1000 0x1000>;
83 interrupts = <0 45 4>, 88 interrupts = <0 45 4>,
84 <0 46 4>; 89 <0 46 4>;
90 clocks = <&oscclk2>;
91 clock-names = "apb_pclk";
85 }; 92 };
86 93
87 timer@100e4000 { 94 timer@100e4000 {
@@ -89,12 +96,16 @@
89 reg = <0x100e4000 0x1000>; 96 reg = <0x100e4000 0x1000>;
90 interrupts = <0 48 4>, 97 interrupts = <0 48 4>,
91 <0 49 4>; 98 <0 49 4>;
99 clocks = <&oscclk2>, <&oscclk2>;
100 clock-names = "timclk", "apb_pclk";
92 }; 101 };
93 102
94 watchdog@100e5000 { 103 watchdog@100e5000 {
95 compatible = "arm,sp805", "arm,primecell"; 104 compatible = "arm,sp805", "arm,primecell";
96 reg = <0x100e5000 0x1000>; 105 reg = <0x100e5000 0x1000>;
97 interrupts = <0 51 4>; 106 interrupts = <0 51 4>;
107 clocks = <&oscclk2>, <&oscclk2>;
108 clock-names = "wdogclk", "apb_pclk";
98 }; 109 };
99 110
100 scu@1e000000 { 111 scu@1e000000 {
@@ -140,13 +151,132 @@
140 <0 63 4>; 151 <0 63 4>;
141 }; 152 };
142 153
143 motherboard { 154 dcc {
155 compatible = "arm,vexpress,config-bus";
156 arm,vexpress,config-bridge = <&v2m_sysreg>;
157
158 osc@0 {
159 /* ACLK clock to the AXI master port on the test chip */
160 compatible = "arm,vexpress-osc";
161 arm,vexpress-sysreg,func = <1 0>;
162 freq-range = <30000000 50000000>;
163 #clock-cells = <0>;
164 clock-output-names = "extsaxiclk";
165 };
166
167 oscclk1: osc@1 {
168 /* Reference clock for the CLCD */
169 compatible = "arm,vexpress-osc";
170 arm,vexpress-sysreg,func = <1 1>;
171 freq-range = <10000000 80000000>;
172 #clock-cells = <0>;
173 clock-output-names = "clcdclk";
174 };
175
176 smbclk: oscclk2: osc@2 {
177 /* Reference clock for the test chip internal PLLs */
178 compatible = "arm,vexpress-osc";
179 arm,vexpress-sysreg,func = <1 2>;
180 freq-range = <33000000 100000000>;
181 #clock-cells = <0>;
182 clock-output-names = "tcrefclk";
183 };
184
185 volt@0 {
186 /* Test Chip internal logic voltage */
187 compatible = "arm,vexpress-volt";
188 arm,vexpress-sysreg,func = <2 0>;
189 regulator-name = "VD10";
190 regulator-always-on;
191 label = "VD10";
192 };
193
194 volt@1 {
195 /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
196 compatible = "arm,vexpress-volt";
197 arm,vexpress-sysreg,func = <2 1>;
198 regulator-name = "VD10_S2";
199 regulator-always-on;
200 label = "VD10_S2";
201 };
202
203 volt@2 {
204 /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
205 compatible = "arm,vexpress-volt";
206 arm,vexpress-sysreg,func = <2 2>;
207 regulator-name = "VD10_S3";
208 regulator-always-on;
209 label = "VD10_S3";
210 };
211
212 volt@3 {
213 /* DDR2 SDRAM and Test Chip DDR2 I/O supply */
214 compatible = "arm,vexpress-volt";
215 arm,vexpress-sysreg,func = <2 3>;
216 regulator-name = "VCC1V8";
217 regulator-always-on;
218 label = "VCC1V8";
219 };
220
221 volt@4 {
222 /* DDR2 SDRAM VTT termination voltage */
223 compatible = "arm,vexpress-volt";
224 arm,vexpress-sysreg,func = <2 4>;
225 regulator-name = "DDR2VTT";
226 regulator-always-on;
227 label = "DDR2VTT";
228 };
229
230 volt@5 {
231 /* Local board supply for miscellaneous logic external to the Test Chip */
232 arm,vexpress-sysreg,func = <2 5>;
233 compatible = "arm,vexpress-volt";
234 regulator-name = "VCC3V3";
235 regulator-always-on;
236 label = "VCC3V3";
237 };
238
239 amp@0 {
240 /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
241 compatible = "arm,vexpress-amp";
242 arm,vexpress-sysreg,func = <3 0>;
243 label = "VD10_S2";
244 };
245
246 amp@1 {
247 /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
248 compatible = "arm,vexpress-amp";
249 arm,vexpress-sysreg,func = <3 1>;
250 label = "VD10_S3";
251 };
252
253 power@0 {
254 /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
255 compatible = "arm,vexpress-power";
256 arm,vexpress-sysreg,func = <12 0>;
257 label = "PVD10_S2";
258 };
259
260 power@1 {
261 /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
262 compatible = "arm,vexpress-power";
263 arm,vexpress-sysreg,func = <12 1>;
264 label = "PVD10_S3";
265 };
266 };
267
268 smb {
269 compatible = "simple-bus";
270
271 #address-cells = <2>;
272 #size-cells = <1>;
144 ranges = <0 0 0x40000000 0x04000000>, 273 ranges = <0 0 0x40000000 0x04000000>,
145 <1 0 0x44000000 0x04000000>, 274 <1 0 0x44000000 0x04000000>,
146 <2 0 0x48000000 0x04000000>, 275 <2 0 0x48000000 0x04000000>,
147 <3 0 0x4c000000 0x04000000>, 276 <3 0 0x4c000000 0x04000000>,
148 <7 0 0x10000000 0x00020000>; 277 <7 0 0x10000000 0x00020000>;
149 278
279 #interrupt-cells = <1>;
150 interrupt-map-mask = <0 0 63>; 280 interrupt-map-mask = <0 0 63>;
151 interrupt-map = <0 0 0 &gic 0 0 4>, 281 interrupt-map = <0 0 0 &gic 0 0 4>,
152 <0 0 1 &gic 0 1 4>, 282 <0 0 1 &gic 0 1 4>,
@@ -191,7 +321,7 @@
191 <0 0 40 &gic 0 40 4>, 321 <0 0 40 &gic 0 40 4>,
192 <0 0 41 &gic 0 41 4>, 322 <0 0 41 &gic 0 41 4>,
193 <0 0 42 &gic 0 42 4>; 323 <0 0 42 &gic 0 42 4>;
324
325 /include/ "vexpress-v2m.dtsi"
194 }; 326 };
195}; 327};
196
197/include/ "vexpress-v2m.dtsi"
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
index afd7e916472f..6636430dd0e6 100644
--- a/arch/arm/include/asm/hardware/sp810.h
+++ b/arch/arm/include/asm/hardware/sp810.h
@@ -50,12 +50,6 @@
50#define SCPCELLID2 0xFF8 50#define SCPCELLID2 0xFF8
51#define SCPCELLID3 0xFFC 51#define SCPCELLID3 0xFFC
52 52
53#define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15)
54#define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15)
55
56#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17)
57#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17)
58
59#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2)) 53#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2))
60 54
61static inline void sysctl_soft_reset(void __iomem *base) 55static inline void sysctl_soft_reset(void __iomem *base)
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index c95296066203..99e63f5f99d1 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -1,11 +1,12 @@
1config ARCH_VEXPRESS 1config ARCH_VEXPRESS
2 bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7 2 bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
3 select ARCH_WANT_OPTIONAL_GPIOLIB 3 select ARCH_REQUIRE_GPIOLIB
4 select ARM_AMBA 4 select ARM_AMBA
5 select ARM_GIC 5 select ARM_GIC
6 select ARM_TIMER_SP804 6 select ARM_TIMER_SP804
7 select CLKDEV_LOOKUP 7 select CLKDEV_LOOKUP
8 select COMMON_CLK 8 select COMMON_CLK
9 select COMMON_CLK_VERSATILE
9 select CPU_V7 10 select CPU_V7
10 select GENERIC_CLOCKEVENTS 11 select GENERIC_CLOCKEVENTS
11 select HAVE_CLK 12 select HAVE_CLK
@@ -17,6 +18,7 @@ config ARCH_VEXPRESS
17 select PLAT_VERSATILE 18 select PLAT_VERSATILE
18 select PLAT_VERSATILE_CLCD 19 select PLAT_VERSATILE_CLCD
19 select REGULATOR_FIXED_VOLTAGE if REGULATOR 20 select REGULATOR_FIXED_VOLTAGE if REGULATOR
21 select VEXPRESS_CONFIG
20 help 22 help
21 This option enables support for systems using Cortex processor based 23 This option enables support for systems using Cortex processor based
22 ARM core and logic (FPGA) tiles on the Versatile Express motherboard, 24 ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 42703e8b4d3b..80b64971fbdd 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -4,7 +4,7 @@
4ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ 4ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
5 -I$(srctree)/arch/arm/plat-versatile/include 5 -I$(srctree)/arch/arm/plat-versatile/include
6 6
7obj-y := v2m.o 7obj-y := v2m.o reset.o
8obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o 8obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
9obj-$(CONFIG_SMP) += platsmp.o 9obj-$(CONFIG_SMP) += platsmp.o
10obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 10obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 4f471fa3e3c5..60838ddb8564 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -9,6 +9,7 @@
9#include <linux/amba/bus.h> 9#include <linux/amba/bus.h>
10#include <linux/amba/clcd.h> 10#include <linux/amba/clcd.h>
11#include <linux/clkdev.h> 11#include <linux/clkdev.h>
12#include <linux/vexpress.h>
12 13
13#include <asm/hardware/arm_timer.h> 14#include <asm/hardware/arm_timer.h>
14#include <asm/hardware/cache-l2x0.h> 15#include <asm/hardware/cache-l2x0.h>
@@ -64,19 +65,6 @@ static void __init ct_ca9x4_init_irq(void)
64 ca9x4_twd_init(); 65 ca9x4_twd_init();
65} 66}
66 67
67static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
68{
69 u32 site = v2m_get_master_site();
70
71 /*
72 * Old firmware was using the "site" component of the command
73 * to control the DVI muxer (while it should be always 0 ie. MB).
74 * Newer firmware uses the data register. Keep both for compatibility.
75 */
76 v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site);
77 v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE(SYS_CFG_SITE_MB), 2);
78}
79
80static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) 68static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
81{ 69{
82 unsigned long framesize = 1024 * 768 * 2; 70 unsigned long framesize = 1024 * 768 * 2;
@@ -93,7 +81,6 @@ static struct clcd_board ct_ca9x4_clcd_data = {
93 .caps = CLCD_CAP_5551 | CLCD_CAP_565, 81 .caps = CLCD_CAP_5551 | CLCD_CAP_565,
94 .check = clcdfb_check, 82 .check = clcdfb_check,
95 .decode = clcdfb_decode, 83 .decode = clcdfb_decode,
96 .enable = ct_ca9x4_clcd_enable,
97 .setup = ct_ca9x4_clcd_setup, 84 .setup = ct_ca9x4_clcd_setup,
98 .mmap = versatile_clcd_mmap_dma, 85 .mmap = versatile_clcd_mmap_dma,
99 .remove = versatile_clcd_remove_dma, 86 .remove = versatile_clcd_remove_dma,
@@ -111,14 +98,6 @@ static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
111 &gpio_device, 98 &gpio_device,
112}; 99};
113 100
114
115static struct v2m_osc ct_osc1 = {
116 .osc = 1,
117 .rate_min = 10000000,
118 .rate_max = 80000000,
119 .rate_default = 23750000,
120};
121
122static struct resource pmu_resources[] = { 101static struct resource pmu_resources[] = {
123 [0] = { 102 [0] = {
124 .start = IRQ_CT_CA9X4_PMU_CPU0, 103 .start = IRQ_CT_CA9X4_PMU_CPU0,
@@ -149,10 +128,18 @@ static struct platform_device pmu_device = {
149 .resource = pmu_resources, 128 .resource = pmu_resources,
150}; 129};
151 130
131static struct platform_device osc1_device = {
132 .name = "vexpress-osc",
133 .id = 1,
134 .num_resources = 1,
135 .resource = (struct resource []) {
136 VEXPRESS_RES_FUNC(0xf, 1),
137 },
138};
139
152static void __init ct_ca9x4_init(void) 140static void __init ct_ca9x4_init(void)
153{ 141{
154 int i; 142 int i;
155 struct clk *clk;
156 143
157#ifdef CONFIG_CACHE_L2X0 144#ifdef CONFIG_CACHE_L2X0
158 void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K); 145 void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
@@ -164,14 +151,14 @@ static void __init ct_ca9x4_init(void)
164 l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); 151 l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
165#endif 152#endif
166 153
167 ct_osc1.site = v2m_get_master_site();
168 clk = v2m_osc_register("ct:osc1", &ct_osc1);
169 clk_register_clkdev(clk, NULL, "ct:clcd");
170
171 for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) 154 for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
172 amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); 155 amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
173 156
174 platform_device_register(&pmu_device); 157 platform_device_register(&pmu_device);
158 platform_device_register(&osc1_device);
159
160 WARN_ON(clk_register_clkdev(vexpress_osc_setup(&osc1_device.dev),
161 NULL, "ct:clcd"));
175} 162}
176 163
177#ifdef CONFIG_SMP 164#ifdef CONFIG_SMP
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 1e388c7bf4d7..68abc8b72781 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -1,8 +1,6 @@
1#ifndef __MACH_MOTHERBOARD_H 1#ifndef __MACH_MOTHERBOARD_H
2#define __MACH_MOTHERBOARD_H 2#define __MACH_MOTHERBOARD_H
3 3
4#include <linux/clk-provider.h>
5
6/* 4/*
7 * Physical addresses, offset from V2M_PA_CS0-3 5 * Physical addresses, offset from V2M_PA_CS0-3
8 */ 6 */
@@ -41,31 +39,6 @@
41#define V2M_CF (V2M_PA_CS7 + 0x0001a000) 39#define V2M_CF (V2M_PA_CS7 + 0x0001a000)
42#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) 40#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000)
43 41
44/*
45 * Offsets from SYSREGS base
46 */
47#define V2M_SYS_ID 0x000
48#define V2M_SYS_SW 0x004
49#define V2M_SYS_LED 0x008
50#define V2M_SYS_100HZ 0x024
51#define V2M_SYS_FLAGS 0x030
52#define V2M_SYS_FLAGSSET 0x030
53#define V2M_SYS_FLAGSCLR 0x034
54#define V2M_SYS_NVFLAGS 0x038
55#define V2M_SYS_NVFLAGSSET 0x038
56#define V2M_SYS_NVFLAGSCLR 0x03c
57#define V2M_SYS_MCI 0x048
58#define V2M_SYS_FLASH 0x03c
59#define V2M_SYS_CFGSW 0x058
60#define V2M_SYS_24MHZ 0x05c
61#define V2M_SYS_MISC 0x060
62#define V2M_SYS_DMA 0x064
63#define V2M_SYS_PROCID0 0x084
64#define V2M_SYS_PROCID1 0x088
65#define V2M_SYS_CFGDATA 0x0a0
66#define V2M_SYS_CFGCTRL 0x0a4
67#define V2M_SYS_CFGSTAT 0x0a8
68
69 42
70/* 43/*
71 * Interrupts. Those in {} are for AMBA devices 44 * Interrupts. Those in {} are for AMBA devices
@@ -91,43 +64,6 @@
91 64
92 65
93/* 66/*
94 * Configuration
95 */
96#define SYS_CFG_START (1 << 31)
97#define SYS_CFG_WRITE (1 << 30)
98#define SYS_CFG_OSC (1 << 20)
99#define SYS_CFG_VOLT (2 << 20)
100#define SYS_CFG_AMP (3 << 20)
101#define SYS_CFG_TEMP (4 << 20)
102#define SYS_CFG_RESET (5 << 20)
103#define SYS_CFG_SCC (6 << 20)
104#define SYS_CFG_MUXFPGA (7 << 20)
105#define SYS_CFG_SHUTDOWN (8 << 20)
106#define SYS_CFG_REBOOT (9 << 20)
107#define SYS_CFG_DVIMODE (11 << 20)
108#define SYS_CFG_POWER (12 << 20)
109#define SYS_CFG_SITE(n) ((n) << 16)
110#define SYS_CFG_SITE_MB 0
111#define SYS_CFG_SITE_DB1 1
112#define SYS_CFG_SITE_DB2 2
113#define SYS_CFG_STACK(n) ((n) << 12)
114
115#define SYS_CFG_ERR (1 << 1)
116#define SYS_CFG_COMPLETE (1 << 0)
117
118int v2m_cfg_write(u32 devfn, u32 data);
119int v2m_cfg_read(u32 devfn, u32 *data);
120void v2m_flags_set(u32 data);
121
122/*
123 * Miscellaneous
124 */
125#define SYS_MISC_MASTERSITE (1 << 14)
126#define SYS_PROCIDx_HBI_MASK 0xfff
127
128int v2m_get_master_site(void);
129
130/*
131 * Core tile IDs 67 * Core tile IDs
132 */ 68 */
133#define V2M_CT_ID_CA9 0x0c000191 69#define V2M_CT_ID_CA9 0x0c000191
@@ -149,21 +85,4 @@ struct ct_desc {
149 85
150extern struct ct_desc *ct_desc; 86extern struct ct_desc *ct_desc;
151 87
152/*
153 * OSC clock provider
154 */
155struct v2m_osc {
156 struct clk_hw hw;
157 u8 site; /* 0 = motherboard, 1 = site 1, 2 = site 2 */
158 u8 stack; /* board stack position */
159 u16 osc;
160 unsigned long rate_min;
161 unsigned long rate_max;
162 unsigned long rate_default;
163};
164
165#define to_v2m_osc(osc) container_of(osc, struct v2m_osc, hw)
166
167struct clk *v2m_osc_register(const char *name, struct v2m_osc *osc);
168
169#endif 88#endif
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 7db27c8c05cc..c5d70de9bb4e 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -13,6 +13,7 @@
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/of_fdt.h> 15#include <linux/of_fdt.h>
16#include <linux/vexpress.h>
16 17
17#include <asm/smp_scu.h> 18#include <asm/smp_scu.h>
18#include <asm/hardware/gic.h> 19#include <asm/hardware/gic.h>
@@ -193,7 +194,7 @@ static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus)
193 * until it receives a soft interrupt, and then the 194 * until it receives a soft interrupt, and then the
194 * secondary CPU branches to this address. 195 * secondary CPU branches to this address.
195 */ 196 */
196 v2m_flags_set(virt_to_phys(versatile_secondary_startup)); 197 vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
197} 198}
198 199
199struct smp_operations __initdata vexpress_smp_ops = { 200struct smp_operations __initdata vexpress_smp_ops = {
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 560e0df728f8..4e168e81fb42 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -16,11 +16,10 @@
16#include <linux/smsc911x.h> 16#include <linux/smsc911x.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/usb/isp1760.h> 18#include <linux/usb/isp1760.h>
19#include <linux/clkdev.h>
20#include <linux/clk-provider.h>
21#include <linux/mtd/physmap.h> 19#include <linux/mtd/physmap.h>
22#include <linux/regulator/fixed.h> 20#include <linux/regulator/fixed.h>
23#include <linux/regulator/machine.h> 21#include <linux/regulator/machine.h>
22#include <linux/vexpress.h>
24 23
25#include <asm/arch_timer.h> 24#include <asm/arch_timer.h>
26#include <asm/mach-types.h> 25#include <asm/mach-types.h>
@@ -33,7 +32,6 @@
33#include <asm/hardware/cache-l2x0.h> 32#include <asm/hardware/cache-l2x0.h>
34#include <asm/hardware/gic.h> 33#include <asm/hardware/gic.h>
35#include <asm/hardware/timer-sp.h> 34#include <asm/hardware/timer-sp.h>
36#include <asm/hardware/sp810.h>
37 35
38#include <mach/ct-ca9x4.h> 36#include <mach/ct-ca9x4.h>
39#include <mach/motherboard.h> 37#include <mach/motherboard.h>
@@ -58,22 +56,6 @@ static struct map_desc v2m_io_desc[] __initdata = {
58 }, 56 },
59}; 57};
60 58
61static void __iomem *v2m_sysreg_base;
62
63static void __init v2m_sysctl_init(void __iomem *base)
64{
65 u32 scctrl;
66
67 if (WARN_ON(!base))
68 return;
69
70 /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
71 scctrl = readl(base + SCCTRL);
72 scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
73 scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
74 writel(scctrl, base + SCCTRL);
75}
76
77static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) 59static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
78{ 60{
79 if (WARN_ON(!base || irq == NO_IRQ)) 61 if (WARN_ON(!base || irq == NO_IRQ))
@@ -87,69 +69,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
87} 69}
88 70
89 71
90static DEFINE_SPINLOCK(v2m_cfg_lock);
91
92int v2m_cfg_write(u32 devfn, u32 data)
93{
94 /* Configuration interface broken? */
95 u32 val;
96
97 printk("%s: writing %08x to %08x\n", __func__, data, devfn);
98
99 devfn |= SYS_CFG_START | SYS_CFG_WRITE;
100
101 spin_lock(&v2m_cfg_lock);
102 val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
103 writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT);
104
105 writel(data, v2m_sysreg_base + V2M_SYS_CFGDATA);
106 writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
107
108 do {
109 val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
110 } while (val == 0);
111 spin_unlock(&v2m_cfg_lock);
112
113 return !!(val & SYS_CFG_ERR);
114}
115
116int v2m_cfg_read(u32 devfn, u32 *data)
117{
118 u32 val;
119
120 devfn |= SYS_CFG_START;
121
122 spin_lock(&v2m_cfg_lock);
123 writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT);
124 writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
125
126 mb();
127
128 do {
129 cpu_relax();
130 val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
131 } while (val == 0);
132
133 *data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA);
134 spin_unlock(&v2m_cfg_lock);
135
136 return !!(val & SYS_CFG_ERR);
137}
138
139void __init v2m_flags_set(u32 data)
140{
141 writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR);
142 writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
143}
144
145int v2m_get_master_site(void)
146{
147 u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
148
149 return misc & SYS_MISC_MASTERSITE ? SYS_CFG_SITE_DB2 : SYS_CFG_SITE_DB1;
150}
151
152
153static struct resource v2m_pcie_i2c_resource = { 72static struct resource v2m_pcie_i2c_resource = {
154 .start = V2M_SERIAL_BUS_PCI, 73 .start = V2M_SERIAL_BUS_PCI,
155 .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1, 74 .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
@@ -237,14 +156,8 @@ static struct platform_device v2m_usb_device = {
237 .dev.platform_data = &v2m_usb_config, 156 .dev.platform_data = &v2m_usb_config,
238}; 157};
239 158
240static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
241{
242 writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH);
243}
244
245static struct physmap_flash_data v2m_flash_data = { 159static struct physmap_flash_data v2m_flash_data = {
246 .width = 4, 160 .width = 4,
247 .set_vpp = v2m_flash_set_vpp,
248}; 161};
249 162
250static struct resource v2m_flash_resources[] = { 163static struct resource v2m_flash_resources[] = {
@@ -291,14 +204,61 @@ static struct platform_device v2m_cf_device = {
291 .dev.platform_data = &v2m_pata_data, 204 .dev.platform_data = &v2m_pata_data,
292}; 205};
293 206
294static unsigned int v2m_mmci_status(struct device *dev)
295{
296 return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0);
297}
298
299static struct mmci_platform_data v2m_mmci_data = { 207static struct mmci_platform_data v2m_mmci_data = {
300 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 208 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
301 .status = v2m_mmci_status, 209 .gpio_wp = VEXPRESS_GPIO_MMC_WPROT,
210 .gpio_cd = VEXPRESS_GPIO_MMC_CARDIN,
211};
212
213static struct resource v2m_sysreg_resources[] = {
214 {
215 .start = V2M_SYSREGS,
216 .end = V2M_SYSREGS + 0xfff,
217 .flags = IORESOURCE_MEM,
218 },
219};
220
221static struct platform_device v2m_sysreg_device = {
222 .name = "vexpress-sysreg",
223 .id = -1,
224 .resource = v2m_sysreg_resources,
225 .num_resources = ARRAY_SIZE(v2m_sysreg_resources),
226};
227
228static struct platform_device v2m_muxfpga_device = {
229 .name = "vexpress-muxfpga",
230 .id = 0,
231 .num_resources = 1,
232 .resource = (struct resource []) {
233 VEXPRESS_RES_FUNC(0, 7),
234 }
235};
236
237static struct platform_device v2m_shutdown_device = {
238 .name = "vexpress-shutdown",
239 .id = 0,
240 .num_resources = 1,
241 .resource = (struct resource []) {
242 VEXPRESS_RES_FUNC(0, 8),
243 }
244};
245
246static struct platform_device v2m_reboot_device = {
247 .name = "vexpress-reboot",
248 .id = 0,
249 .num_resources = 1,
250 .resource = (struct resource []) {
251 VEXPRESS_RES_FUNC(0, 9),
252 }
253};
254
255static struct platform_device v2m_dvimode_device = {
256 .name = "vexpress-dvimode",
257 .id = 0,
258 .num_resources = 1,
259 .resource = (struct resource []) {
260 VEXPRESS_RES_FUNC(0, 11),
261 }
302}; 262};
303 263
304static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL); 264static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL);
@@ -325,123 +285,9 @@ static struct amba_device *v2m_amba_devs[] __initdata = {
325 &rtc_device, 285 &rtc_device,
326}; 286};
327 287
328
329static unsigned long v2m_osc_recalc_rate(struct clk_hw *hw,
330 unsigned long parent_rate)
331{
332 struct v2m_osc *osc = to_v2m_osc(hw);
333
334 return !parent_rate ? osc->rate_default : parent_rate;
335}
336
337static long v2m_osc_round_rate(struct clk_hw *hw, unsigned long rate,
338 unsigned long *parent_rate)
339{
340 struct v2m_osc *osc = to_v2m_osc(hw);
341
342 if (WARN_ON(rate < osc->rate_min))
343 rate = osc->rate_min;
344
345 if (WARN_ON(rate > osc->rate_max))
346 rate = osc->rate_max;
347
348 return rate;
349}
350
351static int v2m_osc_set_rate(struct clk_hw *hw, unsigned long rate,
352 unsigned long parent_rate)
353{
354 struct v2m_osc *osc = to_v2m_osc(hw);
355
356 v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(osc->site) |
357 SYS_CFG_STACK(osc->stack) | osc->osc, rate);
358
359 return 0;
360}
361
362static struct clk_ops v2m_osc_ops = {
363 .recalc_rate = v2m_osc_recalc_rate,
364 .round_rate = v2m_osc_round_rate,
365 .set_rate = v2m_osc_set_rate,
366};
367
368struct clk * __init v2m_osc_register(const char *name, struct v2m_osc *osc)
369{
370 struct clk_init_data init;
371
372 WARN_ON(osc->site > 2);
373 WARN_ON(osc->stack > 15);
374 WARN_ON(osc->osc > 4095);
375
376 init.name = name;
377 init.ops = &v2m_osc_ops;
378 init.flags = CLK_IS_ROOT;
379 init.num_parents = 0;
380
381 osc->hw.init = &init;
382
383 return clk_register(NULL, &osc->hw);
384}
385
386static struct v2m_osc v2m_mb_osc1 = {
387 .site = SYS_CFG_SITE_MB,
388 .osc = 1,
389 .rate_min = 23750000,
390 .rate_max = 63500000,
391 .rate_default = 23750000,
392};
393
394static const char *v2m_ref_clk_periphs[] __initconst = {
395 "mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */
396};
397
398static const char *v2m_osc1_periphs[] __initconst = {
399 "mb:clcd", "1001f000.clcd", "1c1f0000.clcd", /* PL111 CLCD */
400};
401
402static const char *v2m_osc2_periphs[] __initconst = {
403 "mb:mmci", "10005000.mmci", "1c050000.mmci", /* PL180 MMCI */
404 "mb:kmi0", "10006000.kmi", "1c060000.kmi", /* PL050 KMI0 */
405 "mb:kmi1", "10007000.kmi", "1c070000.kmi", /* PL050 KMI1 */
406 "mb:uart0", "10009000.uart", "1c090000.uart", /* PL011 UART0 */
407 "mb:uart1", "1000a000.uart", "1c0a0000.uart", /* PL011 UART1 */
408 "mb:uart2", "1000b000.uart", "1c0b0000.uart", /* PL011 UART2 */
409 "mb:uart3", "1000c000.uart", "1c0c0000.uart", /* PL011 UART3 */
410};
411
412static void __init v2m_clk_init(void)
413{
414 struct clk *clk;
415 int i;
416
417 clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
418 CLK_IS_ROOT, 0);
419 WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL));
420
421 clk = clk_register_fixed_rate(NULL, "mb:ref_clk", NULL,
422 CLK_IS_ROOT, 32768);
423 for (i = 0; i < ARRAY_SIZE(v2m_ref_clk_periphs); i++)
424 WARN_ON(clk_register_clkdev(clk, NULL, v2m_ref_clk_periphs[i]));
425
426 clk = clk_register_fixed_rate(NULL, "mb:sp804_clk", NULL,
427 CLK_IS_ROOT, 1000000);
428 WARN_ON(clk_register_clkdev(clk, "v2m-timer0", "sp804"));
429 WARN_ON(clk_register_clkdev(clk, "v2m-timer1", "sp804"));
430
431 clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1);
432 for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++)
433 WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i]));
434
435 clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL,
436 CLK_IS_ROOT, 24000000);
437 for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++)
438 WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]));
439}
440
441static void __init v2m_timer_init(void) 288static void __init v2m_timer_init(void)
442{ 289{
443 v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K)); 290 vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K));
444 v2m_clk_init();
445 v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0); 291 v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
446} 292}
447 293
@@ -453,19 +299,7 @@ static void __init v2m_init_early(void)
453{ 299{
454 if (ct_desc->init_early) 300 if (ct_desc->init_early)
455 ct_desc->init_early(); 301 ct_desc->init_early();
456 versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); 302 versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
457}
458
459static void v2m_power_off(void)
460{
461 if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
462 printk(KERN_EMERG "Unable to shutdown\n");
463}
464
465static void v2m_restart(char str, const char *cmd)
466{
467 if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
468 printk(KERN_EMERG "Unable to reboot\n");
469} 303}
470 304
471struct ct_desc *ct_desc; 305struct ct_desc *ct_desc;
@@ -482,7 +316,7 @@ static void __init v2m_populate_ct_desc(void)
482 u32 current_tile_id; 316 u32 current_tile_id;
483 317
484 ct_desc = NULL; 318 ct_desc = NULL;
485 current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0) 319 current_tile_id = vexpress_get_procid(VEXPRESS_SITE_MASTER)
486 & V2M_CT_ID_MASK; 320 & V2M_CT_ID_MASK;
487 321
488 for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) 322 for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
@@ -498,7 +332,7 @@ static void __init v2m_populate_ct_desc(void)
498static void __init v2m_map_io(void) 332static void __init v2m_map_io(void)
499{ 333{
500 iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); 334 iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
501 v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K); 335 vexpress_sysreg_early_init(ioremap(V2M_SYSREGS, SZ_4K));
502 v2m_populate_ct_desc(); 336 v2m_populate_ct_desc();
503 ct_desc->map_io(); 337 ct_desc->map_io();
504} 338}
@@ -515,6 +349,12 @@ static void __init v2m_init(void)
515 regulator_register_fixed(0, v2m_eth_supplies, 349 regulator_register_fixed(0, v2m_eth_supplies,
516 ARRAY_SIZE(v2m_eth_supplies)); 350 ARRAY_SIZE(v2m_eth_supplies));
517 351
352 platform_device_register(&v2m_muxfpga_device);
353 platform_device_register(&v2m_shutdown_device);
354 platform_device_register(&v2m_reboot_device);
355 platform_device_register(&v2m_dvimode_device);
356
357 platform_device_register(&v2m_sysreg_device);
518 platform_device_register(&v2m_pcie_i2c_device); 358 platform_device_register(&v2m_pcie_i2c_device);
519 platform_device_register(&v2m_ddc_i2c_device); 359 platform_device_register(&v2m_ddc_i2c_device);
520 platform_device_register(&v2m_flash_device); 360 platform_device_register(&v2m_flash_device);
@@ -525,7 +365,7 @@ static void __init v2m_init(void)
525 for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) 365 for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
526 amba_device_register(v2m_amba_devs[i], &iomem_resource); 366 amba_device_register(v2m_amba_devs[i], &iomem_resource);
527 367
528 pm_power_off = v2m_power_off; 368 pm_power_off = vexpress_power_off;
529 369
530 ct_desc->init_tile(); 370 ct_desc->init_tile();
531} 371}
@@ -539,7 +379,7 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express")
539 .timer = &v2m_timer, 379 .timer = &v2m_timer,
540 .handle_irq = gic_handle_irq, 380 .handle_irq = gic_handle_irq,
541 .init_machine = v2m_init, 381 .init_machine = v2m_init,
542 .restart = v2m_restart, 382 .restart = vexpress_restart,
543MACHINE_END 383MACHINE_END
544 384
545static struct map_desc v2m_rs1_io_desc __initdata = { 385static struct map_desc v2m_rs1_io_desc __initdata = {
@@ -580,20 +420,13 @@ void __init v2m_dt_map_io(void)
580 420
581void __init v2m_dt_init_early(void) 421void __init v2m_dt_init_early(void)
582{ 422{
583 struct device_node *node;
584 u32 dt_hbi; 423 u32 dt_hbi;
585 424
586 node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); 425 vexpress_sysreg_of_early_init();
587 v2m_sysreg_base = of_iomap(node, 0);
588 if (WARN_ON(!v2m_sysreg_base))
589 return;
590 426
591 /* Confirm board type against DT property, if available */ 427 /* Confirm board type against DT property, if available */
592 if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) { 428 if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
593 int site = v2m_get_master_site(); 429 u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER);
594 u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
595 V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
596 u32 hbi = id & SYS_PROCIDx_HBI_MASK;
597 430
598 if (WARN_ON(dt_hbi != hbi)) 431 if (WARN_ON(dt_hbi != hbi))
599 pr_warning("vexpress: DT HBI (%x) is not matching " 432 pr_warning("vexpress: DT HBI (%x) is not matching "
@@ -613,51 +446,47 @@ static void __init v2m_dt_init_irq(void)
613 446
614static void __init v2m_dt_timer_init(void) 447static void __init v2m_dt_timer_init(void)
615{ 448{
616 struct device_node *node; 449 struct device_node *node = NULL;
617 const char *path;
618 int err;
619 450
620 node = of_find_compatible_node(NULL, NULL, "arm,sp810"); 451 vexpress_clk_of_init();
621 v2m_sysctl_init(of_iomap(node, 0));
622 452
623 v2m_clk_init(); 453 do {
454 node = of_find_compatible_node(node, NULL, "arm,sp804");
455 } while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
456 if (node) {
457 pr_info("Using SP804 '%s' as a clock & events source\n",
458 node->full_name);
459 v2m_sp804_init(of_iomap(node, 0),
460 irq_of_parse_and_map(node, 0));
461 }
624 462
625 err = of_property_read_string(of_aliases, "arm,v2m_timer", &path);
626 if (WARN_ON(err))
627 return;
628 node = of_find_node_by_path(path);
629 v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0));
630 if (arch_timer_of_register() != 0) 463 if (arch_timer_of_register() != 0)
631 twd_local_timer_of_register(); 464 twd_local_timer_of_register();
632 465
633 if (arch_timer_sched_clock_init() != 0) 466 if (arch_timer_sched_clock_init() != 0)
634 versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); 467 versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
468 24000000);
635} 469}
636 470
637static struct sys_timer v2m_dt_timer = { 471static struct sys_timer v2m_dt_timer = {
638 .init = v2m_dt_timer_init, 472 .init = v2m_dt_timer_init,
639}; 473};
640 474
641static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = { 475static const struct of_device_id v2m_dt_bus_match[] __initconst = {
642 OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash", 476 { .compatible = "simple-bus", },
643 &v2m_flash_data), 477 { .compatible = "arm,amba-bus", },
644 OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data), 478 { .compatible = "arm,vexpress,config-bus", },
645 /* RS1 memory map */
646 OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash",
647 &v2m_flash_data),
648 OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data),
649 {} 479 {}
650}; 480};
651 481
652static void __init v2m_dt_init(void) 482static void __init v2m_dt_init(void)
653{ 483{
654 l2x0_of_init(0x00400000, 0xfe0fffff); 484 l2x0_of_init(0x00400000, 0xfe0fffff);
655 of_platform_populate(NULL, of_default_bus_match_table, 485 of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL);
656 v2m_dt_auxdata_lookup, NULL); 486 pm_power_off = vexpress_power_off;
657 pm_power_off = v2m_power_off;
658} 487}
659 488
660const static char *v2m_dt_match[] __initconst = { 489static const char * const v2m_dt_match[] __initconst = {
661 "arm,vexpress", 490 "arm,vexpress",
662 "xen,xenvm", 491 "xen,xenvm",
663 NULL, 492 NULL,
@@ -672,5 +501,5 @@ DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
672 .timer = &v2m_dt_timer, 501 .timer = &v2m_dt_timer,
673 .init_machine = v2m_dt_init, 502 .init_machine = v2m_dt_init,
674 .handle_irq = gic_handle_irq, 503 .handle_irq = gic_handle_irq,
675 .restart = v2m_restart, 504 .restart = vexpress_restart,
676MACHINE_END 505MACHINE_END
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index acab3ef8a310..637bcdf8ce77 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1070,3 +1070,9 @@ config MCP_UCB1200_TS
1070 depends on MCP_UCB1200 && INPUT 1070 depends on MCP_UCB1200 && INPUT
1071 1071
1072endmenu 1072endmenu
1073
1074config VEXPRESS_CONFIG
1075 bool
1076 help
1077 Platform configuration infrastructure for the ARM Ltd.
1078 Versatile Express.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d8ccb630ddb0..296817c6c06f 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -138,3 +138,4 @@ obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
138obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o 138obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o
139obj-$(CONFIG_MFD_SYSCON) += syscon.o 139obj-$(CONFIG_MFD_SYSCON) += syscon.o
140obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o 140obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
141obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c
new file mode 100644
index 000000000000..fae15d880758
--- /dev/null
+++ b/drivers/mfd/vexpress-config.c
@@ -0,0 +1,277 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2012 ARM Limited
12 */
13
14#define pr_fmt(fmt) "vexpress-config: " fmt
15
16#include <linux/bitops.h>
17#include <linux/completion.h>
18#include <linux/export.h>
19#include <linux/init.h>
20#include <linux/list.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/slab.h>
24#include <linux/string.h>
25#include <linux/vexpress.h>
26
27
28#define VEXPRESS_CONFIG_MAX_BRIDGES 2
29
30struct vexpress_config_bridge {
31 struct device_node *node;
32 struct vexpress_config_bridge_info *info;
33 struct list_head transactions;
34 spinlock_t transactions_lock;
35} vexpress_config_bridges[VEXPRESS_CONFIG_MAX_BRIDGES];
36
37static DECLARE_BITMAP(vexpress_config_bridges_map,
38 ARRAY_SIZE(vexpress_config_bridges));
39static DEFINE_MUTEX(vexpress_config_bridges_mutex);
40
41struct vexpress_config_bridge *vexpress_config_bridge_register(
42 struct device_node *node,
43 struct vexpress_config_bridge_info *info)
44{
45 struct vexpress_config_bridge *bridge;
46 int i;
47
48 pr_debug("Registering bridge '%s'\n", info->name);
49
50 mutex_lock(&vexpress_config_bridges_mutex);
51 i = find_first_zero_bit(vexpress_config_bridges_map,
52 ARRAY_SIZE(vexpress_config_bridges));
53 if (i >= ARRAY_SIZE(vexpress_config_bridges)) {
54 pr_err("Can't register more bridges!\n");
55 mutex_unlock(&vexpress_config_bridges_mutex);
56 return NULL;
57 }
58 __set_bit(i, vexpress_config_bridges_map);
59 bridge = &vexpress_config_bridges[i];
60
61 bridge->node = node;
62 bridge->info = info;
63 INIT_LIST_HEAD(&bridge->transactions);
64 spin_lock_init(&bridge->transactions_lock);
65
66 mutex_unlock(&vexpress_config_bridges_mutex);
67
68 return bridge;
69}
70
71void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
72{
73 struct vexpress_config_bridge __bridge = *bridge;
74 int i;
75
76 mutex_lock(&vexpress_config_bridges_mutex);
77 for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++)
78 if (&vexpress_config_bridges[i] == bridge)
79 __clear_bit(i, vexpress_config_bridges_map);
80 mutex_unlock(&vexpress_config_bridges_mutex);
81
82 WARN_ON(!list_empty(&__bridge.transactions));
83 while (!list_empty(&__bridge.transactions))
84 cpu_relax();
85}
86
87
88struct vexpress_config_func {
89 struct vexpress_config_bridge *bridge;
90 void *func;
91};
92
93struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
94 struct device_node *node)
95{
96 struct device_node *bridge_node;
97 struct vexpress_config_func *func;
98 int i;
99
100 if (WARN_ON(dev && node && dev->of_node != node))
101 return NULL;
102 if (dev && !node)
103 node = dev->of_node;
104
105 func = kzalloc(sizeof(*func), GFP_KERNEL);
106 if (!func)
107 return NULL;
108
109 bridge_node = of_node_get(node);
110 while (bridge_node) {
111 const __be32 *prop = of_get_property(bridge_node,
112 "arm,vexpress,config-bridge", NULL);
113
114 if (prop) {
115 bridge_node = of_find_node_by_phandle(
116 be32_to_cpup(prop));
117 break;
118 }
119
120 bridge_node = of_get_next_parent(bridge_node);
121 }
122
123 mutex_lock(&vexpress_config_bridges_mutex);
124 for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++) {
125 struct vexpress_config_bridge *bridge =
126 &vexpress_config_bridges[i];
127
128 if (test_bit(i, vexpress_config_bridges_map) &&
129 bridge->node == bridge_node) {
130 func->bridge = bridge;
131 func->func = bridge->info->func_get(dev, node);
132 break;
133 }
134 }
135 mutex_unlock(&vexpress_config_bridges_mutex);
136
137 if (!func->func) {
138 of_node_put(node);
139 kfree(func);
140 return NULL;
141 }
142
143 return func;
144}
145
146void vexpress_config_func_put(struct vexpress_config_func *func)
147{
148 func->bridge->info->func_put(func->func);
149 of_node_put(func->bridge->node);
150 kfree(func);
151}
152
153
154struct vexpress_config_trans {
155 struct vexpress_config_func *func;
156 int offset;
157 bool write;
158 u32 *data;
159 int status;
160 struct completion completion;
161 struct list_head list;
162};
163
164static void vexpress_config_dump_trans(const char *what,
165 struct vexpress_config_trans *trans)
166{
167 pr_debug("%s %s trans %p func 0x%p offset %d data 0x%x status %d\n",
168 what, trans->write ? "write" : "read", trans,
169 trans->func->func, trans->offset,
170 trans->data ? *trans->data : 0, trans->status);
171}
172
173static int vexpress_config_schedule(struct vexpress_config_trans *trans)
174{
175 int status;
176 struct vexpress_config_bridge *bridge = trans->func->bridge;
177 unsigned long flags;
178
179 init_completion(&trans->completion);
180 trans->status = -EFAULT;
181
182 spin_lock_irqsave(&bridge->transactions_lock, flags);
183
184 vexpress_config_dump_trans("Executing", trans);
185
186 if (list_empty(&bridge->transactions))
187 status = bridge->info->func_exec(trans->func->func,
188 trans->offset, trans->write, trans->data);
189 else
190 status = VEXPRESS_CONFIG_STATUS_WAIT;
191
192 switch (status) {
193 case VEXPRESS_CONFIG_STATUS_DONE:
194 vexpress_config_dump_trans("Finished", trans);
195 trans->status = status;
196 break;
197 case VEXPRESS_CONFIG_STATUS_WAIT:
198 list_add_tail(&trans->list, &bridge->transactions);
199 break;
200 }
201
202 spin_unlock_irqrestore(&bridge->transactions_lock, flags);
203
204 return status;
205}
206
207void vexpress_config_complete(struct vexpress_config_bridge *bridge,
208 int status)
209{
210 struct vexpress_config_trans *trans;
211 unsigned long flags;
212
213 spin_lock_irqsave(&bridge->transactions_lock, flags);
214
215 trans = list_first_entry(&bridge->transactions,
216 struct vexpress_config_trans, list);
217 vexpress_config_dump_trans("Completed", trans);
218
219 trans->status = status;
220 list_del(&trans->list);
221
222 if (!list_empty(&bridge->transactions)) {
223 vexpress_config_dump_trans("Pending", trans);
224
225 bridge->info->func_exec(trans->func->func, trans->offset,
226 trans->write, trans->data);
227 }
228 spin_unlock_irqrestore(&bridge->transactions_lock, flags);
229
230 complete(&trans->completion);
231}
232
233int vexpress_config_wait(struct vexpress_config_trans *trans)
234{
235 wait_for_completion(&trans->completion);
236
237 return trans->status;
238}
239
240
241int vexpress_config_read(struct vexpress_config_func *func, int offset,
242 u32 *data)
243{
244 struct vexpress_config_trans trans = {
245 .func = func,
246 .offset = offset,
247 .write = false,
248 .data = data,
249 .status = 0,
250 };
251 int status = vexpress_config_schedule(&trans);
252
253 if (status == VEXPRESS_CONFIG_STATUS_WAIT)
254 status = vexpress_config_wait(&trans);
255
256 return status;
257}
258EXPORT_SYMBOL(vexpress_config_read);
259
260int vexpress_config_write(struct vexpress_config_func *func, int offset,
261 u32 data)
262{
263 struct vexpress_config_trans trans = {
264 .func = func,
265 .offset = offset,
266 .write = true,
267 .data = &data,
268 .status = 0,
269 };
270 int status = vexpress_config_schedule(&trans);
271
272 if (status == VEXPRESS_CONFIG_STATUS_WAIT)
273 status = vexpress_config_wait(&trans);
274
275 return status;
276}
277EXPORT_SYMBOL(vexpress_config_write);
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
new file mode 100644
index 000000000000..059d6b17b14a
--- /dev/null
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -0,0 +1,552 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2012 ARM Limited
12 */
13
14#include <linux/err.h>
15#include <linux/gpio.h>
16#include <linux/io.h>
17#include <linux/leds.h>
18#include <linux/of_address.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/slab.h>
22#include <linux/stat.h>
23#include <linux/timer.h>
24#include <linux/vexpress.h>
25
26#define SYS_ID 0x000
27#define SYS_SW 0x004
28#define SYS_LED 0x008
29#define SYS_100HZ 0x024
30#define SYS_FLAGS 0x030
31#define SYS_FLAGSSET 0x030
32#define SYS_FLAGSCLR 0x034
33#define SYS_NVFLAGS 0x038
34#define SYS_NVFLAGSSET 0x038
35#define SYS_NVFLAGSCLR 0x03c
36#define SYS_MCI 0x048
37#define SYS_FLASH 0x04c
38#define SYS_CFGSW 0x058
39#define SYS_24MHZ 0x05c
40#define SYS_MISC 0x060
41#define SYS_DMA 0x064
42#define SYS_PROCID0 0x084
43#define SYS_PROCID1 0x088
44#define SYS_CFGDATA 0x0a0
45#define SYS_CFGCTRL 0x0a4
46#define SYS_CFGSTAT 0x0a8
47
48#define SYS_HBI_MASK 0xfff
49#define SYS_ID_HBI_SHIFT 16
50#define SYS_PROCIDx_HBI_SHIFT 0
51
52#define SYS_MCI_CARDIN (1 << 0)
53#define SYS_MCI_WPROT (1 << 1)
54
55#define SYS_FLASH_WPn (1 << 0)
56
57#define SYS_MISC_MASTERSITE (1 << 14)
58
59#define SYS_CFGCTRL_START (1 << 31)
60#define SYS_CFGCTRL_WRITE (1 << 30)
61#define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26)
62#define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
63#define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16)
64#define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12)
65#define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0)
66
67#define SYS_CFGSTAT_ERR (1 << 1)
68#define SYS_CFGSTAT_COMPLETE (1 << 0)
69
70
71static void __iomem *vexpress_sysreg_base;
72static struct device *vexpress_sysreg_dev;
73static int vexpress_master_site;
74
75
76void vexpress_flags_set(u32 data)
77{
78 writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR);
79 writel(data, vexpress_sysreg_base + SYS_FLAGSSET);
80}
81
82u32 vexpress_get_procid(int site)
83{
84 if (site == VEXPRESS_SITE_MASTER)
85 site = vexpress_master_site;
86
87 return readl(vexpress_sysreg_base + (site == VEXPRESS_SITE_DB1 ?
88 SYS_PROCID0 : SYS_PROCID1));
89}
90
91u32 vexpress_get_hbi(int site)
92{
93 u32 id;
94
95 switch (site) {
96 case VEXPRESS_SITE_MB:
97 id = readl(vexpress_sysreg_base + SYS_ID);
98 return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK;
99 case VEXPRESS_SITE_MASTER:
100 case VEXPRESS_SITE_DB1:
101 case VEXPRESS_SITE_DB2:
102 id = vexpress_get_procid(site);
103 return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
104 }
105
106 return ~0;
107}
108
109void __iomem *vexpress_get_24mhz_clock_base(void)
110{
111 return vexpress_sysreg_base + SYS_24MHZ;
112}
113
114
115static void vexpress_sysreg_find_prop(struct device_node *node,
116 const char *name, u32 *val)
117{
118 of_node_get(node);
119 while (node) {
120 if (of_property_read_u32(node, name, val) == 0) {
121 of_node_put(node);
122 return;
123 }
124 node = of_get_next_parent(node);
125 }
126}
127
128unsigned __vexpress_get_site(struct device *dev, struct device_node *node)
129{
130 u32 site = 0;
131
132 WARN_ON(dev && node && dev->of_node != node);
133 if (dev && !node)
134 node = dev->of_node;
135
136 if (node) {
137 vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
138 } else if (dev && dev->bus == &platform_bus_type) {
139 struct platform_device *pdev = to_platform_device(dev);
140
141 if (pdev->num_resources == 1 &&
142 pdev->resource[0].flags == IORESOURCE_BUS)
143 site = pdev->resource[0].start;
144 } else if (dev && strncmp(dev_name(dev), "ct:", 3) == 0) {
145 site = VEXPRESS_SITE_MASTER;
146 }
147
148 if (site == VEXPRESS_SITE_MASTER)
149 site = vexpress_master_site;
150
151 return site;
152}
153
154
155struct vexpress_sysreg_config_func {
156 u32 template;
157 u32 device;
158};
159
160static struct vexpress_config_bridge *vexpress_sysreg_config_bridge;
161static struct timer_list vexpress_sysreg_config_timer;
162static u32 *vexpress_sysreg_config_data;
163static int vexpress_sysreg_config_tries;
164
165static void *vexpress_sysreg_config_func_get(struct device *dev,
166 struct device_node *node)
167{
168 struct vexpress_sysreg_config_func *config_func;
169 u32 site;
170 u32 position = 0;
171 u32 dcc = 0;
172 u32 func_device[2];
173 int err = -EFAULT;
174
175 if (node) {
176 of_node_get(node);
177 vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
178 vexpress_sysreg_find_prop(node, "arm,vexpress,position",
179 &position);
180 vexpress_sysreg_find_prop(node, "arm,vexpress,dcc", &dcc);
181 err = of_property_read_u32_array(node,
182 "arm,vexpress-sysreg,func", func_device,
183 ARRAY_SIZE(func_device));
184 of_node_put(node);
185 } else if (dev && dev->bus == &platform_bus_type) {
186 struct platform_device *pdev = to_platform_device(dev);
187
188 if (pdev->num_resources == 1 &&
189 pdev->resource[0].flags == IORESOURCE_BUS) {
190 site = pdev->resource[0].start;
191 func_device[0] = pdev->resource[0].end;
192 func_device[1] = pdev->id;
193 err = 0;
194 }
195 }
196 if (err)
197 return NULL;
198
199 config_func = kzalloc(sizeof(*config_func), GFP_KERNEL);
200 if (!config_func)
201 return NULL;
202
203 config_func->template = SYS_CFGCTRL_DCC(dcc);
204 config_func->template |= SYS_CFGCTRL_FUNC(func_device[0]);
205 config_func->template |= SYS_CFGCTRL_SITE(site == VEXPRESS_SITE_MASTER ?
206 vexpress_master_site : site);
207 config_func->template |= SYS_CFGCTRL_POSITION(position);
208 config_func->device |= func_device[1];
209
210 dev_dbg(vexpress_sysreg_dev, "func 0x%p = 0x%x, %d\n", config_func,
211 config_func->template, config_func->device);
212
213 return config_func;
214}
215
216static void vexpress_sysreg_config_func_put(void *func)
217{
218 kfree(func);
219}
220
221static int vexpress_sysreg_config_func_exec(void *func, int offset,
222 bool write, u32 *data)
223{
224 int status;
225 struct vexpress_sysreg_config_func *config_func = func;
226 u32 command;
227
228 if (WARN_ON(!vexpress_sysreg_base))
229 return -ENOENT;
230
231 command = readl(vexpress_sysreg_base + SYS_CFGCTRL);
232 if (WARN_ON(command & SYS_CFGCTRL_START))
233 return -EBUSY;
234
235 command = SYS_CFGCTRL_START;
236 command |= write ? SYS_CFGCTRL_WRITE : 0;
237 command |= config_func->template;
238 command |= SYS_CFGCTRL_DEVICE(config_func->device + offset);
239
240 /* Use a canary for reads */
241 if (!write)
242 *data = 0xdeadbeef;
243
244 dev_dbg(vexpress_sysreg_dev, "command %x, data %x\n",
245 command, *data);
246 writel(*data, vexpress_sysreg_base + SYS_CFGDATA);
247 writel(0, vexpress_sysreg_base + SYS_CFGSTAT);
248 writel(command, vexpress_sysreg_base + SYS_CFGCTRL);
249 mb();
250
251 if (vexpress_sysreg_dev) {
252 /* Schedule completion check */
253 if (!write)
254 vexpress_sysreg_config_data = data;
255 vexpress_sysreg_config_tries = 100;
256 mod_timer(&vexpress_sysreg_config_timer,
257 jiffies + usecs_to_jiffies(100));
258 status = VEXPRESS_CONFIG_STATUS_WAIT;
259 } else {
260 /* Early execution, no timer available, have to spin */
261 u32 cfgstat;
262
263 do {
264 cpu_relax();
265 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
266 } while (!cfgstat);
267
268 if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE))
269 *data = readl(vexpress_sysreg_base + SYS_CFGDATA);
270 status = VEXPRESS_CONFIG_STATUS_DONE;
271
272 if (cfgstat & SYS_CFGSTAT_ERR)
273 status = -EINVAL;
274 }
275
276 return status;
277}
278
279struct vexpress_config_bridge_info vexpress_sysreg_config_bridge_info = {
280 .name = "vexpress-sysreg",
281 .func_get = vexpress_sysreg_config_func_get,
282 .func_put = vexpress_sysreg_config_func_put,
283 .func_exec = vexpress_sysreg_config_func_exec,
284};
285
286static void vexpress_sysreg_config_complete(unsigned long data)
287{
288 int status = VEXPRESS_CONFIG_STATUS_DONE;
289 u32 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
290
291 if (cfgstat & SYS_CFGSTAT_ERR)
292 status = -EINVAL;
293 if (!vexpress_sysreg_config_tries--)
294 status = -ETIMEDOUT;
295
296 if (status < 0) {
297 dev_err(vexpress_sysreg_dev, "error %d\n", status);
298 } else if (!(cfgstat & SYS_CFGSTAT_COMPLETE)) {
299 mod_timer(&vexpress_sysreg_config_timer,
300 jiffies + usecs_to_jiffies(50));
301 return;
302 }
303
304 if (vexpress_sysreg_config_data) {
305 *vexpress_sysreg_config_data = readl(vexpress_sysreg_base +
306 SYS_CFGDATA);
307 dev_dbg(vexpress_sysreg_dev, "read data %x\n",
308 *vexpress_sysreg_config_data);
309 vexpress_sysreg_config_data = NULL;
310 }
311
312 vexpress_config_complete(vexpress_sysreg_config_bridge, status);
313}
314
315
316void __init vexpress_sysreg_early_init(void __iomem *base)
317{
318 struct device_node *node = of_find_compatible_node(NULL, NULL,
319 "arm,vexpress-sysreg");
320
321 if (node)
322 base = of_iomap(node, 0);
323
324 if (WARN_ON(!base))
325 return;
326
327 vexpress_sysreg_base = base;
328
329 if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE)
330 vexpress_master_site = VEXPRESS_SITE_DB2;
331 else
332 vexpress_master_site = VEXPRESS_SITE_DB1;
333
334 vexpress_sysreg_config_bridge = vexpress_config_bridge_register(
335 node, &vexpress_sysreg_config_bridge_info);
336 WARN_ON(!vexpress_sysreg_config_bridge);
337}
338
339void __init vexpress_sysreg_of_early_init(void)
340{
341 vexpress_sysreg_early_init(NULL);
342}
343
344
345static struct vexpress_sysreg_gpio {
346 unsigned long reg;
347 u32 value;
348} vexpress_sysreg_gpios[] = {
349 [VEXPRESS_GPIO_MMC_CARDIN] = {
350 .reg = SYS_MCI,
351 .value = SYS_MCI_CARDIN,
352 },
353 [VEXPRESS_GPIO_MMC_WPROT] = {
354 .reg = SYS_MCI,
355 .value = SYS_MCI_WPROT,
356 },
357 [VEXPRESS_GPIO_FLASH_WPn] = {
358 .reg = SYS_FLASH,
359 .value = SYS_FLASH_WPn,
360 },
361};
362
363static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip,
364 unsigned offset)
365{
366 return 0;
367}
368
369static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip,
370 unsigned offset, int value)
371{
372 return 0;
373}
374
375static int vexpress_sysreg_gpio_get(struct gpio_chip *chip,
376 unsigned offset)
377{
378 struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
379 u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
380
381 return !!(reg_value & gpio->value);
382}
383
384static void vexpress_sysreg_gpio_set(struct gpio_chip *chip,
385 unsigned offset, int value)
386{
387 struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
388 u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
389
390 if (value)
391 reg_value |= gpio->value;
392 else
393 reg_value &= ~gpio->value;
394
395 writel(reg_value, vexpress_sysreg_base + gpio->reg);
396}
397
398static struct gpio_chip vexpress_sysreg_gpio_chip = {
399 .label = "vexpress-sysreg",
400 .direction_input = vexpress_sysreg_gpio_direction_input,
401 .direction_output = vexpress_sysreg_gpio_direction_output,
402 .get = vexpress_sysreg_gpio_get,
403 .set = vexpress_sysreg_gpio_set,
404 .ngpio = ARRAY_SIZE(vexpress_sysreg_gpios),
405 .base = 0,
406};
407
408
409static ssize_t vexpress_sysreg_sys_id_show(struct device *dev,
410 struct device_attribute *attr, char *buf)
411{
412 return sprintf(buf, "0x%08x\n", readl(vexpress_sysreg_base + SYS_ID));
413}
414
415DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL);
416
417static int __devinit vexpress_sysreg_probe(struct platform_device *pdev)
418{
419 int err;
420 struct resource *res = platform_get_resource(pdev,
421 IORESOURCE_MEM, 0);
422
423 if (!devm_request_mem_region(&pdev->dev, res->start,
424 resource_size(res), pdev->name)) {
425 dev_err(&pdev->dev, "Failed to request memory region!\n");
426 return -EBUSY;
427 }
428
429 if (!vexpress_sysreg_base)
430 vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start,
431 resource_size(res));
432
433 if (!vexpress_sysreg_base) {
434 dev_err(&pdev->dev, "Failed to obtain base address!\n");
435 return -EFAULT;
436 }
437
438 setup_timer(&vexpress_sysreg_config_timer,
439 vexpress_sysreg_config_complete, 0);
440
441 vexpress_sysreg_gpio_chip.dev = &pdev->dev;
442 err = gpiochip_add(&vexpress_sysreg_gpio_chip);
443 if (err) {
444 vexpress_config_bridge_unregister(
445 vexpress_sysreg_config_bridge);
446 dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n",
447 err);
448 return err;
449 }
450
451 vexpress_sysreg_dev = &pdev->dev;
452
453 device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id);
454
455 return 0;
456}
457
458static const struct of_device_id vexpress_sysreg_match[] = {
459 { .compatible = "arm,vexpress-sysreg", },
460 {},
461};
462
463static struct platform_driver vexpress_sysreg_driver = {
464 .driver = {
465 .name = "vexpress-sysreg",
466 .of_match_table = vexpress_sysreg_match,
467 },
468 .probe = vexpress_sysreg_probe,
469};
470
471static int __init vexpress_sysreg_init(void)
472{
473 return platform_driver_register(&vexpress_sysreg_driver);
474}
475core_initcall(vexpress_sysreg_init);
476
477
478#if defined(CONFIG_LEDS_CLASS)
479
480struct vexpress_sysreg_led {
481 u32 mask;
482 struct led_classdev cdev;
483} vexpress_sysreg_leds[] = {
484 { .mask = 1 << 0, .cdev.name = "v2m:green:user1",
485 .cdev.default_trigger = "heartbeat", },
486 { .mask = 1 << 1, .cdev.name = "v2m:green:user2",
487 .cdev.default_trigger = "mmc0", },
488 { .mask = 1 << 2, .cdev.name = "v2m:green:user3",
489 .cdev.default_trigger = "cpu0", },
490 { .mask = 1 << 3, .cdev.name = "v2m:green:user4",
491 .cdev.default_trigger = "cpu1", },
492 { .mask = 1 << 4, .cdev.name = "v2m:green:user5",
493 .cdev.default_trigger = "cpu2", },
494 { .mask = 1 << 5, .cdev.name = "v2m:green:user6",
495 .cdev.default_trigger = "cpu3", },
496 { .mask = 1 << 6, .cdev.name = "v2m:green:user7",
497 .cdev.default_trigger = "cpu4", },
498 { .mask = 1 << 7, .cdev.name = "v2m:green:user8",
499 .cdev.default_trigger = "cpu5", },
500};
501
502static DEFINE_SPINLOCK(vexpress_sysreg_leds_lock);
503
504static void vexpress_sysreg_led_brightness_set(struct led_classdev *cdev,
505 enum led_brightness brightness)
506{
507 struct vexpress_sysreg_led *led = container_of(cdev,
508 struct vexpress_sysreg_led, cdev);
509 unsigned long flags;
510 u32 val;
511
512 spin_lock_irqsave(&vexpress_sysreg_leds_lock, flags);
513
514 val = readl(vexpress_sysreg_base + SYS_LED);
515 if (brightness == LED_OFF)
516 val &= ~led->mask;
517 else
518 val |= led->mask;
519 writel(val, vexpress_sysreg_base + SYS_LED);
520
521 spin_unlock_irqrestore(&vexpress_sysreg_leds_lock, flags);
522}
523
524static int __init vexpress_sysreg_init_leds(void)
525{
526 struct vexpress_sysreg_led *led;
527 int i;
528
529 /* Clear all user LEDs */
530 writel(0, vexpress_sysreg_base + SYS_LED);
531
532 for (i = 0, led = vexpress_sysreg_leds;
533 i < ARRAY_SIZE(vexpress_sysreg_leds); i++, led++) {
534 int err;
535
536 led->cdev.brightness_set = vexpress_sysreg_led_brightness_set;
537 err = led_classdev_register(vexpress_sysreg_dev, &led->cdev);
538 if (err) {
539 dev_err(vexpress_sysreg_dev,
540 "Failed to register LED %d! (%d)\n",
541 i, err);
542 while (led--, i--)
543 led_classdev_unregister(&led->cdev);
544 return err;
545 }
546 }
547
548 return 0;
549}
550device_initcall(vexpress_sysreg_init_leds);
551
552#endif
diff --git a/include/linux/vexpress.h b/include/linux/vexpress.h
new file mode 100644
index 000000000000..c52215ff4245
--- /dev/null
+++ b/include/linux/vexpress.h
@@ -0,0 +1,121 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2012 ARM Limited
12 */
13
14#ifndef _LINUX_VEXPRESS_H
15#define _LINUX_VEXPRESS_H
16
17#include <linux/device.h>
18
19#define VEXPRESS_SITE_MB 0
20#define VEXPRESS_SITE_DB1 1
21#define VEXPRESS_SITE_DB2 2
22#define VEXPRESS_SITE_MASTER 0xf
23
24#define VEXPRESS_CONFIG_STATUS_DONE 0
25#define VEXPRESS_CONFIG_STATUS_WAIT 1
26
27#define VEXPRESS_GPIO_MMC_CARDIN 0
28#define VEXPRESS_GPIO_MMC_WPROT 1
29#define VEXPRESS_GPIO_FLASH_WPn 2
30
31#define VEXPRESS_RES_FUNC(_site, _func) \
32{ \
33 .start = (_site), \
34 .end = (_func), \
35 .flags = IORESOURCE_BUS, \
36}
37
38/* Config bridge API */
39
40/**
41 * struct vexpress_config_bridge_info - description of the platform
42 * configuration infrastructure bridge.
43 *
44 * @name: Bridge name
45 *
46 * @func_get: Obtains pointer to a configuration function for a given
47 * device or a Device Tree node, to be used with @func_put
48 * and @func_exec. The node pointer should take precedence
49 * over device pointer when both are passed.
50 *
51 * @func_put: Tells the bridge that the function will not be used any
52 * more, so all allocated resources can be released.
53 *
54 * @func_exec: Executes a configuration function read or write operation.
55 * The offset selects a 32 bit word of the value accessed.
56 * Must return VEXPRESS_CONFIG_STATUS_DONE when operation
57 * is finished immediately, VEXPRESS_CONFIG_STATUS_WAIT when
58 * will be completed in some time or negative value in case
59 * of error.
60 */
61struct vexpress_config_bridge_info {
62 const char *name;
63 void *(*func_get)(struct device *dev, struct device_node *node);
64 void (*func_put)(void *func);
65 int (*func_exec)(void *func, int offset, bool write, u32 *data);
66};
67
68struct vexpress_config_bridge;
69
70struct vexpress_config_bridge *vexpress_config_bridge_register(
71 struct device_node *node,
72 struct vexpress_config_bridge_info *info);
73void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge);
74
75void vexpress_config_complete(struct vexpress_config_bridge *bridge,
76 int status);
77
78/* Config function API */
79
80struct vexpress_config_func;
81
82struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
83 struct device_node *node);
84#define vexpress_config_func_get_by_dev(dev) \
85 __vexpress_config_func_get(dev, NULL)
86#define vexpress_config_func_get_by_node(node) \
87 __vexpress_config_func_get(NULL, node)
88void vexpress_config_func_put(struct vexpress_config_func *func);
89
90/* Both may sleep! */
91int vexpress_config_read(struct vexpress_config_func *func, int offset,
92 u32 *data);
93int vexpress_config_write(struct vexpress_config_func *func, int offset,
94 u32 data);
95
96/* Platform control */
97
98u32 vexpress_get_procid(int site);
99u32 vexpress_get_hbi(int site);
100void *vexpress_get_24mhz_clock_base(void);
101void vexpress_flags_set(u32 data);
102
103#define vexpress_get_site_by_node(node) __vexpress_get_site(NULL, node)
104#define vexpress_get_site_by_dev(dev) __vexpress_get_site(dev, NULL)
105unsigned __vexpress_get_site(struct device *dev, struct device_node *node);
106
107void vexpress_sysreg_early_init(void __iomem *base);
108void vexpress_sysreg_of_early_init(void);
109
110void vexpress_power_off(void);
111void vexpress_restart(char str, const char *cmd);
112
113/* Clocks */
114
115struct clk *vexpress_osc_setup(struct device *dev);
116void vexpress_osc_of_setup(struct device_node *node);
117
118void vexpress_clk_init(void __iomem *sp810_base);
119void vexpress_clk_of_init(void);
120
121#endif