]>
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> | |
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 | ||
81 | static 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 | ||
97 | static 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 */ | |
104 | static 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 | ||
120 | void 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 | ||
134 | int 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 | ||
144 | int 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 | ||
152 | static 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 */ | |
160 | static 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 | ||
172 | static void __init spear1340_dt_init(void) | |
173 | { | |
174 | of_platform_populate(NULL, of_default_bus_match_table, | |
175 | spear1340_auxdata_lookup, NULL); | |
176 | } | |
177 | ||
178 | static const char * const spear1340_dt_board_compat[] = { | |
179 | "st,spear1340", | |
180 | "st,spear1340-evb", | |
181 | NULL, | |
182 | }; | |
183 | ||
184 | DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree") | |
2d8b21d9 | 185 | .smp = smp_ops(spear13xx_smp_ops), |
e3978dc7 VK |
186 | .map_io = spear13xx_map_io, |
187 | .init_irq = spear13xx_dt_init_irq, | |
188 | .handle_irq = gic_handle_irq, | |
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 |