diff options
Diffstat (limited to 'arch/arm/mach-kirkwood/common.c')
-rw-r--r-- | arch/arm/mach-kirkwood/common.c | 286 |
1 files changed, 187 insertions, 99 deletions
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 3ad037385a5e..25fb3fd418ef 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -15,7 +15,8 @@ | |||
15 | #include <linux/ata_platform.h> | 15 | #include <linux/ata_platform.h> |
16 | #include <linux/mtd/nand.h> | 16 | #include <linux/mtd/nand.h> |
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/of.h> | 18 | #include <linux/clk-provider.h> |
19 | #include <linux/spinlock.h> | ||
19 | #include <net/dsa.h> | 20 | #include <net/dsa.h> |
20 | #include <asm/page.h> | 21 | #include <asm/page.h> |
21 | #include <asm/timex.h> | 22 | #include <asm/timex.h> |
@@ -32,6 +33,7 @@ | |||
32 | #include <plat/common.h> | 33 | #include <plat/common.h> |
33 | #include <plat/time.h> | 34 | #include <plat/time.h> |
34 | #include <plat/addr-map.h> | 35 | #include <plat/addr-map.h> |
36 | #include <plat/mv_xor.h> | ||
35 | #include "common.h" | 37 | #include "common.h" |
36 | 38 | ||
37 | /***************************************************************************** | 39 | /***************************************************************************** |
@@ -61,20 +63,188 @@ void __init kirkwood_map_io(void) | |||
61 | iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); | 63 | iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); |
62 | } | 64 | } |
63 | 65 | ||
64 | /* | 66 | /***************************************************************************** |
65 | * Default clock control bits. Any bit _not_ set in this variable | 67 | * CLK tree |
66 | * will be cleared from the hardware after platform devices have been | 68 | ****************************************************************************/ |
67 | * registered. Some reserved bits must be set to 1. | 69 | |
68 | */ | 70 | static void disable_sata0(void) |
69 | unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED; | 71 | { |
72 | /* Disable PLL and IVREF */ | ||
73 | writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); | ||
74 | /* Disable PHY */ | ||
75 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); | ||
76 | } | ||
77 | |||
78 | static void disable_sata1(void) | ||
79 | { | ||
80 | /* Disable PLL and IVREF */ | ||
81 | writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); | ||
82 | /* Disable PHY */ | ||
83 | writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); | ||
84 | } | ||
85 | |||
86 | static void disable_pcie0(void) | ||
87 | { | ||
88 | writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); | ||
89 | while (1) | ||
90 | if (readl(PCIE_STATUS) & 0x1) | ||
91 | break; | ||
92 | writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); | ||
93 | } | ||
94 | |||
95 | static void disable_pcie1(void) | ||
96 | { | ||
97 | u32 dev, rev; | ||
98 | |||
99 | kirkwood_pcie_id(&dev, &rev); | ||
100 | |||
101 | if (dev == MV88F6282_DEV_ID) { | ||
102 | writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); | ||
103 | while (1) | ||
104 | if (readl(PCIE1_STATUS) & 0x1) | ||
105 | break; | ||
106 | writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /* An extended version of the gated clk. This calls fn() before | ||
111 | * disabling the clock. We use this to turn off PHYs etc. */ | ||
112 | struct clk_gate_fn { | ||
113 | struct clk_gate gate; | ||
114 | void (*fn)(void); | ||
115 | }; | ||
116 | |||
117 | #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) | ||
119 | |||
120 | static void clk_gate_fn_disable(struct clk_hw *hw) | ||
121 | { | ||
122 | struct clk_gate *gate = to_clk_gate(hw); | ||
123 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); | ||
124 | |||
125 | if (gate_fn->fn) | ||
126 | gate_fn->fn(); | ||
127 | |||
128 | clk_gate_ops.disable(hw); | ||
129 | } | ||
130 | |||
131 | static struct clk_ops clk_gate_fn_ops; | ||
132 | |||
133 | static struct clk __init *clk_register_gate_fn(struct device *dev, | ||
134 | const char *name, | ||
135 | const char *parent_name, unsigned long flags, | ||
136 | void __iomem *reg, u8 bit_idx, | ||
137 | u8 clk_gate_flags, spinlock_t *lock, | ||
138 | void (*fn)(void)) | ||
139 | { | ||
140 | struct clk_gate_fn *gate_fn; | ||
141 | struct clk *clk; | ||
142 | struct clk_init_data init; | ||
143 | |||
144 | gate_fn = kzalloc(sizeof(struct clk_gate_fn), GFP_KERNEL); | ||
145 | if (!gate_fn) { | ||
146 | pr_err("%s: could not allocate gated clk\n", __func__); | ||
147 | return ERR_PTR(-ENOMEM); | ||
148 | } | ||
149 | |||
150 | init.name = name; | ||
151 | init.ops = &clk_gate_fn_ops; | ||
152 | init.flags = flags; | ||
153 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
154 | init.num_parents = (parent_name ? 1 : 0); | ||
155 | |||
156 | /* struct clk_gate assignments */ | ||
157 | gate_fn->gate.reg = reg; | ||
158 | gate_fn->gate.bit_idx = bit_idx; | ||
159 | gate_fn->gate.flags = clk_gate_flags; | ||
160 | gate_fn->gate.lock = lock; | ||
161 | gate_fn->gate.hw.init = &init; | ||
162 | |||
163 | /* ops is the gate ops, but with our disable function */ | ||
164 | if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { | ||
165 | clk_gate_fn_ops = clk_gate_ops; | ||
166 | clk_gate_fn_ops.disable = clk_gate_fn_disable; | ||
167 | } | ||
70 | 168 | ||
169 | clk = clk_register(dev, &gate_fn->gate.hw); | ||
170 | |||
171 | if (IS_ERR(clk)) | ||
172 | kfree(gate_fn); | ||
173 | |||
174 | return clk; | ||
175 | } | ||
176 | |||
177 | static DEFINE_SPINLOCK(gating_lock); | ||
178 | static struct clk *tclk; | ||
179 | |||
180 | static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) | ||
181 | { | ||
182 | return clk_register_gate(NULL, name, "tclk", 0, | ||
183 | (void __iomem *)CLOCK_GATING_CTRL, | ||
184 | bit_idx, 0, &gating_lock); | ||
185 | } | ||
186 | |||
187 | static struct clk __init *kirkwood_register_gate_fn(const char *name, | ||
188 | u8 bit_idx, | ||
189 | void (*fn)(void)) | ||
190 | { | ||
191 | return clk_register_gate_fn(NULL, name, "tclk", 0, | ||
192 | (void __iomem *)CLOCK_GATING_CTRL, | ||
193 | bit_idx, 0, &gating_lock, fn); | ||
194 | } | ||
195 | |||
196 | void __init kirkwood_clk_init(void) | ||
197 | { | ||
198 | struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; | ||
199 | struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; | ||
200 | |||
201 | tclk = clk_register_fixed_rate(NULL, "tclk", NULL, | ||
202 | CLK_IS_ROOT, kirkwood_tclk); | ||
203 | |||
204 | runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); | ||
205 | ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); | ||
206 | ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); | ||
207 | sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, | ||
208 | disable_sata0); | ||
209 | sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, | ||
210 | disable_sata1); | ||
211 | usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); | ||
212 | sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); | ||
213 | crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); | ||
214 | xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); | ||
215 | xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); | ||
216 | pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, | ||
217 | disable_pcie0); | ||
218 | pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, | ||
219 | disable_pcie1); | ||
220 | audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); | ||
221 | kirkwood_register_gate("tdm", CGC_BIT_TDM); | ||
222 | kirkwood_register_gate("tsu", CGC_BIT_TSU); | ||
223 | |||
224 | /* clkdev entries, mapping clks to devices */ | ||
225 | orion_clkdev_add(NULL, "orion_spi.0", runit); | ||
226 | orion_clkdev_add(NULL, "orion_spi.1", runit); | ||
227 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); | ||
228 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); | ||
229 | orion_clkdev_add(NULL, "orion_wdt", tclk); | ||
230 | orion_clkdev_add("0", "sata_mv.0", sata0); | ||
231 | orion_clkdev_add("1", "sata_mv.0", sata1); | ||
232 | orion_clkdev_add(NULL, "orion-ehci.0", usb0); | ||
233 | orion_clkdev_add(NULL, "orion_nand", runit); | ||
234 | orion_clkdev_add(NULL, "mvsdio", sdio); | ||
235 | orion_clkdev_add(NULL, "mv_crypto", crypto); | ||
236 | orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0); | ||
237 | orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1); | ||
238 | orion_clkdev_add("0", "pcie", pex0); | ||
239 | orion_clkdev_add("1", "pcie", pex1); | ||
240 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); | ||
241 | } | ||
71 | 242 | ||
72 | /***************************************************************************** | 243 | /***************************************************************************** |
73 | * EHCI0 | 244 | * EHCI0 |
74 | ****************************************************************************/ | 245 | ****************************************************************************/ |
75 | void __init kirkwood_ehci_init(void) | 246 | void __init kirkwood_ehci_init(void) |
76 | { | 247 | { |
77 | kirkwood_clk_ctrl |= CGC_USB0; | ||
78 | orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); | 248 | orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); |
79 | } | 249 | } |
80 | 250 | ||
@@ -84,11 +254,9 @@ void __init kirkwood_ehci_init(void) | |||
84 | ****************************************************************************/ | 254 | ****************************************************************************/ |
85 | void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) | 255 | void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) |
86 | { | 256 | { |
87 | kirkwood_clk_ctrl |= CGC_GE0; | ||
88 | |||
89 | orion_ge00_init(eth_data, | 257 | orion_ge00_init(eth_data, |
90 | GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, | 258 | GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, |
91 | IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk); | 259 | IRQ_KIRKWOOD_GE00_ERR); |
92 | } | 260 | } |
93 | 261 | ||
94 | 262 | ||
@@ -97,12 +265,9 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) | |||
97 | ****************************************************************************/ | 265 | ****************************************************************************/ |
98 | void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) | 266 | void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) |
99 | { | 267 | { |
100 | |||
101 | kirkwood_clk_ctrl |= CGC_GE1; | ||
102 | |||
103 | orion_ge01_init(eth_data, | 268 | orion_ge01_init(eth_data, |
104 | GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, | 269 | GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, |
105 | IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk); | 270 | IRQ_KIRKWOOD_GE01_ERR); |
106 | } | 271 | } |
107 | 272 | ||
108 | 273 | ||
@@ -144,7 +309,6 @@ static struct platform_device kirkwood_nand_flash = { | |||
144 | void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, | 309 | void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, |
145 | int chip_delay) | 310 | int chip_delay) |
146 | { | 311 | { |
147 | kirkwood_clk_ctrl |= CGC_RUNIT; | ||
148 | kirkwood_nand_data.parts = parts; | 312 | kirkwood_nand_data.parts = parts; |
149 | kirkwood_nand_data.nr_parts = nr_parts; | 313 | kirkwood_nand_data.nr_parts = nr_parts; |
150 | kirkwood_nand_data.chip_delay = chip_delay; | 314 | kirkwood_nand_data.chip_delay = chip_delay; |
@@ -154,7 +318,6 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, | |||
154 | void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, | 318 | void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, |
155 | int (*dev_ready)(struct mtd_info *)) | 319 | int (*dev_ready)(struct mtd_info *)) |
156 | { | 320 | { |
157 | kirkwood_clk_ctrl |= CGC_RUNIT; | ||
158 | kirkwood_nand_data.parts = parts; | 321 | kirkwood_nand_data.parts = parts; |
159 | kirkwood_nand_data.nr_parts = nr_parts; | 322 | kirkwood_nand_data.nr_parts = nr_parts; |
160 | kirkwood_nand_data.dev_ready = dev_ready; | 323 | kirkwood_nand_data.dev_ready = dev_ready; |
@@ -175,10 +338,6 @@ static void __init kirkwood_rtc_init(void) | |||
175 | ****************************************************************************/ | 338 | ****************************************************************************/ |
176 | void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) | 339 | void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) |
177 | { | 340 | { |
178 | kirkwood_clk_ctrl |= CGC_SATA0; | ||
179 | if (sata_data->n_ports > 1) | ||
180 | kirkwood_clk_ctrl |= CGC_SATA1; | ||
181 | |||
182 | orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); | 341 | orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); |
183 | } | 342 | } |
184 | 343 | ||
@@ -221,7 +380,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) | |||
221 | mvsdio_data->clock = 100000000; | 380 | mvsdio_data->clock = 100000000; |
222 | else | 381 | else |
223 | mvsdio_data->clock = 200000000; | 382 | mvsdio_data->clock = 200000000; |
224 | kirkwood_clk_ctrl |= CGC_SDIO; | ||
225 | kirkwood_sdio.dev.platform_data = mvsdio_data; | 383 | kirkwood_sdio.dev.platform_data = mvsdio_data; |
226 | platform_device_register(&kirkwood_sdio); | 384 | platform_device_register(&kirkwood_sdio); |
227 | } | 385 | } |
@@ -232,8 +390,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) | |||
232 | ****************************************************************************/ | 390 | ****************************************************************************/ |
233 | void __init kirkwood_spi_init() | 391 | void __init kirkwood_spi_init() |
234 | { | 392 | { |
235 | kirkwood_clk_ctrl |= CGC_RUNIT; | 393 | orion_spi_init(SPI_PHYS_BASE); |
236 | orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk); | ||
237 | } | 394 | } |
238 | 395 | ||
239 | 396 | ||
@@ -253,7 +410,7 @@ void __init kirkwood_i2c_init(void) | |||
253 | void __init kirkwood_uart0_init(void) | 410 | void __init kirkwood_uart0_init(void) |
254 | { | 411 | { |
255 | orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, | 412 | orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, |
256 | IRQ_KIRKWOOD_UART_0, kirkwood_tclk); | 413 | IRQ_KIRKWOOD_UART_0, tclk); |
257 | } | 414 | } |
258 | 415 | ||
259 | 416 | ||
@@ -263,7 +420,7 @@ void __init kirkwood_uart0_init(void) | |||
263 | void __init kirkwood_uart1_init(void) | 420 | void __init kirkwood_uart1_init(void) |
264 | { | 421 | { |
265 | orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, | 422 | orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, |
266 | IRQ_KIRKWOOD_UART_1, kirkwood_tclk); | 423 | IRQ_KIRKWOOD_UART_1, tclk); |
267 | } | 424 | } |
268 | 425 | ||
269 | /***************************************************************************** | 426 | /***************************************************************************** |
@@ -271,7 +428,6 @@ void __init kirkwood_uart1_init(void) | |||
271 | ****************************************************************************/ | 428 | ****************************************************************************/ |
272 | void __init kirkwood_crypto_init(void) | 429 | void __init kirkwood_crypto_init(void) |
273 | { | 430 | { |
274 | kirkwood_clk_ctrl |= CGC_CRYPTO; | ||
275 | orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, | 431 | orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, |
276 | KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); | 432 | KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); |
277 | } | 433 | } |
@@ -282,8 +438,6 @@ void __init kirkwood_crypto_init(void) | |||
282 | ****************************************************************************/ | 438 | ****************************************************************************/ |
283 | void __init kirkwood_xor0_init(void) | 439 | void __init kirkwood_xor0_init(void) |
284 | { | 440 | { |
285 | kirkwood_clk_ctrl |= CGC_XOR0; | ||
286 | |||
287 | orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, | 441 | orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, |
288 | IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); | 442 | IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); |
289 | } | 443 | } |
@@ -294,8 +448,6 @@ void __init kirkwood_xor0_init(void) | |||
294 | ****************************************************************************/ | 448 | ****************************************************************************/ |
295 | void __init kirkwood_xor1_init(void) | 449 | void __init kirkwood_xor1_init(void) |
296 | { | 450 | { |
297 | kirkwood_clk_ctrl |= CGC_XOR1; | ||
298 | |||
299 | orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, | 451 | orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, |
300 | IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); | 452 | IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); |
301 | } | 453 | } |
@@ -306,7 +458,7 @@ void __init kirkwood_xor1_init(void) | |||
306 | ****************************************************************************/ | 458 | ****************************************************************************/ |
307 | void __init kirkwood_wdt_init(void) | 459 | void __init kirkwood_wdt_init(void) |
308 | { | 460 | { |
309 | orion_wdt_init(kirkwood_tclk); | 461 | orion_wdt_init(); |
310 | } | 462 | } |
311 | 463 | ||
312 | 464 | ||
@@ -382,7 +534,6 @@ static struct platform_device kirkwood_pcm_device = { | |||
382 | 534 | ||
383 | void __init kirkwood_audio_init(void) | 535 | void __init kirkwood_audio_init(void) |
384 | { | 536 | { |
385 | kirkwood_clk_ctrl |= CGC_AUDIO; | ||
386 | platform_device_register(&kirkwood_i2s_device); | 537 | platform_device_register(&kirkwood_i2s_device); |
387 | platform_device_register(&kirkwood_pcm_device); | 538 | platform_device_register(&kirkwood_pcm_device); |
388 | } | 539 | } |
@@ -466,6 +617,9 @@ void __init kirkwood_init(void) | |||
466 | kirkwood_l2_init(); | 617 | kirkwood_l2_init(); |
467 | #endif | 618 | #endif |
468 | 619 | ||
620 | /* Setup root of clk tree */ | ||
621 | kirkwood_clk_init(); | ||
622 | |||
469 | /* internal devices that every board has */ | 623 | /* internal devices that every board has */ |
470 | kirkwood_rtc_init(); | 624 | kirkwood_rtc_init(); |
471 | kirkwood_wdt_init(); | 625 | kirkwood_wdt_init(); |
@@ -478,72 +632,6 @@ void __init kirkwood_init(void) | |||
478 | #endif | 632 | #endif |
479 | } | 633 | } |
480 | 634 | ||
481 | static int __init kirkwood_clock_gate(void) | ||
482 | { | ||
483 | unsigned int curr = readl(CLOCK_GATING_CTRL); | ||
484 | u32 dev, rev; | ||
485 | |||
486 | #ifdef CONFIG_OF | ||
487 | struct device_node *np; | ||
488 | #endif | ||
489 | kirkwood_pcie_id(&dev, &rev); | ||
490 | printk(KERN_DEBUG "Gating clock of unused units\n"); | ||
491 | printk(KERN_DEBUG "before: 0x%08x\n", curr); | ||
492 | |||
493 | /* Make sure those units are accessible */ | ||
494 | writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL); | ||
495 | |||
496 | #ifdef CONFIG_OF | ||
497 | np = of_find_compatible_node(NULL, NULL, "mrvl,orion-nand"); | ||
498 | if (np && of_device_is_available(np)) { | ||
499 | kirkwood_clk_ctrl |= CGC_RUNIT; | ||
500 | of_node_put(np); | ||
501 | } | ||
502 | #endif | ||
503 | |||
504 | /* For SATA: first shutdown the phy */ | ||
505 | if (!(kirkwood_clk_ctrl & CGC_SATA0)) { | ||
506 | /* Disable PLL and IVREF */ | ||
507 | writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); | ||
508 | /* Disable PHY */ | ||
509 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); | ||
510 | } | ||
511 | if (!(kirkwood_clk_ctrl & CGC_SATA1)) { | ||
512 | /* Disable PLL and IVREF */ | ||
513 | writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); | ||
514 | /* Disable PHY */ | ||
515 | writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); | ||
516 | } | ||
517 | |||
518 | /* For PCIe: first shutdown the phy */ | ||
519 | if (!(kirkwood_clk_ctrl & CGC_PEX0)) { | ||
520 | writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); | ||
521 | while (1) | ||
522 | if (readl(PCIE_STATUS) & 0x1) | ||
523 | break; | ||
524 | writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); | ||
525 | } | ||
526 | |||
527 | /* For PCIe 1: first shutdown the phy */ | ||
528 | if (dev == MV88F6282_DEV_ID) { | ||
529 | if (!(kirkwood_clk_ctrl & CGC_PEX1)) { | ||
530 | writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); | ||
531 | while (1) | ||
532 | if (readl(PCIE1_STATUS) & 0x1) | ||
533 | break; | ||
534 | writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); | ||
535 | } | ||
536 | } else /* keep this bit set for devices that don't have PCIe1 */ | ||
537 | kirkwood_clk_ctrl |= CGC_PEX1; | ||
538 | |||
539 | /* Now gate clock the required units */ | ||
540 | writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL); | ||
541 | printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL)); | ||
542 | |||
543 | return 0; | ||
544 | } | ||
545 | late_initcall(kirkwood_clock_gate); | ||
546 | |||
547 | void kirkwood_restart(char mode, const char *cmd) | 635 | void kirkwood_restart(char mode, const char *cmd) |
548 | { | 636 | { |
549 | /* | 637 | /* |