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>
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>
32 /* dmac device registration */
33 static struct pl08x_channel_data spear600_dma_info[] = {
40 .periph_buses = PL08X_AHB1,
47 .periph_buses = PL08X_AHB1,
54 .periph_buses = PL08X_AHB1,
61 .periph_buses = PL08X_AHB1,
68 .periph_buses = PL08X_AHB1,
75 .periph_buses = PL08X_AHB1,
82 .periph_buses = PL08X_AHB2,
89 .periph_buses = PL08X_AHB2,
96 .periph_buses = PL08X_AHB1,
103 .periph_buses = PL08X_AHB1,
110 .periph_buses = PL08X_AHB1,
117 .periph_buses = PL08X_AHB1,
124 .periph_buses = PL08X_AHB1,
131 .periph_buses = PL08X_AHB2,
138 .periph_buses = PL08X_AHB1,
140 .bus_id = "from_jpeg",
145 .periph_buses = PL08X_AHB1,
152 .periph_buses = PL08X_AHB1,
159 .periph_buses = PL08X_AHB1,
166 .periph_buses = PL08X_AHB1,
173 .periph_buses = PL08X_AHB1,
180 .periph_buses = PL08X_AHB1,
187 .periph_buses = PL08X_AHB1,
194 .periph_buses = PL08X_AHB1,
201 .periph_buses = PL08X_AHB1,
208 .periph_buses = PL08X_AHB1,
215 .periph_buses = PL08X_AHB1,
222 .periph_buses = PL08X_AHB1,
229 .periph_buses = PL08X_AHB1,
236 .periph_buses = PL08X_AHB1,
243 .periph_buses = PL08X_AHB1,
250 .periph_buses = PL08X_AHB1,
257 .periph_buses = PL08X_AHB1,
264 .periph_buses = PL08X_AHB2,
271 .periph_buses = PL08X_AHB2,
278 .periph_buses = PL08X_AHB2,
285 .periph_buses = PL08X_AHB2,
292 .periph_buses = PL08X_AHB2,
299 .periph_buses = PL08X_AHB2,
306 .periph_buses = PL08X_AHB2,
313 .periph_buses = PL08X_AHB2,
320 .periph_buses = PL08X_AHB2,
327 .periph_buses = PL08X_AHB2,
334 .periph_buses = PL08X_AHB2,
341 .periph_buses = PL08X_AHB2,
348 .periph_buses = PL08X_AHB2,
355 .periph_buses = PL08X_AHB2,
362 .periph_buses = PL08X_AHB2,
369 .periph_buses = PL08X_AHB2,
373 struct pl08x_platform_data pl080_plat_data = {
376 .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
377 PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
378 PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
379 PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
380 PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
381 PL080_CONTROL_PROT_SYS),
383 .lli_buses = PL08X_AHB1,
384 .mem_buses = PL08X_AHB1,
385 .get_signal = pl080_get_signal,
386 .put_signal = pl080_put_signal,
387 .slave_channels = spear600_dma_info,
388 .num_slave_channels = ARRAY_SIZE(spear600_dma_info),
392 * Following will create 16MB static virtual/physical mappings
394 * 0xF0000000 0xF0000000
395 * 0xF1000000 0xF1000000
396 * 0xD0000000 0xFD000000
397 * 0xFC000000 0xFC000000
399 struct map_desc spear6xx_io_desc[] __initdata = {
401 .virtual = VA_SPEAR6XX_ML_CPU_BASE,
402 .pfn = __phys_to_pfn(SPEAR6XX_ML_CPU_BASE),
403 .length = 2 * SZ_16M,
406 .virtual = VA_SPEAR6XX_ICM1_BASE,
407 .pfn = __phys_to_pfn(SPEAR6XX_ICM1_BASE),
411 .virtual = VA_SPEAR6XX_ICM3_SMI_CTRL_BASE,
412 .pfn = __phys_to_pfn(SPEAR6XX_ICM3_SMI_CTRL_BASE),
418 /* This will create static memory mapping for selected devices */
419 void __init spear6xx_map_io(void)
421 iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
423 /* This will initialize clock framework */
427 static void __init spear6xx_timer_init(void)
429 char pclk_name[] = "pll3_48m_clk";
430 struct clk *gpt_clk, *pclk;
432 /* get the system timer clock */
433 gpt_clk = clk_get_sys("gpt0", NULL);
434 if (IS_ERR(gpt_clk)) {
435 pr_err("%s:couldn't get clk for gpt\n", __func__);
439 /* get the suitable parent clock for timer*/
440 pclk = clk_get(NULL, pclk_name);
442 pr_err("%s:couldn't get %s as parent for gpt\n",
443 __func__, pclk_name);
447 clk_set_parent(gpt_clk, pclk);
451 spear_setup_timer(SPEAR6XX_CPU_TMR_BASE, IRQ_CPU_GPT1_1);
454 struct sys_timer spear6xx_timer = {
455 .init = spear6xx_timer_init,
458 /* Add auxdata to pass platform data */
459 struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
460 OF_DEV_AUXDATA("arm,pl080", SPEAR6XX_ICM3_DMA_BASE, NULL,
465 static void __init spear600_dt_init(void)
467 of_platform_populate(NULL, of_default_bus_match_table,
468 spear6xx_auxdata_lookup, NULL);
471 static const char *spear600_dt_board_compat[] = {
476 static const struct of_device_id vic_of_match[] __initconst = {
477 { .compatible = "arm,pl190-vic", .data = vic_of_init, },
481 static void __init spear6xx_dt_init_irq(void)
483 of_irq_init(vic_of_match);
486 DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
487 .map_io = spear6xx_map_io,
488 .init_irq = spear6xx_dt_init_irq,
489 .handle_irq = vic_handle_irq,
490 .timer = &spear6xx_timer,
491 .init_machine = spear600_dt_init,
492 .restart = spear_restart,
493 .dt_compat = spear600_dt_board_compat,