Commit | Line | Data |
---|---|---|
e3978dc7 VK |
1 | /* |
2 | * arch/arm/mach-spear13xx/spear1340.c | |
3 | * | |
4 | * SPEAr1340 machine source file | |
5 | * | |
6 | * Copyright (C) 2012 ST Microelectronics | |
10d8935f | 7 | * Viresh Kumar <viresh.linux@gmail.com> |
e3978dc7 VK |
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> | |
0529e315 | 21 | #include <linux/irqchip.h> |
e3978dc7 | 22 | #include <asm/mach/arch.h> |
e3978dc7 VK |
23 | #include <mach/generic.h> |
24 | #include <mach/spear.h> | |
25 | ||
17dd1094 AB |
26 | #include "spear13xx-dma.h" |
27 | ||
e3978dc7 VK |
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") | |
2d8b21d9 | 186 | .smp = smp_ops(spear13xx_smp_ops), |
e3978dc7 | 187 | .map_io = spear13xx_map_io, |
0529e315 | 188 | .init_irq = irqchip_init, |
6bb27d73 | 189 | .init_time = spear13xx_timer_init, |
e3978dc7 VK |
190 | .init_machine = spear1340_dt_init, |
191 | .restart = spear_restart, | |
192 | .dt_compat = spear1340_dt_board_compat, | |
193 | MACHINE_END |