diff options
Diffstat (limited to 'arch/arm/mach-kirkwood/common.c')
-rw-r--r-- | arch/arm/mach-kirkwood/common.c | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index f261cd242643..c9201539ffbd 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -67,6 +67,14 @@ void __init kirkwood_map_io(void) | |||
67 | * CLK tree | 67 | * CLK tree |
68 | ****************************************************************************/ | 68 | ****************************************************************************/ |
69 | 69 | ||
70 | static void enable_sata0(void) | ||
71 | { | ||
72 | /* Enable PLL and IVREF */ | ||
73 | writel(readl(SATA0_PHY_MODE_2) | 0xf, SATA0_PHY_MODE_2); | ||
74 | /* Enable PHY */ | ||
75 | writel(readl(SATA0_IF_CTRL) & ~0x200, SATA0_IF_CTRL); | ||
76 | } | ||
77 | |||
70 | static void disable_sata0(void) | 78 | static void disable_sata0(void) |
71 | { | 79 | { |
72 | /* Disable PLL and IVREF */ | 80 | /* Disable PLL and IVREF */ |
@@ -75,6 +83,14 @@ static void disable_sata0(void) | |||
75 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); | 83 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); |
76 | } | 84 | } |
77 | 85 | ||
86 | static void enable_sata1(void) | ||
87 | { | ||
88 | /* Enable PLL and IVREF */ | ||
89 | writel(readl(SATA1_PHY_MODE_2) | 0xf, SATA1_PHY_MODE_2); | ||
90 | /* Enable PHY */ | ||
91 | writel(readl(SATA1_IF_CTRL) & ~0x200, SATA1_IF_CTRL); | ||
92 | } | ||
93 | |||
78 | static void disable_sata1(void) | 94 | static void disable_sata1(void) |
79 | { | 95 | { |
80 | /* Disable PLL and IVREF */ | 96 | /* Disable PLL and IVREF */ |
@@ -107,23 +123,38 @@ static void disable_pcie1(void) | |||
107 | } | 123 | } |
108 | } | 124 | } |
109 | 125 | ||
110 | /* An extended version of the gated clk. This calls fn() before | 126 | /* An extended version of the gated clk. This calls fn_en()/fn_dis |
111 | * disabling the clock. We use this to turn off PHYs etc. */ | 127 | * before enabling/disabling the clock. We use this to turn on/off |
128 | * PHYs etc. */ | ||
112 | struct clk_gate_fn { | 129 | struct clk_gate_fn { |
113 | struct clk_gate gate; | 130 | struct clk_gate gate; |
114 | void (*fn)(void); | 131 | void (*fn_en)(void); |
132 | void (*fn_dis)(void); | ||
115 | }; | 133 | }; |
116 | 134 | ||
117 | #define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) | 135 | #define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) |
118 | #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) | 136 | #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) |
119 | 137 | ||
138 | static int clk_gate_fn_enable(struct clk_hw *hw) | ||
139 | { | ||
140 | struct clk_gate *gate = to_clk_gate(hw); | ||
141 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); | ||
142 | int ret; | ||
143 | |||
144 | ret = clk_gate_ops.enable(hw); | ||
145 | if (!ret && gate_fn->fn_en) | ||
146 | gate_fn->fn_en(); | ||
147 | |||
148 | return ret; | ||
149 | } | ||
150 | |||
120 | static void clk_gate_fn_disable(struct clk_hw *hw) | 151 | static void clk_gate_fn_disable(struct clk_hw *hw) |
121 | { | 152 | { |
122 | struct clk_gate *gate = to_clk_gate(hw); | 153 | struct clk_gate *gate = to_clk_gate(hw); |
123 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); | 154 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); |
124 | 155 | ||
125 | if (gate_fn->fn) | 156 | if (gate_fn->fn_dis) |
126 | gate_fn->fn(); | 157 | gate_fn->fn_dis(); |
127 | 158 | ||
128 | clk_gate_ops.disable(hw); | 159 | clk_gate_ops.disable(hw); |
129 | } | 160 | } |
@@ -135,7 +166,7 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, | |||
135 | const char *parent_name, unsigned long flags, | 166 | const char *parent_name, unsigned long flags, |
136 | void __iomem *reg, u8 bit_idx, | 167 | void __iomem *reg, u8 bit_idx, |
137 | u8 clk_gate_flags, spinlock_t *lock, | 168 | u8 clk_gate_flags, spinlock_t *lock, |
138 | void (*fn)(void)) | 169 | void (*fn_en)(void), void (*fn_dis)(void)) |
139 | { | 170 | { |
140 | struct clk_gate_fn *gate_fn; | 171 | struct clk_gate_fn *gate_fn; |
141 | struct clk *clk; | 172 | struct clk *clk; |
@@ -159,11 +190,14 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, | |||
159 | gate_fn->gate.flags = clk_gate_flags; | 190 | gate_fn->gate.flags = clk_gate_flags; |
160 | gate_fn->gate.lock = lock; | 191 | gate_fn->gate.lock = lock; |
161 | gate_fn->gate.hw.init = &init; | 192 | gate_fn->gate.hw.init = &init; |
162 | gate_fn->fn = fn; | 193 | gate_fn->fn_en = fn_en; |
194 | gate_fn->fn_dis = fn_dis; | ||
163 | 195 | ||
164 | /* ops is the gate ops, but with our disable function */ | 196 | /* ops is the gate ops, but with our enable/disable functions */ |
165 | if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { | 197 | if (clk_gate_fn_ops.enable != clk_gate_fn_enable || |
198 | clk_gate_fn_ops.disable != clk_gate_fn_disable) { | ||
166 | clk_gate_fn_ops = clk_gate_ops; | 199 | clk_gate_fn_ops = clk_gate_ops; |
200 | clk_gate_fn_ops.enable = clk_gate_fn_enable; | ||
167 | clk_gate_fn_ops.disable = clk_gate_fn_disable; | 201 | clk_gate_fn_ops.disable = clk_gate_fn_disable; |
168 | } | 202 | } |
169 | 203 | ||
@@ -187,11 +221,12 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) | |||
187 | 221 | ||
188 | static struct clk __init *kirkwood_register_gate_fn(const char *name, | 222 | static struct clk __init *kirkwood_register_gate_fn(const char *name, |
189 | u8 bit_idx, | 223 | u8 bit_idx, |
190 | void (*fn)(void)) | 224 | void (*fn_en)(void), |
225 | void (*fn_dis)(void)) | ||
191 | { | 226 | { |
192 | return clk_register_gate_fn(NULL, name, "tclk", 0, | 227 | return clk_register_gate_fn(NULL, name, "tclk", 0, |
193 | (void __iomem *)CLOCK_GATING_CTRL, | 228 | (void __iomem *)CLOCK_GATING_CTRL, |
194 | bit_idx, 0, &gating_lock, fn); | 229 | bit_idx, 0, &gating_lock, fn_en, fn_dis); |
195 | } | 230 | } |
196 | 231 | ||
197 | static struct clk *ge0, *ge1; | 232 | static struct clk *ge0, *ge1; |
@@ -208,18 +243,18 @@ void __init kirkwood_clk_init(void) | |||
208 | ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); | 243 | ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); |
209 | ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); | 244 | ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); |
210 | sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, | 245 | sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, |
211 | disable_sata0); | 246 | enable_sata0, disable_sata0); |
212 | sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, | 247 | sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, |
213 | disable_sata1); | 248 | enable_sata1, disable_sata1); |
214 | usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); | 249 | usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); |
215 | sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); | 250 | sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); |
216 | crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); | 251 | crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); |
217 | xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); | 252 | xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); |
218 | xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); | 253 | xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); |
219 | pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, | 254 | pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, |
220 | disable_pcie0); | 255 | NULL, disable_pcie0); |
221 | pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, | 256 | pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, |
222 | disable_pcie1); | 257 | NULL, disable_pcie1); |
223 | audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); | 258 | audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); |
224 | kirkwood_register_gate("tdm", CGC_BIT_TDM); | 259 | kirkwood_register_gate("tdm", CGC_BIT_TDM); |
225 | kirkwood_register_gate("tsu", CGC_BIT_TSU); | 260 | kirkwood_register_gate("tsu", CGC_BIT_TSU); |
@@ -241,6 +276,11 @@ void __init kirkwood_clk_init(void) | |||
241 | orion_clkdev_add("0", "pcie", pex0); | 276 | orion_clkdev_add("0", "pcie", pex0); |
242 | orion_clkdev_add("1", "pcie", pex1); | 277 | orion_clkdev_add("1", "pcie", pex1); |
243 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); | 278 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); |
279 | |||
280 | /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., | ||
281 | * so should never be gated. | ||
282 | */ | ||
283 | clk_prepare_enable(runit); | ||
244 | } | 284 | } |
245 | 285 | ||
246 | /***************************************************************************** | 286 | /***************************************************************************** |