aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@st.com>2012-04-19 12:53:13 -0400
committerArnd Bergmann <arnd@arndb.de>2012-05-14 11:34:05 -0400
commite3978dc7dfcb9e7b022bda775929943b43bdefd8 (patch)
treec37d37291c0b7df7c3207d2e042d2f1253af2afd /arch/arm
parentb31e23726bb9d6cd8848fc539b23330769830110 (diff)
SPEAr13xx: Add source files
This patch adds source files for SPEAr13xx Machines. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Deepak Sikri <deepak.sikri@st.com> Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-spear13xx/Kconfig18
-rw-r--r--arch/arm/mach-spear13xx/Makefile10
-rw-r--r--arch/arm/mach-spear13xx/Makefile.boot6
-rw-r--r--arch/arm/mach-spear13xx/headsmp.S47
-rw-r--r--arch/arm/mach-spear13xx/hotplug.c119
-rw-r--r--arch/arm/mach-spear13xx/platsmp.c127
-rw-r--r--arch/arm/mach-spear13xx/spear1310.c88
-rw-r--r--arch/arm/mach-spear13xx/spear1340.c192
-rw-r--r--arch/arm/mach-spear13xx/spear13xx.c197
-rw-r--r--arch/arm/plat-spear/restart.c5
10 files changed, 809 insertions, 0 deletions
diff --git a/arch/arm/mach-spear13xx/Kconfig b/arch/arm/mach-spear13xx/Kconfig
new file mode 100644
index 000000000000..138e8918f3e0
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Kconfig
@@ -0,0 +1,18 @@
1#
2# SPEAr13XX Machine configuration file
3#
4
5if ARCH_SPEAR13XX
6
7menu "SPEAr13xx Implementations"
8config MACH_SPEAR1310
9 bool "SPEAr1310 Machine support with Device Tree"
10 help
11 Supports ST SPEAr1310 machine configured via the device-tree
12
13config MACH_SPEAR1340
14 bool "SPEAr1340 Machine support with Device Tree"
15 help
16 Supports ST SPEAr1340 machine configured via the device-tree
17endmenu
18endif #ARCH_SPEAR13XX
diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
new file mode 100644
index 000000000000..3435ea78c15d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for SPEAr13XX machine series
3#
4
5obj-$(CONFIG_SMP) += headsmp.o platsmp.o
6obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
7
8obj-$(CONFIG_ARCH_SPEAR13XX) += spear13xx.o
9obj-$(CONFIG_MACH_SPEAR1310) += spear1310.o
10obj-$(CONFIG_MACH_SPEAR1340) += spear1340.o
diff --git a/arch/arm/mach-spear13xx/Makefile.boot b/arch/arm/mach-spear13xx/Makefile.boot
new file mode 100644
index 000000000000..403efd7e6d27
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile.boot
@@ -0,0 +1,6 @@
1zreladdr-y += 0x00008000
2params_phys-y := 0x00000100
3initrd_phys-y := 0x00800000
4
5dtb-$(CONFIG_MACH_SPEAR1310) += spear1310-evb.dtb
6dtb-$(CONFIG_MACH_SPEAR1340) += spear1340-evb.dtb
diff --git a/arch/arm/mach-spear13xx/headsmp.S b/arch/arm/mach-spear13xx/headsmp.S
new file mode 100644
index 000000000000..ed85473a047f
--- /dev/null
+++ b/arch/arm/mach-spear13xx/headsmp.S
@@ -0,0 +1,47 @@
1/*
2 * arch/arm/mach-spear13XX/headsmp.S
3 *
4 * Picked from realview
5 * Copyright (c) 2012 ST Microelectronics Limited
6 * Shiraz Hashim <shiraz.hashim@st.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <linux/init.h>
15
16 __INIT
17
18/*
19 * spear13xx specific entry point for secondary CPUs. This provides
20 * a "holding pen" into which all secondary cores are held until we're
21 * ready for them to initialise.
22 */
23ENTRY(spear13xx_secondary_startup)
24 mrc p15, 0, r0, c0, c0, 5
25 and r0, r0, #15
26 adr r4, 1f
27 ldmia r4, {r5, r6}
28 sub r4, r4, r5
29 add r6, r6, r4
30pen: ldr r7, [r6]
31 cmp r7, r0
32 bne pen
33
34 /* re-enable coherency */
35 mrc p15, 0, r0, c1, c0, 1
36 orr r0, r0, #(1 << 6) | (1 << 0)
37 mcr p15, 0, r0, c1, c0, 1
38 /*
39 * we've been released from the holding pen: secondary_stack
40 * should now contain the SVC stack for this core
41 */
42 b secondary_startup
43
44 .align
451: .long .
46 .long pen_release
47ENDPROC(spear13xx_secondary_startup)
diff --git a/arch/arm/mach-spear13xx/hotplug.c b/arch/arm/mach-spear13xx/hotplug.c
new file mode 100644
index 000000000000..5c6867b46d09
--- /dev/null
+++ b/arch/arm/mach-spear13xx/hotplug.c
@@ -0,0 +1,119 @@
1/*
2 * linux/arch/arm/mach-spear13xx/hotplug.c
3 *
4 * Copyright (C) 2012 ST Microelectronics Ltd.
5 * Deepak Sikri <deepak.sikri@st.com>
6 *
7 * based upon linux/arch/arm/mach-realview/hotplug.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/smp.h>
16#include <asm/cacheflush.h>
17#include <asm/cp15.h>
18#include <asm/smp_plat.h>
19
20extern volatile int pen_release;
21
22static inline void cpu_enter_lowpower(void)
23{
24 unsigned int v;
25
26 flush_cache_all();
27 asm volatile(
28 " mcr p15, 0, %1, c7, c5, 0\n"
29 " dsb\n"
30 /*
31 * Turn off coherency
32 */
33 " mrc p15, 0, %0, c1, c0, 1\n"
34 " bic %0, %0, #0x20\n"
35 " mcr p15, 0, %0, c1, c0, 1\n"
36 " mrc p15, 0, %0, c1, c0, 0\n"
37 " bic %0, %0, %2\n"
38 " mcr p15, 0, %0, c1, c0, 0\n"
39 : "=&r" (v)
40 : "r" (0), "Ir" (CR_C)
41 : "cc", "memory");
42}
43
44static inline void cpu_leave_lowpower(void)
45{
46 unsigned int v;
47
48 asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
49 " orr %0, %0, %1\n"
50 " mcr p15, 0, %0, c1, c0, 0\n"
51 " mrc p15, 0, %0, c1, c0, 1\n"
52 " orr %0, %0, #0x20\n"
53 " mcr p15, 0, %0, c1, c0, 1\n"
54 : "=&r" (v)
55 : "Ir" (CR_C)
56 : "cc");
57}
58
59static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
60{
61 for (;;) {
62 wfi();
63
64 if (pen_release == cpu) {
65 /*
66 * OK, proper wakeup, we're done
67 */
68 break;
69 }
70
71 /*
72 * Getting here, means that we have come out of WFI without
73 * having been woken up - this shouldn't happen
74 *
75 * Just note it happening - when we're woken, we can report
76 * its occurrence.
77 */
78 (*spurious)++;
79 }
80}
81
82int platform_cpu_kill(unsigned int cpu)
83{
84 return 1;
85}
86
87/*
88 * platform-specific code to shutdown a CPU
89 *
90 * Called with IRQs disabled
91 */
92void __cpuinit platform_cpu_die(unsigned int cpu)
93{
94 int spurious = 0;
95
96 /*
97 * we're ready for shutdown now, so do it
98 */
99 cpu_enter_lowpower();
100 platform_do_lowpower(cpu, &spurious);
101
102 /*
103 * bring this CPU back into the world of cache
104 * coherency, and then restore interrupts
105 */
106 cpu_leave_lowpower();
107
108 if (spurious)
109 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
110}
111
112int platform_cpu_disable(unsigned int cpu)
113{
114 /*
115 * we don't allow CPU 0 to be shutdown (it is still too special
116 * e.g. clock tick interrupts)
117 */
118 return cpu == 0 ? -EPERM : 0;
119}
diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
new file mode 100644
index 000000000000..f5d07f2663d7
--- /dev/null
+++ b/arch/arm/mach-spear13xx/platsmp.c
@@ -0,0 +1,127 @@
1/*
2 * arch/arm/mach-spear13xx/platsmp.c
3 *
4 * based upon linux/arch/arm/mach-realview/platsmp.c
5 *
6 * Copyright (C) 2012 ST Microelectronics Ltd.
7 * Shiraz Hashim <shiraz.hashim@st.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/delay.h>
15#include <linux/jiffies.h>
16#include <linux/io.h>
17#include <linux/smp.h>
18#include <asm/cacheflush.h>
19#include <asm/hardware/gic.h>
20#include <asm/smp_scu.h>
21#include <mach/spear.h>
22
23/*
24 * control for which core is the next to come out of the secondary
25 * boot "holding pen"
26 */
27volatile int __cpuinitdata pen_release = -1;
28static DEFINE_SPINLOCK(boot_lock);
29
30static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
31extern void spear13xx_secondary_startup(void);
32
33void __cpuinit platform_secondary_init(unsigned int cpu)
34{
35 /*
36 * if any interrupts are already enabled for the primary
37 * core (e.g. timer irq), then they will not have been enabled
38 * for us: do so
39 */
40 gic_secondary_init(0);
41
42 /*
43 * let the primary processor know we're out of the
44 * pen, then head off into the C entry point
45 */
46 pen_release = -1;
47 smp_wmb();
48
49 /*
50 * Synchronise with the boot thread.
51 */
52 spin_lock(&boot_lock);
53 spin_unlock(&boot_lock);
54}
55
56int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
57{
58 unsigned long timeout;
59
60 /*
61 * set synchronisation state between this boot processor
62 * and the secondary one
63 */
64 spin_lock(&boot_lock);
65
66 /*
67 * The secondary processor is waiting to be released from
68 * the holding pen - release it, then wait for it to flag
69 * that it has been released by resetting pen_release.
70 *
71 * Note that "pen_release" is the hardware CPU ID, whereas
72 * "cpu" is Linux's internal ID.
73 */
74 pen_release = cpu;
75 flush_cache_all();
76 outer_flush_all();
77
78 timeout = jiffies + (1 * HZ);
79 while (time_before(jiffies, timeout)) {
80 smp_rmb();
81 if (pen_release == -1)
82 break;
83
84 udelay(10);
85 }
86
87 /*
88 * now the secondary core is starting up let it run its
89 * calibrations, then wait for it to finish
90 */
91 spin_unlock(&boot_lock);
92
93 return pen_release != -1 ? -ENOSYS : 0;
94}
95
96/*
97 * Initialise the CPU possible map early - this describes the CPUs
98 * which may be present or become present in the system.
99 */
100void __init smp_init_cpus(void)
101{
102 unsigned int i, ncores = scu_get_core_count(scu_base);
103
104 if (ncores > nr_cpu_ids) {
105 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
106 ncores, nr_cpu_ids);
107 ncores = nr_cpu_ids;
108 }
109
110 for (i = 0; i < ncores; i++)
111 set_cpu_possible(i, true);
112
113 set_smp_cross_call(gic_raise_softirq);
114}
115
116void __init platform_smp_prepare_cpus(unsigned int max_cpus)
117{
118
119 scu_enable(scu_base);
120
121 /*
122 * Write the address of secondary startup into the system-wide location
123 * (presently it is in SRAM). The BootMonitor waits until it receives a
124 * soft interrupt, and then the secondary CPU branches to this address.
125 */
126 __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
127}
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
new file mode 100644
index 000000000000..fefd15b2f380
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -0,0 +1,88 @@
1/*
2 * arch/arm/mach-spear13xx/spear1310.c
3 *
4 * SPEAr1310 machine source file
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#define pr_fmt(fmt) "SPEAr1310: " fmt
15
16#include <linux/amba/pl022.h>
17#include <linux/of_platform.h>
18#include <asm/hardware/gic.h>
19#include <asm/mach/arch.h>
20#include <asm/mach/map.h>
21#include <mach/generic.h>
22#include <mach/spear.h>
23
24/* Base addresses */
25#define SPEAR1310_SSP1_BASE UL(0x5D400000)
26#define SPEAR1310_SATA0_BASE UL(0xB1000000)
27#define SPEAR1310_SATA1_BASE UL(0xB1800000)
28#define SPEAR1310_SATA2_BASE UL(0xB4000000)
29
30/* ssp device registration */
31static struct pl022_ssp_controller ssp1_plat_data = {
32 .bus_id = 0,
33 .enable_dma = 0,
34 .num_chipselect = 3,
35};
36
37/* Add SPEAr1310 auxdata to pass platform data */
38static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = {
39 OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
40 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
41 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
42 OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
43
44 OF_DEV_AUXDATA("arm,pl022", SPEAR1310_SSP1_BASE, NULL, &ssp1_plat_data),
45 {}
46};
47
48static void __init spear1310_dt_init(void)
49{
50 of_platform_populate(NULL, of_default_bus_match_table,
51 spear1310_auxdata_lookup, NULL);
52}
53
54static const char * const spear1310_dt_board_compat[] = {
55 "st,spear1310",
56 "st,spear1310-evb",
57 NULL,
58};
59
60/*
61 * Following will create 16MB static virtual/physical mappings
62 * PHYSICAL VIRTUAL
63 * 0xD8000000 0xFA000000
64 */
65struct map_desc spear1310_io_desc[] __initdata = {
66 {
67 .virtual = VA_SPEAR1310_RAS_GRP1_BASE,
68 .pfn = __phys_to_pfn(SPEAR1310_RAS_GRP1_BASE),
69 .length = SZ_16M,
70 .type = MT_DEVICE
71 },
72};
73
74static void __init spear1310_map_io(void)
75{
76 iotable_init(spear1310_io_desc, ARRAY_SIZE(spear1310_io_desc));
77 spear13xx_map_io();
78}
79
80DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
81 .map_io = spear1310_map_io,
82 .init_irq = spear13xx_dt_init_irq,
83 .handle_irq = gic_handle_irq,
84 .timer = &spear13xx_timer,
85 .init_machine = spear1310_dt_init,
86 .restart = spear_restart,
87 .dt_compat = spear1310_dt_board_compat,
88MACHINE_END
diff --git a/arch/arm/mach-spear13xx/spear1340.c b/arch/arm/mach-spear13xx/spear1340.c
new file mode 100644
index 000000000000..ee38cbc56869
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1340.c
@@ -0,0 +1,192 @@
1/*
2 * arch/arm/mach-spear13xx/spear1340.c
3 *
4 * SPEAr1340 machine source file
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#define pr_fmt(fmt) "SPEAr1340: " fmt
15
16#include <linux/ahci_platform.h>
17#include <linux/amba/serial.h>
18#include <linux/delay.h>
19#include <linux/dw_dmac.h>
20#include <linux/of_platform.h>
21#include <asm/hardware/gic.h>
22#include <asm/mach/arch.h>
23#include <mach/dma.h>
24#include <mach/generic.h>
25#include <mach/spear.h>
26
27/* Base addresses */
28#define SPEAR1340_SATA_BASE UL(0xB1000000)
29#define SPEAR1340_UART1_BASE UL(0xB4100000)
30
31/* Power Management Registers */
32#define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100)
33#define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104)
34#define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108)
35
36#define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318)
37#define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C)
38#define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320)
39
40/* PCIE - SATA configuration registers */
41#define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424)
42 /* PCIE CFG MASks */
43 #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11)
44 #define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10)
45 #define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9)
46 #define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8)
47 #define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4)
48 #define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3)
49 #define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2)
50 #define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1)
51 #define SPEAR1340_PCIE_SATA_SEL_PCIE (0)
52 #define SPEAR1340_PCIE_SATA_SEL_SATA (1)
53 #define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F
54 #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \
55 SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
56 SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
57 SPEAR1340_PCIE_CFG_POWERUP_RESET | \
58 SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
59 #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \
60 SPEAR1340_SATA_CFG_PM_CLK_EN | \
61 SPEAR1340_SATA_CFG_POWERUP_RESET | \
62 SPEAR1340_SATA_CFG_RX_CLK_EN | \
63 SPEAR1340_SATA_CFG_TX_CLK_EN)
64
65#define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428)
66 #define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31)
67 #define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27)
68 #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27)
69 #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27)
70 #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0)
71 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
72 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
73 SPEAR1340_MIPHY_CLK_REF_DIV2 | \
74 SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
75 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
76 (SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
77 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
78 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
79 SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
80
81static struct dw_dma_slave uart1_dma_param[] = {
82 {
83 /* Tx */
84 .cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX),
85 .cfg_lo = 0,
86 .src_master = DMA_MASTER_MEMORY,
87 .dst_master = SPEAR1340_DMA_MASTER_UART1,
88 }, {
89 /* Rx */
90 .cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX),
91 .cfg_lo = 0,
92 .src_master = SPEAR1340_DMA_MASTER_UART1,
93 .dst_master = DMA_MASTER_MEMORY,
94 }
95};
96
97static struct amba_pl011_data uart1_data = {
98 .dma_filter = dw_dma_filter,
99 .dma_tx_param = &uart1_dma_param[0],
100 .dma_rx_param = &uart1_dma_param[1],
101};
102
103/* SATA device registration */
104static int sata_miphy_init(struct device *dev, void __iomem *addr)
105{
106 writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
107 writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
108 SPEAR1340_PCIE_MIPHY_CFG);
109 /* Switch on sata power domain */
110 writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
111 msleep(20);
112 /* Disable PCIE SATA Controller reset */
113 writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
114 SPEAR1340_PERIP1_SW_RST);
115 msleep(20);
116
117 return 0;
118}
119
120void sata_miphy_exit(struct device *dev)
121{
122 writel(0, SPEAR1340_PCIE_SATA_CFG);
123 writel(0, SPEAR1340_PCIE_MIPHY_CFG);
124
125 /* Enable PCIE SATA Controller reset */
126 writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
127 SPEAR1340_PERIP1_SW_RST);
128 msleep(20);
129 /* Switch off sata power domain */
130 writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
131 msleep(20);
132}
133
134int sata_suspend(struct device *dev)
135{
136 if (dev->power.power_state.event == PM_EVENT_FREEZE)
137 return 0;
138
139 sata_miphy_exit(dev);
140
141 return 0;
142}
143
144int sata_resume(struct device *dev)
145{
146 if (dev->power.power_state.event == PM_EVENT_THAW)
147 return 0;
148
149 return sata_miphy_init(dev, NULL);
150}
151
152static struct ahci_platform_data sata_pdata = {
153 .init = sata_miphy_init,
154 .exit = sata_miphy_exit,
155 .suspend = sata_suspend,
156 .resume = sata_resume,
157};
158
159/* Add SPEAr1340 auxdata to pass platform data */
160static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
161 OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
162 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
163 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
164 OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
165
166 OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
167 &sata_pdata),
168 OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data),
169 {}
170};
171
172static void __init spear1340_dt_init(void)
173{
174 of_platform_populate(NULL, of_default_bus_match_table,
175 spear1340_auxdata_lookup, NULL);
176}
177
178static const char * const spear1340_dt_board_compat[] = {
179 "st,spear1340",
180 "st,spear1340-evb",
181 NULL,
182};
183
184DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
185 .map_io = spear13xx_map_io,
186 .init_irq = spear13xx_dt_init_irq,
187 .handle_irq = gic_handle_irq,
188 .timer = &spear13xx_timer,
189 .init_machine = spear1340_dt_init,
190 .restart = spear_restart,
191 .dt_compat = spear1340_dt_board_compat,
192MACHINE_END
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
new file mode 100644
index 000000000000..50b349ae863d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -0,0 +1,197 @@
1/*
2 * arch/arm/mach-spear13xx/spear13xx.c
3 *
4 * SPEAr13XX machines common source file
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#define pr_fmt(fmt) "SPEAr13xx: " fmt
15
16#include <linux/amba/pl022.h>
17#include <linux/clk.h>
18#include <linux/dw_dmac.h>
19#include <linux/err.h>
20#include <linux/of_irq.h>
21#include <asm/hardware/cache-l2x0.h>
22#include <asm/hardware/gic.h>
23#include <asm/mach/map.h>
24#include <asm/smp_twd.h>
25#include <mach/dma.h>
26#include <mach/generic.h>
27#include <mach/spear.h>
28
29/* common dw_dma filter routine to be used by peripherals */
30bool dw_dma_filter(struct dma_chan *chan, void *slave)
31{
32 struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
33
34 if (chan->device->dev == dws->dma_dev) {
35 chan->private = slave;
36 return true;
37 } else {
38 return false;
39 }
40}
41
42/* ssp device registration */
43static struct dw_dma_slave ssp_dma_param[] = {
44 {
45 /* Tx */
46 .cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX),
47 .cfg_lo = 0,
48 .src_master = DMA_MASTER_MEMORY,
49 .dst_master = DMA_MASTER_SSP0,
50 }, {
51 /* Rx */
52 .cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX),
53 .cfg_lo = 0,
54 .src_master = DMA_MASTER_SSP0,
55 .dst_master = DMA_MASTER_MEMORY,
56 }
57};
58
59struct pl022_ssp_controller pl022_plat_data = {
60 .bus_id = 0,
61 .enable_dma = 1,
62 .dma_filter = dw_dma_filter,
63 .dma_rx_param = &ssp_dma_param[1],
64 .dma_tx_param = &ssp_dma_param[0],
65 .num_chipselect = 3,
66};
67
68/* CF device registration */
69struct dw_dma_slave cf_dma_priv = {
70 .cfg_hi = 0,
71 .cfg_lo = 0,
72 .src_master = 0,
73 .dst_master = 0,
74};
75
76/* dmac device registeration */
77struct dw_dma_platform_data dmac_plat_data = {
78 .nr_channels = 8,
79 .chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
80 .chan_priority = CHAN_PRIORITY_DESCENDING,
81};
82
83void __init spear13xx_l2x0_init(void)
84{
85 /*
86 * 512KB (64KB/way), 8-way associativity, parity supported
87 *
88 * FIXME: 9th bit, of Auxillary Controller register must be set
89 * for some spear13xx devices for stable L2 operation.
90 *
91 * Enable Early BRESP, L2 prefetch for Instruction and Data,
92 * write alloc and 'Full line of zero' options
93 *
94 */
95
96 writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
97
98 /*
99 * Program following latencies in order to make
100 * SPEAr1340 work at 600 MHz
101 */
102 writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
103 writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
104 l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
105}
106
107/*
108 * Following will create 16MB static virtual/physical mappings
109 * PHYSICAL VIRTUAL
110 * 0xB3000000 0xFE000000
111 * 0xE0000000 0xFD000000
112 * 0xEC000000 0xFC000000
113 * 0xED000000 0xFB000000
114 */
115struct map_desc spear13xx_io_desc[] __initdata = {
116 {
117 .virtual = VA_PERIP_GRP2_BASE,
118 .pfn = __phys_to_pfn(PERIP_GRP2_BASE),
119 .length = SZ_16M,
120 .type = MT_DEVICE
121 }, {
122 .virtual = VA_PERIP_GRP1_BASE,
123 .pfn = __phys_to_pfn(PERIP_GRP1_BASE),
124 .length = SZ_16M,
125 .type = MT_DEVICE
126 }, {
127 .virtual = VA_A9SM_AND_MPMC_BASE,
128 .pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE),
129 .length = SZ_16M,
130 .type = MT_DEVICE
131 }, {
132 .virtual = (unsigned long)VA_L2CC_BASE,
133 .pfn = __phys_to_pfn(L2CC_BASE),
134 .length = SZ_4K,
135 .type = MT_DEVICE
136 },
137};
138
139/* This will create static memory mapping for selected devices */
140void __init spear13xx_map_io(void)
141{
142 iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
143}
144
145static void __init spear13xx_clk_init(void)
146{
147 if (of_machine_is_compatible("st,spear1310"))
148 spear1310_clk_init();
149 else if (of_machine_is_compatible("st,spear1340"))
150 spear1340_clk_init();
151 else
152 pr_err("%s: Unknown machine\n", __func__);
153}
154
155static void __init spear13xx_timer_init(void)
156{
157 char pclk_name[] = "osc_24m_clk";
158 struct clk *gpt_clk, *pclk;
159
160 spear13xx_clk_init();
161
162 /* get the system timer clock */
163 gpt_clk = clk_get_sys("gpt0", NULL);
164 if (IS_ERR(gpt_clk)) {
165 pr_err("%s:couldn't get clk for gpt\n", __func__);
166 BUG();
167 }
168
169 /* get the suitable parent clock for timer*/
170 pclk = clk_get(NULL, pclk_name);
171 if (IS_ERR(pclk)) {
172 pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
173 pclk_name);
174 BUG();
175 }
176
177 clk_set_parent(gpt_clk, pclk);
178 clk_put(gpt_clk);
179 clk_put(pclk);
180
181 spear_setup_of_timer();
182 twd_local_timer_of_register();
183}
184
185struct sys_timer spear13xx_timer = {
186 .init = spear13xx_timer_init,
187};
188
189static const struct of_device_id gic_of_match[] __initconst = {
190 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
191 { /* Sentinel */ }
192};
193
194void __init spear13xx_dt_init_irq(void)
195{
196 of_irq_init(gic_of_match);
197}
diff --git a/arch/arm/plat-spear/restart.c b/arch/arm/plat-spear/restart.c
index 4471a232713a..ea0a61302b7e 100644
--- a/arch/arm/plat-spear/restart.c
+++ b/arch/arm/plat-spear/restart.c
@@ -16,6 +16,7 @@
16#include <mach/spear.h> 16#include <mach/spear.h>
17#include <mach/generic.h> 17#include <mach/generic.h>
18 18
19#define SPEAR13XX_SYS_SW_RES (VA_MISC_BASE + 0x204)
19void spear_restart(char mode, const char *cmd) 20void spear_restart(char mode, const char *cmd)
20{ 21{
21 if (mode == 's') { 22 if (mode == 's') {
@@ -23,6 +24,10 @@ void spear_restart(char mode, const char *cmd)
23 soft_restart(0); 24 soft_restart(0);
24 } else { 25 } else {
25 /* hardware reset, Use on-chip reset capability */ 26 /* hardware reset, Use on-chip reset capability */
27#ifdef CONFIG_ARCH_SPEAR13XX
28 writel_relaxed(0x01, SPEAR13XX_SYS_SW_RES);
29#else
26 sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE); 30 sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
31#endif
27 } 32 }
28} 33}