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