diff options
Diffstat (limited to 'arch/arm/mach-spear/spear1340.c')
-rw-r--r-- | arch/arm/mach-spear/spear1340.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c new file mode 100644 index 000000000000..75e38644bbfb --- /dev/null +++ b/arch/arm/mach-spear/spear1340.c | |||
@@ -0,0 +1,193 @@ | |||
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.linux@gmail.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 <linux/irqchip.h> | ||
22 | #include <asm/mach/arch.h> | ||
23 | #include "generic.h" | ||
24 | #include <mach/spear.h> | ||
25 | |||
26 | #include "spear13xx-dma.h" | ||
27 | |||
28 | /* Base addresses */ | ||
29 | #define SPEAR1340_SATA_BASE UL(0xB1000000) | ||
30 | #define SPEAR1340_UART1_BASE UL(0xB4100000) | ||
31 | |||
32 | /* Power Management Registers */ | ||
33 | #define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100) | ||
34 | #define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104) | ||
35 | #define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108) | ||
36 | |||
37 | #define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318) | ||
38 | #define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C) | ||
39 | #define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320) | ||
40 | |||
41 | /* PCIE - SATA configuration registers */ | ||
42 | #define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424) | ||
43 | /* PCIE CFG MASks */ | ||
44 | #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11) | ||
45 | #define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10) | ||
46 | #define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9) | ||
47 | #define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8) | ||
48 | #define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4) | ||
49 | #define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3) | ||
50 | #define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2) | ||
51 | #define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1) | ||
52 | #define SPEAR1340_PCIE_SATA_SEL_PCIE (0) | ||
53 | #define SPEAR1340_PCIE_SATA_SEL_SATA (1) | ||
54 | #define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F | ||
55 | #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \ | ||
56 | SPEAR1340_PCIE_CFG_AUX_CLK_EN | \ | ||
57 | SPEAR1340_PCIE_CFG_CORE_CLK_EN | \ | ||
58 | SPEAR1340_PCIE_CFG_POWERUP_RESET | \ | ||
59 | SPEAR1340_PCIE_CFG_DEVICE_PRESENT) | ||
60 | #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \ | ||
61 | SPEAR1340_SATA_CFG_PM_CLK_EN | \ | ||
62 | SPEAR1340_SATA_CFG_POWERUP_RESET | \ | ||
63 | SPEAR1340_SATA_CFG_RX_CLK_EN | \ | ||
64 | SPEAR1340_SATA_CFG_TX_CLK_EN) | ||
65 | |||
66 | #define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428) | ||
67 | #define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31) | ||
68 | #define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27) | ||
69 | #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27) | ||
70 | #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27) | ||
71 | #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0) | ||
72 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \ | ||
73 | (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ | ||
74 | SPEAR1340_MIPHY_CLK_REF_DIV2 | \ | ||
75 | SPEAR1340_MIPHY_PLL_RATIO_TOP(60)) | ||
76 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \ | ||
77 | (SPEAR1340_MIPHY_PLL_RATIO_TOP(120)) | ||
78 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \ | ||
79 | (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ | ||
80 | SPEAR1340_MIPHY_PLL_RATIO_TOP(25)) | ||
81 | |||
82 | static struct dw_dma_slave uart1_dma_param[] = { | ||
83 | { | ||
84 | /* Tx */ | ||
85 | .cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX), | ||
86 | .cfg_lo = 0, | ||
87 | .src_master = DMA_MASTER_MEMORY, | ||
88 | .dst_master = SPEAR1340_DMA_MASTER_UART1, | ||
89 | }, { | ||
90 | /* Rx */ | ||
91 | .cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX), | ||
92 | .cfg_lo = 0, | ||
93 | .src_master = SPEAR1340_DMA_MASTER_UART1, | ||
94 | .dst_master = DMA_MASTER_MEMORY, | ||
95 | } | ||
96 | }; | ||
97 | |||
98 | static struct amba_pl011_data uart1_data = { | ||
99 | .dma_filter = dw_dma_filter, | ||
100 | .dma_tx_param = &uart1_dma_param[0], | ||
101 | .dma_rx_param = &uart1_dma_param[1], | ||
102 | }; | ||
103 | |||
104 | /* SATA device registration */ | ||
105 | static int sata_miphy_init(struct device *dev, void __iomem *addr) | ||
106 | { | ||
107 | writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG); | ||
108 | writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK, | ||
109 | SPEAR1340_PCIE_MIPHY_CFG); | ||
110 | /* Switch on sata power domain */ | ||
111 | writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG); | ||
112 | msleep(20); | ||
113 | /* Disable PCIE SATA Controller reset */ | ||
114 | writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)), | ||
115 | SPEAR1340_PERIP1_SW_RST); | ||
116 | msleep(20); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | void sata_miphy_exit(struct device *dev) | ||
122 | { | ||
123 | writel(0, SPEAR1340_PCIE_SATA_CFG); | ||
124 | writel(0, SPEAR1340_PCIE_MIPHY_CFG); | ||
125 | |||
126 | /* Enable PCIE SATA Controller reset */ | ||
127 | writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)), | ||
128 | SPEAR1340_PERIP1_SW_RST); | ||
129 | msleep(20); | ||
130 | /* Switch off sata power domain */ | ||
131 | writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG); | ||
132 | msleep(20); | ||
133 | } | ||
134 | |||
135 | int sata_suspend(struct device *dev) | ||
136 | { | ||
137 | if (dev->power.power_state.event == PM_EVENT_FREEZE) | ||
138 | return 0; | ||
139 | |||
140 | sata_miphy_exit(dev); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | int sata_resume(struct device *dev) | ||
146 | { | ||
147 | if (dev->power.power_state.event == PM_EVENT_THAW) | ||
148 | return 0; | ||
149 | |||
150 | return sata_miphy_init(dev, NULL); | ||
151 | } | ||
152 | |||
153 | static struct ahci_platform_data sata_pdata = { | ||
154 | .init = sata_miphy_init, | ||
155 | .exit = sata_miphy_exit, | ||
156 | .suspend = sata_suspend, | ||
157 | .resume = sata_resume, | ||
158 | }; | ||
159 | |||
160 | /* Add SPEAr1340 auxdata to pass platform data */ | ||
161 | static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = { | ||
162 | OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv), | ||
163 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data), | ||
164 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data), | ||
165 | OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data), | ||
166 | |||
167 | OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL, | ||
168 | &sata_pdata), | ||
169 | OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data), | ||
170 | {} | ||
171 | }; | ||
172 | |||
173 | static void __init spear1340_dt_init(void) | ||
174 | { | ||
175 | of_platform_populate(NULL, of_default_bus_match_table, | ||
176 | spear1340_auxdata_lookup, NULL); | ||
177 | } | ||
178 | |||
179 | static const char * const spear1340_dt_board_compat[] = { | ||
180 | "st,spear1340", | ||
181 | "st,spear1340-evb", | ||
182 | NULL, | ||
183 | }; | ||
184 | |||
185 | DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree") | ||
186 | .smp = smp_ops(spear13xx_smp_ops), | ||
187 | .map_io = spear13xx_map_io, | ||
188 | .init_irq = irqchip_init, | ||
189 | .init_time = spear13xx_timer_init, | ||
190 | .init_machine = spear1340_dt_init, | ||
191 | .restart = spear_restart, | ||
192 | .dt_compat = spear1340_dt_board_compat, | ||
193 | MACHINE_END | ||