]>
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> | |
e3978dc7 | 19 | #include <linux/of_platform.h> |
e3978dc7 | 20 | #include <asm/mach/arch.h> |
2b9c613c | 21 | #include "generic.h" |
e3978dc7 VK |
22 | #include <mach/spear.h> |
23 | ||
6e8887f6 | 24 | /* FIXME: Move SATA PHY code into a standalone driver */ |
17dd1094 | 25 | |
e3978dc7 VK |
26 | /* Base addresses */ |
27 | #define SPEAR1340_SATA_BASE UL(0xB1000000) | |
e3978dc7 VK |
28 | |
29 | /* Power Management Registers */ | |
30 | #define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100) | |
31 | #define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104) | |
32 | #define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108) | |
33 | ||
34 | #define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318) | |
35 | #define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C) | |
36 | #define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320) | |
37 | ||
38 | /* PCIE - SATA configuration registers */ | |
39 | #define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424) | |
40 | /* PCIE CFG MASks */ | |
41 | #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11) | |
42 | #define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10) | |
43 | #define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9) | |
44 | #define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8) | |
45 | #define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4) | |
46 | #define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3) | |
47 | #define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2) | |
48 | #define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1) | |
49 | #define SPEAR1340_PCIE_SATA_SEL_PCIE (0) | |
50 | #define SPEAR1340_PCIE_SATA_SEL_SATA (1) | |
51 | #define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F | |
52 | #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \ | |
53 | SPEAR1340_PCIE_CFG_AUX_CLK_EN | \ | |
54 | SPEAR1340_PCIE_CFG_CORE_CLK_EN | \ | |
55 | SPEAR1340_PCIE_CFG_POWERUP_RESET | \ | |
56 | SPEAR1340_PCIE_CFG_DEVICE_PRESENT) | |
57 | #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \ | |
58 | SPEAR1340_SATA_CFG_PM_CLK_EN | \ | |
59 | SPEAR1340_SATA_CFG_POWERUP_RESET | \ | |
60 | SPEAR1340_SATA_CFG_RX_CLK_EN | \ | |
61 | SPEAR1340_SATA_CFG_TX_CLK_EN) | |
62 | ||
63 | #define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428) | |
64 | #define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31) | |
65 | #define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27) | |
66 | #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27) | |
67 | #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27) | |
68 | #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0) | |
69 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \ | |
70 | (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ | |
71 | SPEAR1340_MIPHY_CLK_REF_DIV2 | \ | |
72 | SPEAR1340_MIPHY_PLL_RATIO_TOP(60)) | |
73 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \ | |
74 | (SPEAR1340_MIPHY_PLL_RATIO_TOP(120)) | |
75 | #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \ | |
76 | (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ | |
77 | SPEAR1340_MIPHY_PLL_RATIO_TOP(25)) | |
78 | ||
e3978dc7 VK |
79 | /* SATA device registration */ |
80 | static int sata_miphy_init(struct device *dev, void __iomem *addr) | |
81 | { | |
82 | writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG); | |
83 | writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK, | |
84 | SPEAR1340_PCIE_MIPHY_CFG); | |
85 | /* Switch on sata power domain */ | |
86 | writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG); | |
87 | msleep(20); | |
88 | /* Disable PCIE SATA Controller reset */ | |
89 | writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)), | |
90 | SPEAR1340_PERIP1_SW_RST); | |
91 | msleep(20); | |
92 | ||
93 | return 0; | |
94 | } | |
95 | ||
96 | void sata_miphy_exit(struct device *dev) | |
97 | { | |
98 | writel(0, SPEAR1340_PCIE_SATA_CFG); | |
99 | writel(0, SPEAR1340_PCIE_MIPHY_CFG); | |
100 | ||
101 | /* Enable PCIE SATA Controller reset */ | |
102 | writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)), | |
103 | SPEAR1340_PERIP1_SW_RST); | |
104 | msleep(20); | |
105 | /* Switch off sata power domain */ | |
106 | writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG); | |
107 | msleep(20); | |
108 | } | |
109 | ||
110 | int sata_suspend(struct device *dev) | |
111 | { | |
112 | if (dev->power.power_state.event == PM_EVENT_FREEZE) | |
113 | return 0; | |
114 | ||
115 | sata_miphy_exit(dev); | |
116 | ||
117 | return 0; | |
118 | } | |
119 | ||
120 | int sata_resume(struct device *dev) | |
121 | { | |
122 | if (dev->power.power_state.event == PM_EVENT_THAW) | |
123 | return 0; | |
124 | ||
125 | return sata_miphy_init(dev, NULL); | |
126 | } | |
127 | ||
128 | static struct ahci_platform_data sata_pdata = { | |
129 | .init = sata_miphy_init, | |
130 | .exit = sata_miphy_exit, | |
131 | .suspend = sata_suspend, | |
132 | .resume = sata_resume, | |
133 | }; | |
134 | ||
135 | /* Add SPEAr1340 auxdata to pass platform data */ | |
136 | static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = { | |
e3978dc7 VK |
137 | OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL, |
138 | &sata_pdata), | |
e3978dc7 VK |
139 | {} |
140 | }; | |
141 | ||
142 | static void __init spear1340_dt_init(void) | |
143 | { | |
144 | of_platform_populate(NULL, of_default_bus_match_table, | |
145 | spear1340_auxdata_lookup, NULL); | |
146 | } | |
147 | ||
148 | static const char * const spear1340_dt_board_compat[] = { | |
149 | "st,spear1340", | |
150 | "st,spear1340-evb", | |
151 | NULL, | |
152 | }; | |
153 | ||
154 | DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree") | |
2d8b21d9 | 155 | .smp = smp_ops(spear13xx_smp_ops), |
e3978dc7 | 156 | .map_io = spear13xx_map_io, |
6bb27d73 | 157 | .init_time = spear13xx_timer_init, |
e3978dc7 VK |
158 | .init_machine = spear1340_dt_init, |
159 | .restart = spear_restart, | |
160 | .dt_compat = spear1340_dt_board_compat, | |
161 | MACHINE_END |