2 * arch/arm/mach-spear6xx/spear6xx.c
4 * SPEAr6XX machines common source file
6 * Copyright (C) 2009 ST Microelectronics
7 * Rajeev Kumar<rajeev-dlh.kumar@st.com>
9 * Copyright 2012 Stefan Roese <sr@denx.de>
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.
16 #include <linux/amba/pl08x.h>
17 #include <linux/clk.h>
18 #include <linux/err.h>
19 #include <linux/irqchip.h>
21 #include <linux/of_address.h>
22 #include <linux/of_platform.h>
23 #include <linux/amba/pl080.h>
24 #include <asm/mach/arch.h>
25 #include <asm/mach/time.h>
26 #include <asm/mach/map.h>
29 #include <mach/spear.h>
30 #include <mach/misc_regs.h>
32 /* dmac device registration */
33 static struct pl08x_channel_data spear600_dma_info[] = {
39 .periph_buses = PL08X_AHB1,
45 .periph_buses = PL08X_AHB1,
51 .periph_buses = PL08X_AHB1,
57 .periph_buses = PL08X_AHB1,
63 .periph_buses = PL08X_AHB1,
69 .periph_buses = PL08X_AHB1,
75 .periph_buses = PL08X_AHB2,
81 .periph_buses = PL08X_AHB2,
87 .periph_buses = PL08X_AHB1,
93 .periph_buses = PL08X_AHB1,
99 .periph_buses = PL08X_AHB1,
105 .periph_buses = PL08X_AHB1,
111 .periph_buses = PL08X_AHB1,
117 .periph_buses = PL08X_AHB2,
123 .periph_buses = PL08X_AHB1,
125 .bus_id = "from_jpeg",
129 .periph_buses = PL08X_AHB1,
135 .periph_buses = PL08X_AHB1,
141 .periph_buses = PL08X_AHB1,
147 .periph_buses = PL08X_AHB1,
153 .periph_buses = PL08X_AHB1,
159 .periph_buses = PL08X_AHB1,
165 .periph_buses = PL08X_AHB1,
171 .periph_buses = PL08X_AHB1,
177 .periph_buses = PL08X_AHB1,
183 .periph_buses = PL08X_AHB1,
189 .periph_buses = PL08X_AHB1,
195 .periph_buses = PL08X_AHB1,
201 .periph_buses = PL08X_AHB1,
207 .periph_buses = PL08X_AHB1,
213 .periph_buses = PL08X_AHB1,
219 .periph_buses = PL08X_AHB1,
225 .periph_buses = PL08X_AHB1,
231 .periph_buses = PL08X_AHB2,
237 .periph_buses = PL08X_AHB2,
243 .periph_buses = PL08X_AHB2,
249 .periph_buses = PL08X_AHB2,
255 .periph_buses = PL08X_AHB2,
261 .periph_buses = PL08X_AHB2,
267 .periph_buses = PL08X_AHB2,
273 .periph_buses = PL08X_AHB2,
279 .periph_buses = PL08X_AHB2,
285 .periph_buses = PL08X_AHB2,
291 .periph_buses = PL08X_AHB2,
297 .periph_buses = PL08X_AHB2,
303 .periph_buses = PL08X_AHB2,
309 .periph_buses = PL08X_AHB2,
315 .periph_buses = PL08X_AHB2,
321 .periph_buses = PL08X_AHB2,
325 static struct pl08x_platform_data spear6xx_pl080_plat_data = {
329 (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
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),
336 .lli_buses = PL08X_AHB1,
337 .mem_buses = PL08X_AHB1,
338 .get_signal = pl080_get_signal,
339 .put_signal = pl080_put_signal,
340 .slave_channels = spear600_dma_info,
341 .num_slave_channels = ARRAY_SIZE(spear600_dma_info),
345 * Following will create 16MB static virtual/physical mappings
347 * 0xF0000000 0xF0000000
348 * 0xF1000000 0xF1000000
349 * 0xD0000000 0xFD000000
350 * 0xFC000000 0xFC000000
352 struct map_desc spear6xx_io_desc[] __initdata = {
354 .virtual = (unsigned long)VA_SPEAR6XX_ML_CPU_BASE,
355 .pfn = __phys_to_pfn(SPEAR_ICM3_ML1_2_BASE),
356 .length = 2 * SZ_16M,
359 .virtual = (unsigned long)VA_SPEAR_ICM1_2_BASE,
360 .pfn = __phys_to_pfn(SPEAR_ICM1_2_BASE),
364 .virtual = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE,
365 .pfn = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE),
371 /* This will create static memory mapping for selected devices */
372 void __init spear6xx_map_io(void)
374 iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
377 void __init spear6xx_timer_init(void)
379 char pclk_name[] = "pll3_clk";
380 struct clk *gpt_clk, *pclk;
382 spear6xx_clk_init(MISC_BASE);
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__);
391 /* get the suitable parent clock for timer*/
392 pclk = clk_get(NULL, pclk_name);
394 pr_err("%s:couldn't get %s as parent for gpt\n",
395 __func__, pclk_name);
399 clk_set_parent(gpt_clk, pclk);
403 spear_setup_of_timer();
406 /* Add auxdata to pass platform data */
407 struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
408 OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
409 &spear6xx_pl080_plat_data),
413 static void __init spear600_dt_init(void)
415 of_platform_populate(NULL, of_default_bus_match_table,
416 spear6xx_auxdata_lookup, NULL);
419 static const char *spear600_dt_board_compat[] = {
424 DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
425 .map_io = spear6xx_map_io,
426 .init_irq = irqchip_init,
427 .init_time = spear6xx_timer_init,
428 .init_machine = spear600_dt_init,
429 .restart = spear_restart,
430 .dt_compat = spear600_dt_board_compat,