diff options
-rw-r--r-- | Documentation/devicetree/bindings/arm/vexpress-sysreg.txt | 50 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/arm/vexpress.txt | 98 | ||||
-rw-r--r-- | arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 146 | ||||
-rw-r--r-- | arch/arm/boot/dts/vexpress-v2m.dtsi | 146 | ||||
-rw-r--r-- | arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts | 121 | ||||
-rw-r--r-- | arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 186 | ||||
-rw-r--r-- | arch/arm/boot/dts/vexpress-v2p-ca5s.dts | 84 | ||||
-rw-r--r-- | arch/arm/boot/dts/vexpress-v2p-ca9.dts | 136 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/sp810.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/ct-ca9x4.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/motherboard.h | 81 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/platsmp.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/v2m.c | 349 | ||||
-rw-r--r-- | drivers/mfd/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/vexpress-config.c | 277 | ||||
-rw-r--r-- | drivers/mfd/vexpress-sysreg.c | 552 | ||||
-rw-r--r-- | include/linux/vexpress.h | 121 |
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 @@ | |||
1 | ARM Versatile Express system registers | ||
2 | -------------------------------------- | ||
3 | |||
4 | This is a system control registers block, providing multiple low level | ||
5 | platform functions like board detection and identification, software | ||
6 | interrupt generation, MMC and NOR Flash control etc. | ||
7 | |||
8 | Required 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 | |||
19 | Example: | ||
20 | v2m_sysreg: sysreg@10000000 { | ||
21 | compatible = "arm,vexpress-sysreg"; | ||
22 | reg = <0x10000000 0x1000>; | ||
23 | gpio-controller; | ||
24 | #gpio-cells = <2>; | ||
25 | }; | ||
26 | |||
27 | This block also can also act a bridge to the platform's configuration | ||
28 | bus via "system control" interface, addressing devices with site number, | ||
29 | position in the board stack, config controller, function and device | ||
30 | numbers - see motherboard's TRM for more details. | ||
31 | |||
32 | The 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 | ||
34 | parent) and relies on the board topology properties - see main vexpress | ||
35 | node documentation for more details. It must must also define the | ||
36 | following 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 | |||
42 | Example: | ||
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 | |||
11 | can be initialized in one of two different configurations ("memory | 11 | can be initialized in one of two different configurations ("memory |
12 | maps"), care must be taken to include the correct one. | 12 | maps"), care must be taken to include the correct one. |
13 | 13 | ||
14 | |||
15 | Root node | ||
16 | --------- | ||
17 | |||
14 | Required properties in the root node: | 18 | Required 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 | |||
53 | CPU nodes | ||
54 | --------- | ||
55 | |||
48 | Top-level standard "cpus" node is required. It must contain a node | 56 | Top-level standard "cpus" node is required. It must contain a node |
49 | with device_type = "cpu" property for every available core, eg.: | 57 | with 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 | |||
71 | Configuration infrastructure | ||
72 | ---------------------------- | ||
73 | |||
74 | The platform has an elaborated configuration system, consisting of | ||
75 | microcontrollers residing on the mother- and daughterboards known | ||
76 | as Motherboard/Daughterboard Configuration Controller (MCC and DCC). | ||
77 | The controllers are responsible for the platform initialization | ||
78 | (reset generation, flash programming, FPGA bitfiles loading etc.) | ||
79 | but also control clock generators, voltage regulators, gather | ||
80 | environmental data like temperature, power consumption etc. Even | ||
81 | the video output switch (FPGA) is controlled that way. | ||
82 | |||
83 | Nodes describing devices controlled by this infrastructure should | ||
84 | point at the bridge device node: | ||
85 | - bridge phandle: | ||
86 | arm,vexpress,config-bridge = <phandle>; | ||
87 | This property can be also defined in a parent node (eg. for a DCC) | ||
88 | and is effective for all children. | ||
89 | |||
90 | |||
91 | Platform topology | ||
92 | ----------------- | ||
93 | |||
94 | As Versatile Express can be configured in number of physically | ||
95 | different setups, the device tree should describe platform topology. | ||
96 | Root node and main motherboard node must define the following | ||
97 | property, 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 | |||
109 | Any of the numbers above defaults to zero if not defined in | ||
110 | the node or any of its parent. | ||
111 | |||
112 | |||
113 | Motherboard | ||
114 | ----------- | ||
115 | |||
62 | The motherboard description file provides a single "motherboard" node | 116 | The motherboard description file provides a single "motherboard" node |
63 | using 2 address cells corresponding to the Static Memory Bus used | 117 | using 2 address cells corresponding to the Static Memory Bus used |
64 | between the motherboard and the tile. The first cell defines the Chip | 118 | between 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 | ||
90 | Current Linux implementation requires a "arm,v2m_timer" alias | 144 | The tile description should define a "smb" node, describing the |
91 | pointing at one of the motherboard's SP804 timers, if it is to be | 145 | Static Memory Bus between the tile and motherboard. It must define |
92 | used as the system timer. This alias should be defined in the | 146 | the following properties: |
93 | motherboard 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 | ||
95 | The tile description must define "ranges", "interrupt-map-mask" and | ||
96 | "interrupt-map" properties to translate the motherboard's address | ||
97 | and interrupt space into one used by the tile's processor. | ||
98 | 158 | ||
99 | Abbreviated example: | 159 | Example 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 | ||
61 | static inline void sysctl_soft_reset(void __iomem *base) | 55 | static 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 @@ | |||
1 | config ARCH_VEXPRESS | 1 | config 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 @@ | |||
4 | ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ | 4 | ccflags-$(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 | ||
7 | obj-y := v2m.o | 7 | obj-y := v2m.o reset.o |
8 | obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o | 8 | obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o |
9 | obj-$(CONFIG_SMP) += platsmp.o | 9 | obj-$(CONFIG_SMP) += platsmp.o |
10 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 10 | obj-$(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 | ||
67 | static 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 | |||
80 | static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) | 68 | static 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 | |||
115 | static struct v2m_osc ct_osc1 = { | ||
116 | .osc = 1, | ||
117 | .rate_min = 10000000, | ||
118 | .rate_max = 80000000, | ||
119 | .rate_default = 23750000, | ||
120 | }; | ||
121 | |||
122 | static struct resource pmu_resources[] = { | 101 | static 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 | ||
131 | static 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 | |||
152 | static void __init ct_ca9x4_init(void) | 140 | static 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 | |||
118 | int v2m_cfg_write(u32 devfn, u32 data); | ||
119 | int v2m_cfg_read(u32 devfn, u32 *data); | ||
120 | void 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 | |||
128 | int 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 | ||
150 | extern struct ct_desc *ct_desc; | 86 | extern struct ct_desc *ct_desc; |
151 | 87 | ||
152 | /* | ||
153 | * OSC clock provider | ||
154 | */ | ||
155 | struct 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 | |||
167 | struct 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 | ||
199 | struct smp_operations __initdata vexpress_smp_ops = { | 200 | struct 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 | ||
61 | static void __iomem *v2m_sysreg_base; | ||
62 | |||
63 | static 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 | |||
77 | static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) | 59 | static 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 | ||
90 | static DEFINE_SPINLOCK(v2m_cfg_lock); | ||
91 | |||
92 | int 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 | |||
116 | int 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 | |||
139 | void __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 | |||
145 | int 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 | |||
153 | static struct resource v2m_pcie_i2c_resource = { | 72 | static 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 | ||
240 | static void v2m_flash_set_vpp(struct platform_device *pdev, int on) | ||
241 | { | ||
242 | writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH); | ||
243 | } | ||
244 | |||
245 | static struct physmap_flash_data v2m_flash_data = { | 159 | static struct physmap_flash_data v2m_flash_data = { |
246 | .width = 4, | 160 | .width = 4, |
247 | .set_vpp = v2m_flash_set_vpp, | ||
248 | }; | 161 | }; |
249 | 162 | ||
250 | static struct resource v2m_flash_resources[] = { | 163 | static 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 | ||
294 | static unsigned int v2m_mmci_status(struct device *dev) | ||
295 | { | ||
296 | return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0); | ||
297 | } | ||
298 | |||
299 | static struct mmci_platform_data v2m_mmci_data = { | 207 | static 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 | |||
213 | static struct resource v2m_sysreg_resources[] = { | ||
214 | { | ||
215 | .start = V2M_SYSREGS, | ||
216 | .end = V2M_SYSREGS + 0xfff, | ||
217 | .flags = IORESOURCE_MEM, | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | static 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 | |||
228 | static 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 | |||
237 | static 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 | |||
246 | static 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 | |||
255 | static 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 | ||
304 | static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL); | 264 | static 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 | |||
329 | static 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 | |||
337 | static 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 | |||
351 | static 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 | |||
362 | static 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 | |||
368 | struct 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 | |||
386 | static 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 | |||
394 | static const char *v2m_ref_clk_periphs[] __initconst = { | ||
395 | "mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */ | ||
396 | }; | ||
397 | |||
398 | static const char *v2m_osc1_periphs[] __initconst = { | ||
399 | "mb:clcd", "1001f000.clcd", "1c1f0000.clcd", /* PL111 CLCD */ | ||
400 | }; | ||
401 | |||
402 | static 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 | |||
412 | static 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 | |||
441 | static void __init v2m_timer_init(void) | 288 | static 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 | |||
459 | static 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 | |||
465 | static 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 | ||
471 | struct ct_desc *ct_desc; | 305 | struct 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) | |||
498 | static void __init v2m_map_io(void) | 332 | static 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, |
543 | MACHINE_END | 383 | MACHINE_END |
544 | 384 | ||
545 | static struct map_desc v2m_rs1_io_desc __initdata = { | 385 | static struct map_desc v2m_rs1_io_desc __initdata = { |
@@ -580,20 +420,13 @@ void __init v2m_dt_map_io(void) | |||
580 | 420 | ||
581 | void __init v2m_dt_init_early(void) | 421 | void __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 | ||
614 | static void __init v2m_dt_timer_init(void) | 447 | static 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 | ||
637 | static struct sys_timer v2m_dt_timer = { | 471 | static struct sys_timer v2m_dt_timer = { |
638 | .init = v2m_dt_timer_init, | 472 | .init = v2m_dt_timer_init, |
639 | }; | 473 | }; |
640 | 474 | ||
641 | static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = { | 475 | static 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 | ||
652 | static void __init v2m_dt_init(void) | 482 | static 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 | ||
660 | const static char *v2m_dt_match[] __initconst = { | 489 | static 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, |
676 | MACHINE_END | 505 | MACHINE_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 | ||
1072 | endmenu | 1072 | endmenu |
1073 | |||
1074 | config 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 | |||
138 | obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o | 138 | obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o |
139 | obj-$(CONFIG_MFD_SYSCON) += syscon.o | 139 | obj-$(CONFIG_MFD_SYSCON) += syscon.o |
140 | obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o | 140 | obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o |
141 | obj-$(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 | |||
30 | struct 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 | |||
37 | static DECLARE_BITMAP(vexpress_config_bridges_map, | ||
38 | ARRAY_SIZE(vexpress_config_bridges)); | ||
39 | static DEFINE_MUTEX(vexpress_config_bridges_mutex); | ||
40 | |||
41 | struct 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 | |||
71 | void 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 | |||
88 | struct vexpress_config_func { | ||
89 | struct vexpress_config_bridge *bridge; | ||
90 | void *func; | ||
91 | }; | ||
92 | |||
93 | struct 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 | |||
146 | void 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 | |||
154 | struct 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 | |||
164 | static 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 | |||
173 | static 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 | |||
207 | void 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 | |||
233 | int vexpress_config_wait(struct vexpress_config_trans *trans) | ||
234 | { | ||
235 | wait_for_completion(&trans->completion); | ||
236 | |||
237 | return trans->status; | ||
238 | } | ||
239 | |||
240 | |||
241 | int 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 | } | ||
258 | EXPORT_SYMBOL(vexpress_config_read); | ||
259 | |||
260 | int 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 | } | ||
277 | EXPORT_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 | |||
71 | static void __iomem *vexpress_sysreg_base; | ||
72 | static struct device *vexpress_sysreg_dev; | ||
73 | static int vexpress_master_site; | ||
74 | |||
75 | |||
76 | void vexpress_flags_set(u32 data) | ||
77 | { | ||
78 | writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR); | ||
79 | writel(data, vexpress_sysreg_base + SYS_FLAGSSET); | ||
80 | } | ||
81 | |||
82 | u32 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 | |||
91 | u32 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 | |||
109 | void __iomem *vexpress_get_24mhz_clock_base(void) | ||
110 | { | ||
111 | return vexpress_sysreg_base + SYS_24MHZ; | ||
112 | } | ||
113 | |||
114 | |||
115 | static 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 | |||
128 | unsigned __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 | |||
155 | struct vexpress_sysreg_config_func { | ||
156 | u32 template; | ||
157 | u32 device; | ||
158 | }; | ||
159 | |||
160 | static struct vexpress_config_bridge *vexpress_sysreg_config_bridge; | ||
161 | static struct timer_list vexpress_sysreg_config_timer; | ||
162 | static u32 *vexpress_sysreg_config_data; | ||
163 | static int vexpress_sysreg_config_tries; | ||
164 | |||
165 | static 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 | |||
216 | static void vexpress_sysreg_config_func_put(void *func) | ||
217 | { | ||
218 | kfree(func); | ||
219 | } | ||
220 | |||
221 | static 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 | |||
279 | struct 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 | |||
286 | static 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 | |||
316 | void __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 | |||
339 | void __init vexpress_sysreg_of_early_init(void) | ||
340 | { | ||
341 | vexpress_sysreg_early_init(NULL); | ||
342 | } | ||
343 | |||
344 | |||
345 | static 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 | |||
363 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | ||
364 | unsigned offset) | ||
365 | { | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
370 | unsigned offset, int value) | ||
371 | { | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static 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 | |||
384 | static 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 | |||
398 | static 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 | |||
409 | static 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 | |||
415 | DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL); | ||
416 | |||
417 | static 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 | |||
458 | static const struct of_device_id vexpress_sysreg_match[] = { | ||
459 | { .compatible = "arm,vexpress-sysreg", }, | ||
460 | {}, | ||
461 | }; | ||
462 | |||
463 | static 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 | |||
471 | static int __init vexpress_sysreg_init(void) | ||
472 | { | ||
473 | return platform_driver_register(&vexpress_sysreg_driver); | ||
474 | } | ||
475 | core_initcall(vexpress_sysreg_init); | ||
476 | |||
477 | |||
478 | #if defined(CONFIG_LEDS_CLASS) | ||
479 | |||
480 | struct 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 | |||
502 | static DEFINE_SPINLOCK(vexpress_sysreg_leds_lock); | ||
503 | |||
504 | static 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 | |||
524 | static 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 | } | ||
550 | device_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 | */ | ||
61 | struct 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 | |||
68 | struct vexpress_config_bridge; | ||
69 | |||
70 | struct vexpress_config_bridge *vexpress_config_bridge_register( | ||
71 | struct device_node *node, | ||
72 | struct vexpress_config_bridge_info *info); | ||
73 | void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge); | ||
74 | |||
75 | void vexpress_config_complete(struct vexpress_config_bridge *bridge, | ||
76 | int status); | ||
77 | |||
78 | /* Config function API */ | ||
79 | |||
80 | struct vexpress_config_func; | ||
81 | |||
82 | struct 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) | ||
88 | void vexpress_config_func_put(struct vexpress_config_func *func); | ||
89 | |||
90 | /* Both may sleep! */ | ||
91 | int vexpress_config_read(struct vexpress_config_func *func, int offset, | ||
92 | u32 *data); | ||
93 | int vexpress_config_write(struct vexpress_config_func *func, int offset, | ||
94 | u32 data); | ||
95 | |||
96 | /* Platform control */ | ||
97 | |||
98 | u32 vexpress_get_procid(int site); | ||
99 | u32 vexpress_get_hbi(int site); | ||
100 | void *vexpress_get_24mhz_clock_base(void); | ||
101 | void 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) | ||
105 | unsigned __vexpress_get_site(struct device *dev, struct device_node *node); | ||
106 | |||
107 | void vexpress_sysreg_early_init(void __iomem *base); | ||
108 | void vexpress_sysreg_of_early_init(void); | ||
109 | |||
110 | void vexpress_power_off(void); | ||
111 | void vexpress_restart(char str, const char *cmd); | ||
112 | |||
113 | /* Clocks */ | ||
114 | |||
115 | struct clk *vexpress_osc_setup(struct device *dev); | ||
116 | void vexpress_osc_of_setup(struct device_node *node); | ||
117 | |||
118 | void vexpress_clk_init(void __iomem *sp810_base); | ||
119 | void vexpress_clk_of_init(void); | ||
120 | |||
121 | #endif | ||