Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spear6xx.c
Go to the documentation of this file.
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<[email protected]>
8  *
9  * Copyright 2012 Stefan Roese <[email protected]>
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_irq.h>
22 #include <linux/of_platform.h>
23 #include <asm/hardware/pl080.h>
24 #include <asm/hardware/vic.h>
25 #include <asm/mach/arch.h>
26 #include <asm/mach/time.h>
27 #include <asm/mach/map.h>
28 #include <plat/pl080.h>
29 #include <mach/generic.h>
30 #include <mach/spear.h>
31 
32 /* dmac device registration */
33 static struct pl08x_channel_data spear600_dma_info[] = {
34  {
35  .bus_id = "ssp1_rx",
36  .min_signal = 0,
37  .max_signal = 0,
38  .muxval = 0,
39  .periph_buses = PL08X_AHB1,
40  }, {
41  .bus_id = "ssp1_tx",
42  .min_signal = 1,
43  .max_signal = 1,
44  .muxval = 0,
45  .periph_buses = PL08X_AHB1,
46  }, {
47  .bus_id = "uart0_rx",
48  .min_signal = 2,
49  .max_signal = 2,
50  .muxval = 0,
51  .periph_buses = PL08X_AHB1,
52  }, {
53  .bus_id = "uart0_tx",
54  .min_signal = 3,
55  .max_signal = 3,
56  .muxval = 0,
57  .periph_buses = PL08X_AHB1,
58  }, {
59  .bus_id = "uart1_rx",
60  .min_signal = 4,
61  .max_signal = 4,
62  .muxval = 0,
63  .periph_buses = PL08X_AHB1,
64  }, {
65  .bus_id = "uart1_tx",
66  .min_signal = 5,
67  .max_signal = 5,
68  .muxval = 0,
69  .periph_buses = PL08X_AHB1,
70  }, {
71  .bus_id = "ssp2_rx",
72  .min_signal = 6,
73  .max_signal = 6,
74  .muxval = 0,
75  .periph_buses = PL08X_AHB2,
76  }, {
77  .bus_id = "ssp2_tx",
78  .min_signal = 7,
79  .max_signal = 7,
80  .muxval = 0,
81  .periph_buses = PL08X_AHB2,
82  }, {
83  .bus_id = "ssp0_rx",
84  .min_signal = 8,
85  .max_signal = 8,
86  .muxval = 0,
87  .periph_buses = PL08X_AHB1,
88  }, {
89  .bus_id = "ssp0_tx",
90  .min_signal = 9,
91  .max_signal = 9,
92  .muxval = 0,
93  .periph_buses = PL08X_AHB1,
94  }, {
95  .bus_id = "i2c_rx",
96  .min_signal = 10,
97  .max_signal = 10,
98  .muxval = 0,
99  .periph_buses = PL08X_AHB1,
100  }, {
101  .bus_id = "i2c_tx",
102  .min_signal = 11,
103  .max_signal = 11,
104  .muxval = 0,
105  .periph_buses = PL08X_AHB1,
106  }, {
107  .bus_id = "irda",
108  .min_signal = 12,
109  .max_signal = 12,
110  .muxval = 0,
111  .periph_buses = PL08X_AHB1,
112  }, {
113  .bus_id = "adc",
114  .min_signal = 13,
115  .max_signal = 13,
116  .muxval = 0,
117  .periph_buses = PL08X_AHB2,
118  }, {
119  .bus_id = "to_jpeg",
120  .min_signal = 14,
121  .max_signal = 14,
122  .muxval = 0,
123  .periph_buses = PL08X_AHB1,
124  }, {
125  .bus_id = "from_jpeg",
126  .min_signal = 15,
127  .max_signal = 15,
128  .muxval = 0,
129  .periph_buses = PL08X_AHB1,
130  }, {
131  .bus_id = "ras0_rx",
132  .min_signal = 0,
133  .max_signal = 0,
134  .muxval = 1,
135  .periph_buses = PL08X_AHB1,
136  }, {
137  .bus_id = "ras0_tx",
138  .min_signal = 1,
139  .max_signal = 1,
140  .muxval = 1,
141  .periph_buses = PL08X_AHB1,
142  }, {
143  .bus_id = "ras1_rx",
144  .min_signal = 2,
145  .max_signal = 2,
146  .muxval = 1,
147  .periph_buses = PL08X_AHB1,
148  }, {
149  .bus_id = "ras1_tx",
150  .min_signal = 3,
151  .max_signal = 3,
152  .muxval = 1,
153  .periph_buses = PL08X_AHB1,
154  }, {
155  .bus_id = "ras2_rx",
156  .min_signal = 4,
157  .max_signal = 4,
158  .muxval = 1,
159  .periph_buses = PL08X_AHB1,
160  }, {
161  .bus_id = "ras2_tx",
162  .min_signal = 5,
163  .max_signal = 5,
164  .muxval = 1,
165  .periph_buses = PL08X_AHB1,
166  }, {
167  .bus_id = "ras3_rx",
168  .min_signal = 6,
169  .max_signal = 6,
170  .muxval = 1,
171  .periph_buses = PL08X_AHB1,
172  }, {
173  .bus_id = "ras3_tx",
174  .min_signal = 7,
175  .max_signal = 7,
176  .muxval = 1,
177  .periph_buses = PL08X_AHB1,
178  }, {
179  .bus_id = "ras4_rx",
180  .min_signal = 8,
181  .max_signal = 8,
182  .muxval = 1,
183  .periph_buses = PL08X_AHB1,
184  }, {
185  .bus_id = "ras4_tx",
186  .min_signal = 9,
187  .max_signal = 9,
188  .muxval = 1,
189  .periph_buses = PL08X_AHB1,
190  }, {
191  .bus_id = "ras5_rx",
192  .min_signal = 10,
193  .max_signal = 10,
194  .muxval = 1,
195  .periph_buses = PL08X_AHB1,
196  }, {
197  .bus_id = "ras5_tx",
198  .min_signal = 11,
199  .max_signal = 11,
200  .muxval = 1,
201  .periph_buses = PL08X_AHB1,
202  }, {
203  .bus_id = "ras6_rx",
204  .min_signal = 12,
205  .max_signal = 12,
206  .muxval = 1,
207  .periph_buses = PL08X_AHB1,
208  }, {
209  .bus_id = "ras6_tx",
210  .min_signal = 13,
211  .max_signal = 13,
212  .muxval = 1,
213  .periph_buses = PL08X_AHB1,
214  }, {
215  .bus_id = "ras7_rx",
216  .min_signal = 14,
217  .max_signal = 14,
218  .muxval = 1,
219  .periph_buses = PL08X_AHB1,
220  }, {
221  .bus_id = "ras7_tx",
222  .min_signal = 15,
223  .max_signal = 15,
224  .muxval = 1,
225  .periph_buses = PL08X_AHB1,
226  }, {
227  .bus_id = "ext0_rx",
228  .min_signal = 0,
229  .max_signal = 0,
230  .muxval = 2,
231  .periph_buses = PL08X_AHB2,
232  }, {
233  .bus_id = "ext0_tx",
234  .min_signal = 1,
235  .max_signal = 1,
236  .muxval = 2,
237  .periph_buses = PL08X_AHB2,
238  }, {
239  .bus_id = "ext1_rx",
240  .min_signal = 2,
241  .max_signal = 2,
242  .muxval = 2,
243  .periph_buses = PL08X_AHB2,
244  }, {
245  .bus_id = "ext1_tx",
246  .min_signal = 3,
247  .max_signal = 3,
248  .muxval = 2,
249  .periph_buses = PL08X_AHB2,
250  }, {
251  .bus_id = "ext2_rx",
252  .min_signal = 4,
253  .max_signal = 4,
254  .muxval = 2,
255  .periph_buses = PL08X_AHB2,
256  }, {
257  .bus_id = "ext2_tx",
258  .min_signal = 5,
259  .max_signal = 5,
260  .muxval = 2,
261  .periph_buses = PL08X_AHB2,
262  }, {
263  .bus_id = "ext3_rx",
264  .min_signal = 6,
265  .max_signal = 6,
266  .muxval = 2,
267  .periph_buses = PL08X_AHB2,
268  }, {
269  .bus_id = "ext3_tx",
270  .min_signal = 7,
271  .max_signal = 7,
272  .muxval = 2,
273  .periph_buses = PL08X_AHB2,
274  }, {
275  .bus_id = "ext4_rx",
276  .min_signal = 8,
277  .max_signal = 8,
278  .muxval = 2,
279  .periph_buses = PL08X_AHB2,
280  }, {
281  .bus_id = "ext4_tx",
282  .min_signal = 9,
283  .max_signal = 9,
284  .muxval = 2,
285  .periph_buses = PL08X_AHB2,
286  }, {
287  .bus_id = "ext5_rx",
288  .min_signal = 10,
289  .max_signal = 10,
290  .muxval = 2,
291  .periph_buses = PL08X_AHB2,
292  }, {
293  .bus_id = "ext5_tx",
294  .min_signal = 11,
295  .max_signal = 11,
296  .muxval = 2,
297  .periph_buses = PL08X_AHB2,
298  }, {
299  .bus_id = "ext6_rx",
300  .min_signal = 12,
301  .max_signal = 12,
302  .muxval = 2,
303  .periph_buses = PL08X_AHB2,
304  }, {
305  .bus_id = "ext6_tx",
306  .min_signal = 13,
307  .max_signal = 13,
308  .muxval = 2,
309  .periph_buses = PL08X_AHB2,
310  }, {
311  .bus_id = "ext7_rx",
312  .min_signal = 14,
313  .max_signal = 14,
314  .muxval = 2,
315  .periph_buses = PL08X_AHB2,
316  }, {
317  .bus_id = "ext7_tx",
318  .min_signal = 15,
319  .max_signal = 15,
320  .muxval = 2,
321  .periph_buses = PL08X_AHB2,
322  },
323 };
324 
326  .memcpy_channel = {
327  .bus_id = "memcpy",
328  .cctl_memcpy =
330  PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
331  PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
332  PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
333  PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
334  PL080_CONTROL_PROT_SYS),
335  },
340  .slave_channels = spear600_dma_info,
341  .num_slave_channels = ARRAY_SIZE(spear600_dma_info),
342 };
343 
344 /*
345  * Following will create 16MB static virtual/physical mappings
346  * PHYSICAL VIRTUAL
347  * 0xF0000000 0xF0000000
348  * 0xF1000000 0xF1000000
349  * 0xD0000000 0xFD000000
350  * 0xFC000000 0xFC000000
351  */
352 struct map_desc spear6xx_io_desc[] __initdata = {
353  {
354  .virtual = VA_SPEAR6XX_ML_CPU_BASE,
356  .length = 2 * SZ_16M,
357  .type = MT_DEVICE
358  }, {
359  .virtual = VA_SPEAR6XX_ICM1_BASE,
361  .length = SZ_16M,
362  .type = MT_DEVICE
363  }, {
366  .length = SZ_16M,
367  .type = MT_DEVICE
368  },
369 };
370 
371 /* This will create static memory mapping for selected devices */
373 {
374  iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
375 }
376 
377 static void __init spear6xx_timer_init(void)
378 {
379  char pclk_name[] = "pll3_clk";
380  struct clk *gpt_clk, *pclk;
381 
383 
384  /* get the system timer clock */
385  gpt_clk = clk_get_sys("gpt0", NULL);
386  if (IS_ERR(gpt_clk)) {
387  pr_err("%s:couldn't get clk for gpt\n", __func__);
388  BUG();
389  }
390 
391  /* get the suitable parent clock for timer*/
392  pclk = clk_get(NULL, pclk_name);
393  if (IS_ERR(pclk)) {
394  pr_err("%s:couldn't get %s as parent for gpt\n",
395  __func__, pclk_name);
396  BUG();
397  }
398 
399  clk_set_parent(gpt_clk, pclk);
400  clk_put(gpt_clk);
401  clk_put(pclk);
402 
404 }
405 
407  .init = spear6xx_timer_init,
408 };
409 
410 /* Add auxdata to pass platform data */
411 struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
412  OF_DEV_AUXDATA("arm,pl080", SPEAR6XX_ICM3_DMA_BASE, NULL,
413  &pl080_plat_data),
414  {}
415 };
416 
417 static void __init spear600_dt_init(void)
418 {
419  of_platform_populate(NULL, of_default_bus_match_table,
420  spear6xx_auxdata_lookup, NULL);
421 }
422 
423 static const char *spear600_dt_board_compat[] = {
424  "st,spear600",
425  NULL
426 };
427 
428 static const struct of_device_id vic_of_match[] __initconst = {
429  { .compatible = "arm,pl190-vic", .data = vic_of_init, },
430  { /* Sentinel */ }
431 };
432 
433 static void __init spear6xx_dt_init_irq(void)
434 {
435  of_irq_init(vic_of_match);
436 }
437 
438 DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
439  .map_io = spear6xx_map_io,
440  .init_irq = spear6xx_dt_init_irq,
441  .handle_irq = vic_handle_irq,
442  .timer = &spear6xx_timer,
443  .init_machine = spear600_dt_init,
444  .restart = spear_restart,
445  .dt_compat = spear600_dt_board_compat,