Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[sfrench/cifs-2.6.git] / arch / arm / mach-spear / spear6xx.c
1 /*
2  * arch/arm/mach-spear6xx/spear6xx.c
3  *
4  * SPEAr6XX machines common source file
5  *
6  * Copyright (C) 2009 ST Microelectronics
7  * Rajeev Kumar<rajeev-dlh.kumar@st.com>
8  *
9  * Copyright 2012 Stefan Roese <sr@denx.de>
10  *
11  * This file is licensed under the terms of the GNU General Public
12  * License version 2. This program is licensed "as is" without any
13  * warranty of any kind, whether express or implied.
14  */
15
16 #include <linux/amba/pl08x.h>
17 #include <linux/clk.h>
18 #include <linux/err.h>
19 #include <linux/of.h>
20 #include <linux/of_address.h>
21 #include <linux/of_platform.h>
22 #include <linux/amba/pl080.h>
23 #include <asm/mach/arch.h>
24 #include <asm/mach/time.h>
25 #include <asm/mach/map.h>
26 #include "pl080.h"
27 #include "generic.h"
28 #include <mach/spear.h>
29 #include <mach/misc_regs.h>
30
31 /* dmac device registration */
32 static struct pl08x_channel_data spear600_dma_info[] = {
33         {
34                 .bus_id = "ssp1_rx",
35                 .min_signal = 0,
36                 .max_signal = 0,
37                 .muxval = 0,
38                 .periph_buses = PL08X_AHB1,
39         }, {
40                 .bus_id = "ssp1_tx",
41                 .min_signal = 1,
42                 .max_signal = 1,
43                 .muxval = 0,
44                 .periph_buses = PL08X_AHB1,
45         }, {
46                 .bus_id = "uart0_rx",
47                 .min_signal = 2,
48                 .max_signal = 2,
49                 .muxval = 0,
50                 .periph_buses = PL08X_AHB1,
51         }, {
52                 .bus_id = "uart0_tx",
53                 .min_signal = 3,
54                 .max_signal = 3,
55                 .muxval = 0,
56                 .periph_buses = PL08X_AHB1,
57         }, {
58                 .bus_id = "uart1_rx",
59                 .min_signal = 4,
60                 .max_signal = 4,
61                 .muxval = 0,
62                 .periph_buses = PL08X_AHB1,
63         }, {
64                 .bus_id = "uart1_tx",
65                 .min_signal = 5,
66                 .max_signal = 5,
67                 .muxval = 0,
68                 .periph_buses = PL08X_AHB1,
69         }, {
70                 .bus_id = "ssp2_rx",
71                 .min_signal = 6,
72                 .max_signal = 6,
73                 .muxval = 0,
74                 .periph_buses = PL08X_AHB2,
75         }, {
76                 .bus_id = "ssp2_tx",
77                 .min_signal = 7,
78                 .max_signal = 7,
79                 .muxval = 0,
80                 .periph_buses = PL08X_AHB2,
81         }, {
82                 .bus_id = "ssp0_rx",
83                 .min_signal = 8,
84                 .max_signal = 8,
85                 .muxval = 0,
86                 .periph_buses = PL08X_AHB1,
87         }, {
88                 .bus_id = "ssp0_tx",
89                 .min_signal = 9,
90                 .max_signal = 9,
91                 .muxval = 0,
92                 .periph_buses = PL08X_AHB1,
93         }, {
94                 .bus_id = "i2c_rx",
95                 .min_signal = 10,
96                 .max_signal = 10,
97                 .muxval = 0,
98                 .periph_buses = PL08X_AHB1,
99         }, {
100                 .bus_id = "i2c_tx",
101                 .min_signal = 11,
102                 .max_signal = 11,
103                 .muxval = 0,
104                 .periph_buses = PL08X_AHB1,
105         }, {
106                 .bus_id = "irda",
107                 .min_signal = 12,
108                 .max_signal = 12,
109                 .muxval = 0,
110                 .periph_buses = PL08X_AHB1,
111         }, {
112                 .bus_id = "adc",
113                 .min_signal = 13,
114                 .max_signal = 13,
115                 .muxval = 0,
116                 .periph_buses = PL08X_AHB2,
117         }, {
118                 .bus_id = "to_jpeg",
119                 .min_signal = 14,
120                 .max_signal = 14,
121                 .muxval = 0,
122                 .periph_buses = PL08X_AHB1,
123         }, {
124                 .bus_id = "from_jpeg",
125                 .min_signal = 15,
126                 .max_signal = 15,
127                 .muxval = 0,
128                 .periph_buses = PL08X_AHB1,
129         }, {
130                 .bus_id = "ras0_rx",
131                 .min_signal = 0,
132                 .max_signal = 0,
133                 .muxval = 1,
134                 .periph_buses = PL08X_AHB1,
135         }, {
136                 .bus_id = "ras0_tx",
137                 .min_signal = 1,
138                 .max_signal = 1,
139                 .muxval = 1,
140                 .periph_buses = PL08X_AHB1,
141         }, {
142                 .bus_id = "ras1_rx",
143                 .min_signal = 2,
144                 .max_signal = 2,
145                 .muxval = 1,
146                 .periph_buses = PL08X_AHB1,
147         }, {
148                 .bus_id = "ras1_tx",
149                 .min_signal = 3,
150                 .max_signal = 3,
151                 .muxval = 1,
152                 .periph_buses = PL08X_AHB1,
153         }, {
154                 .bus_id = "ras2_rx",
155                 .min_signal = 4,
156                 .max_signal = 4,
157                 .muxval = 1,
158                 .periph_buses = PL08X_AHB1,
159         }, {
160                 .bus_id = "ras2_tx",
161                 .min_signal = 5,
162                 .max_signal = 5,
163                 .muxval = 1,
164                 .periph_buses = PL08X_AHB1,
165         }, {
166                 .bus_id = "ras3_rx",
167                 .min_signal = 6,
168                 .max_signal = 6,
169                 .muxval = 1,
170                 .periph_buses = PL08X_AHB1,
171         }, {
172                 .bus_id = "ras3_tx",
173                 .min_signal = 7,
174                 .max_signal = 7,
175                 .muxval = 1,
176                 .periph_buses = PL08X_AHB1,
177         }, {
178                 .bus_id = "ras4_rx",
179                 .min_signal = 8,
180                 .max_signal = 8,
181                 .muxval = 1,
182                 .periph_buses = PL08X_AHB1,
183         }, {
184                 .bus_id = "ras4_tx",
185                 .min_signal = 9,
186                 .max_signal = 9,
187                 .muxval = 1,
188                 .periph_buses = PL08X_AHB1,
189         }, {
190                 .bus_id = "ras5_rx",
191                 .min_signal = 10,
192                 .max_signal = 10,
193                 .muxval = 1,
194                 .periph_buses = PL08X_AHB1,
195         }, {
196                 .bus_id = "ras5_tx",
197                 .min_signal = 11,
198                 .max_signal = 11,
199                 .muxval = 1,
200                 .periph_buses = PL08X_AHB1,
201         }, {
202                 .bus_id = "ras6_rx",
203                 .min_signal = 12,
204                 .max_signal = 12,
205                 .muxval = 1,
206                 .periph_buses = PL08X_AHB1,
207         }, {
208                 .bus_id = "ras6_tx",
209                 .min_signal = 13,
210                 .max_signal = 13,
211                 .muxval = 1,
212                 .periph_buses = PL08X_AHB1,
213         }, {
214                 .bus_id = "ras7_rx",
215                 .min_signal = 14,
216                 .max_signal = 14,
217                 .muxval = 1,
218                 .periph_buses = PL08X_AHB1,
219         }, {
220                 .bus_id = "ras7_tx",
221                 .min_signal = 15,
222                 .max_signal = 15,
223                 .muxval = 1,
224                 .periph_buses = PL08X_AHB1,
225         }, {
226                 .bus_id = "ext0_rx",
227                 .min_signal = 0,
228                 .max_signal = 0,
229                 .muxval = 2,
230                 .periph_buses = PL08X_AHB2,
231         }, {
232                 .bus_id = "ext0_tx",
233                 .min_signal = 1,
234                 .max_signal = 1,
235                 .muxval = 2,
236                 .periph_buses = PL08X_AHB2,
237         }, {
238                 .bus_id = "ext1_rx",
239                 .min_signal = 2,
240                 .max_signal = 2,
241                 .muxval = 2,
242                 .periph_buses = PL08X_AHB2,
243         }, {
244                 .bus_id = "ext1_tx",
245                 .min_signal = 3,
246                 .max_signal = 3,
247                 .muxval = 2,
248                 .periph_buses = PL08X_AHB2,
249         }, {
250                 .bus_id = "ext2_rx",
251                 .min_signal = 4,
252                 .max_signal = 4,
253                 .muxval = 2,
254                 .periph_buses = PL08X_AHB2,
255         }, {
256                 .bus_id = "ext2_tx",
257                 .min_signal = 5,
258                 .max_signal = 5,
259                 .muxval = 2,
260                 .periph_buses = PL08X_AHB2,
261         }, {
262                 .bus_id = "ext3_rx",
263                 .min_signal = 6,
264                 .max_signal = 6,
265                 .muxval = 2,
266                 .periph_buses = PL08X_AHB2,
267         }, {
268                 .bus_id = "ext3_tx",
269                 .min_signal = 7,
270                 .max_signal = 7,
271                 .muxval = 2,
272                 .periph_buses = PL08X_AHB2,
273         }, {
274                 .bus_id = "ext4_rx",
275                 .min_signal = 8,
276                 .max_signal = 8,
277                 .muxval = 2,
278                 .periph_buses = PL08X_AHB2,
279         }, {
280                 .bus_id = "ext4_tx",
281                 .min_signal = 9,
282                 .max_signal = 9,
283                 .muxval = 2,
284                 .periph_buses = PL08X_AHB2,
285         }, {
286                 .bus_id = "ext5_rx",
287                 .min_signal = 10,
288                 .max_signal = 10,
289                 .muxval = 2,
290                 .periph_buses = PL08X_AHB2,
291         }, {
292                 .bus_id = "ext5_tx",
293                 .min_signal = 11,
294                 .max_signal = 11,
295                 .muxval = 2,
296                 .periph_buses = PL08X_AHB2,
297         }, {
298                 .bus_id = "ext6_rx",
299                 .min_signal = 12,
300                 .max_signal = 12,
301                 .muxval = 2,
302                 .periph_buses = PL08X_AHB2,
303         }, {
304                 .bus_id = "ext6_tx",
305                 .min_signal = 13,
306                 .max_signal = 13,
307                 .muxval = 2,
308                 .periph_buses = PL08X_AHB2,
309         }, {
310                 .bus_id = "ext7_rx",
311                 .min_signal = 14,
312                 .max_signal = 14,
313                 .muxval = 2,
314                 .periph_buses = PL08X_AHB2,
315         }, {
316                 .bus_id = "ext7_tx",
317                 .min_signal = 15,
318                 .max_signal = 15,
319                 .muxval = 2,
320                 .periph_buses = PL08X_AHB2,
321         },
322 };
323
324 static struct pl08x_platform_data spear6xx_pl080_plat_data = {
325         .memcpy_burst_size = PL08X_BURST_SZ_16,
326         .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
327         .memcpy_prot_buff = true,
328         .memcpy_prot_cache = true,
329         .lli_buses = PL08X_AHB1,
330         .mem_buses = PL08X_AHB1,
331         .get_xfer_signal = pl080_get_signal,
332         .put_xfer_signal = pl080_put_signal,
333         .slave_channels = spear600_dma_info,
334         .num_slave_channels = ARRAY_SIZE(spear600_dma_info),
335 };
336
337 /*
338  * Following will create 16MB static virtual/physical mappings
339  * PHYSICAL             VIRTUAL
340  * 0xF0000000           0xF0000000
341  * 0xF1000000           0xF1000000
342  * 0xD0000000           0xFD000000
343  * 0xFC000000           0xFC000000
344  */
345 struct map_desc spear6xx_io_desc[] __initdata = {
346         {
347                 .virtual        = (unsigned long)VA_SPEAR6XX_ML_CPU_BASE,
348                 .pfn            = __phys_to_pfn(SPEAR_ICM3_ML1_2_BASE),
349                 .length         = 2 * SZ_16M,
350                 .type           = MT_DEVICE
351         },      {
352                 .virtual        = (unsigned long)VA_SPEAR_ICM1_2_BASE,
353                 .pfn            = __phys_to_pfn(SPEAR_ICM1_2_BASE),
354                 .length         = SZ_16M,
355                 .type           = MT_DEVICE
356         }, {
357                 .virtual        = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE,
358                 .pfn            = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE),
359                 .length         = SZ_16M,
360                 .type           = MT_DEVICE
361         },
362 };
363
364 /* This will create static memory mapping for selected devices */
365 void __init spear6xx_map_io(void)
366 {
367         iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
368 }
369
370 void __init spear6xx_timer_init(void)
371 {
372         char pclk_name[] = "pll3_clk";
373         struct clk *gpt_clk, *pclk;
374
375         spear6xx_clk_init(MISC_BASE);
376
377         /* get the system timer clock */
378         gpt_clk = clk_get_sys("gpt0", NULL);
379         if (IS_ERR(gpt_clk)) {
380                 pr_err("%s:couldn't get clk for gpt\n", __func__);
381                 BUG();
382         }
383
384         /* get the suitable parent clock for timer*/
385         pclk = clk_get(NULL, pclk_name);
386         if (IS_ERR(pclk)) {
387                 pr_err("%s:couldn't get %s as parent for gpt\n",
388                                 __func__, pclk_name);
389                 BUG();
390         }
391
392         clk_set_parent(gpt_clk, pclk);
393         clk_put(gpt_clk);
394         clk_put(pclk);
395
396         spear_setup_of_timer();
397 }
398
399 /* Add auxdata to pass platform data */
400 struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
401         OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
402                         &spear6xx_pl080_plat_data),
403         {}
404 };
405
406 static void __init spear600_dt_init(void)
407 {
408         of_platform_default_populate(NULL, spear6xx_auxdata_lookup, NULL);
409 }
410
411 static const char *spear600_dt_board_compat[] = {
412         "st,spear600",
413         NULL
414 };
415
416 DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
417         .map_io         =       spear6xx_map_io,
418         .init_time      =       spear6xx_timer_init,
419         .init_machine   =       spear600_dt_init,
420         .restart        =       spear_restart,
421         .dt_compat      =       spear600_dt_board_compat,
422 MACHINE_END