aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-kirkwood
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2012-04-11 15:07:45 -0400
committerMike Turquette <mturquette@linaro.org>2012-05-08 19:34:04 -0400
commit98d9986cb8bf65f8316b45244fdafc1d12c303be (patch)
tree88e6367c63a01ea8fe2c6480eea6d9d0782fa502 /arch/arm/mach-kirkwood
parente919c71665d2386eec6dc2ecd58d01bae69fc0fd (diff)
ARM: Kirkwood: Replace clock gating
Add a varient of the basic clk-gate code. This variant calls a function before gating the clock off. This function is used to disable the SATA or PCIe PHY. Now that all the drivers prepare and enable there clk as needed, there is no need for the common code to keep track of which clocks need gating on. Let the common clock framework turn off clocks which are not used. Buy using the added clk varient, when the clk framework turns off SATA or PCIe clocks, we also disabled SATA and PCIe PHYs which were not needed. The function kirkwood_pcie_id() can now be called outside of __init code, so remove this property for it, and functions it calls. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Jamie Lentin <jm@lentin.co.uk> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'arch/arm/mach-kirkwood')
-rw-r--r--arch/arm/mach-kirkwood/common.c212
-rw-r--r--arch/arm/mach-kirkwood/pcie.c5
2 files changed, 127 insertions, 90 deletions
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 850ba64109cb..25fb3fd418ef 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -63,27 +63,136 @@ void __init kirkwood_map_io(void)
63 iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); 63 iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
64} 64}
65 65
66/*
67 * Default clock control bits. Any bit _not_ set in this variable
68 * will be cleared from the hardware after platform devices have been
69 * registered. Some reserved bits must be set to 1.
70 */
71unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
72
73
74/***************************************************************************** 66/*****************************************************************************
75 * CLK tree 67 * CLK tree
76 ****************************************************************************/ 68 ****************************************************************************/
69
70static void disable_sata0(void)
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
78static 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
86static 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
95static 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. */
112struct 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
120static 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
131static struct clk_ops clk_gate_fn_ops;
132
133static 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 }
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
77static DEFINE_SPINLOCK(gating_lock); 177static DEFINE_SPINLOCK(gating_lock);
78static struct clk *tclk; 178static struct clk *tclk;
79 179
80static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) 180static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)
81{ 181{
82 return clk_register_gate(NULL, name, "tclk", CLK_IGNORE_UNUSED, 182 return clk_register_gate(NULL, name, "tclk", 0,
83 (void __iomem *)CLOCK_GATING_CTRL, 183 (void __iomem *)CLOCK_GATING_CTRL,
84 bit_idx, 0, &gating_lock); 184 bit_idx, 0, &gating_lock);
85} 185}
86 186
187static 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
87void __init kirkwood_clk_init(void) 196void __init kirkwood_clk_init(void)
88{ 197{
89 struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; 198 struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio;
@@ -95,15 +204,19 @@ void __init kirkwood_clk_init(void)
95 runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); 204 runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT);
96 ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); 205 ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0);
97 ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); 206 ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1);
98 sata0 = kirkwood_register_gate("sata0", CGC_BIT_SATA0); 207 sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0,
99 sata1 = kirkwood_register_gate("sata1", CGC_BIT_SATA1); 208 disable_sata0);
209 sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1,
210 disable_sata1);
100 usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); 211 usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0);
101 sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); 212 sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO);
102 crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); 213 crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO);
103 xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); 214 xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0);
104 xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); 215 xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1);
105 pex0 = kirkwood_register_gate("pex0", CGC_BIT_PEX0); 216 pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0,
106 pex1 = kirkwood_register_gate("pex1", CGC_BIT_PEX1); 217 disable_pcie0);
218 pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1,
219 disable_pcie1);
107 audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); 220 audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO);
108 kirkwood_register_gate("tdm", CGC_BIT_TDM); 221 kirkwood_register_gate("tdm", CGC_BIT_TDM);
109 kirkwood_register_gate("tsu", CGC_BIT_TSU); 222 kirkwood_register_gate("tsu", CGC_BIT_TSU);
@@ -132,7 +245,6 @@ void __init kirkwood_clk_init(void)
132 ****************************************************************************/ 245 ****************************************************************************/
133void __init kirkwood_ehci_init(void) 246void __init kirkwood_ehci_init(void)
134{ 247{
135 kirkwood_clk_ctrl |= CGC_USB0;
136 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);
137} 249}
138 250
@@ -142,8 +254,6 @@ void __init kirkwood_ehci_init(void)
142 ****************************************************************************/ 254 ****************************************************************************/
143void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) 255void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
144{ 256{
145 kirkwood_clk_ctrl |= CGC_GE0;
146
147 orion_ge00_init(eth_data, 257 orion_ge00_init(eth_data,
148 GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, 258 GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
149 IRQ_KIRKWOOD_GE00_ERR); 259 IRQ_KIRKWOOD_GE00_ERR);
@@ -155,9 +265,6 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
155 ****************************************************************************/ 265 ****************************************************************************/
156void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) 266void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
157{ 267{
158
159 kirkwood_clk_ctrl |= CGC_GE1;
160
161 orion_ge01_init(eth_data, 268 orion_ge01_init(eth_data,
162 GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, 269 GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
163 IRQ_KIRKWOOD_GE01_ERR); 270 IRQ_KIRKWOOD_GE01_ERR);
@@ -202,7 +309,6 @@ static struct platform_device kirkwood_nand_flash = {
202void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, 309void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
203 int chip_delay) 310 int chip_delay)
204{ 311{
205 kirkwood_clk_ctrl |= CGC_RUNIT;
206 kirkwood_nand_data.parts = parts; 312 kirkwood_nand_data.parts = parts;
207 kirkwood_nand_data.nr_parts = nr_parts; 313 kirkwood_nand_data.nr_parts = nr_parts;
208 kirkwood_nand_data.chip_delay = chip_delay; 314 kirkwood_nand_data.chip_delay = chip_delay;
@@ -212,7 +318,6 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
212void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, 318void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
213 int (*dev_ready)(struct mtd_info *)) 319 int (*dev_ready)(struct mtd_info *))
214{ 320{
215 kirkwood_clk_ctrl |= CGC_RUNIT;
216 kirkwood_nand_data.parts = parts; 321 kirkwood_nand_data.parts = parts;
217 kirkwood_nand_data.nr_parts = nr_parts; 322 kirkwood_nand_data.nr_parts = nr_parts;
218 kirkwood_nand_data.dev_ready = dev_ready; 323 kirkwood_nand_data.dev_ready = dev_ready;
@@ -233,10 +338,6 @@ static void __init kirkwood_rtc_init(void)
233 ****************************************************************************/ 338 ****************************************************************************/
234void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) 339void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
235{ 340{
236 kirkwood_clk_ctrl |= CGC_SATA0;
237 if (sata_data->n_ports > 1)
238 kirkwood_clk_ctrl |= CGC_SATA1;
239
240 orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); 341 orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
241} 342}
242 343
@@ -279,7 +380,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
279 mvsdio_data->clock = 100000000; 380 mvsdio_data->clock = 100000000;
280 else 381 else
281 mvsdio_data->clock = 200000000; 382 mvsdio_data->clock = 200000000;
282 kirkwood_clk_ctrl |= CGC_SDIO;
283 kirkwood_sdio.dev.platform_data = mvsdio_data; 383 kirkwood_sdio.dev.platform_data = mvsdio_data;
284 platform_device_register(&kirkwood_sdio); 384 platform_device_register(&kirkwood_sdio);
285} 385}
@@ -290,7 +390,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
290 ****************************************************************************/ 390 ****************************************************************************/
291void __init kirkwood_spi_init() 391void __init kirkwood_spi_init()
292{ 392{
293 kirkwood_clk_ctrl |= CGC_RUNIT;
294 orion_spi_init(SPI_PHYS_BASE); 393 orion_spi_init(SPI_PHYS_BASE);
295} 394}
296 395
@@ -329,7 +428,6 @@ void __init kirkwood_uart1_init(void)
329 ****************************************************************************/ 428 ****************************************************************************/
330void __init kirkwood_crypto_init(void) 429void __init kirkwood_crypto_init(void)
331{ 430{
332 kirkwood_clk_ctrl |= CGC_CRYPTO;
333 orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, 431 orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
334 KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); 432 KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
335} 433}
@@ -340,7 +438,6 @@ void __init kirkwood_crypto_init(void)
340 ****************************************************************************/ 438 ****************************************************************************/
341void __init kirkwood_xor0_init(void) 439void __init kirkwood_xor0_init(void)
342{ 440{
343 kirkwood_clk_ctrl |= CGC_XOR0;
344 orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, 441 orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
345 IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); 442 IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
346} 443}
@@ -351,7 +448,6 @@ void __init kirkwood_xor0_init(void)
351 ****************************************************************************/ 448 ****************************************************************************/
352void __init kirkwood_xor1_init(void) 449void __init kirkwood_xor1_init(void)
353{ 450{
354 kirkwood_clk_ctrl |= CGC_XOR1;
355 orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, 451 orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
356 IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); 452 IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
357} 453}
@@ -438,7 +534,6 @@ static struct platform_device kirkwood_pcm_device = {
438 534
439void __init kirkwood_audio_init(void) 535void __init kirkwood_audio_init(void)
440{ 536{
441 kirkwood_clk_ctrl |= CGC_AUDIO;
442 platform_device_register(&kirkwood_i2s_device); 537 platform_device_register(&kirkwood_i2s_device);
443 platform_device_register(&kirkwood_pcm_device); 538 platform_device_register(&kirkwood_pcm_device);
444} 539}
@@ -537,61 +632,6 @@ void __init kirkwood_init(void)
537#endif 632#endif
538} 633}
539 634
540static int __init kirkwood_clock_gate(void)
541{
542 unsigned int curr = readl(CLOCK_GATING_CTRL);
543 u32 dev, rev;
544
545 kirkwood_pcie_id(&dev, &rev);
546 printk(KERN_DEBUG "Gating clock of unused units\n");
547 printk(KERN_DEBUG "before: 0x%08x\n", curr);
548
549 /* Make sure those units are accessible */
550 writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
551
552 /* For SATA: first shutdown the phy */
553 if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
554 /* Disable PLL and IVREF */
555 writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
556 /* Disable PHY */
557 writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
558 }
559 if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
560 /* Disable PLL and IVREF */
561 writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
562 /* Disable PHY */
563 writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
564 }
565
566 /* For PCIe: first shutdown the phy */
567 if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
568 writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
569 while (1)
570 if (readl(PCIE_STATUS) & 0x1)
571 break;
572 writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
573 }
574
575 /* For PCIe 1: first shutdown the phy */
576 if (dev == MV88F6282_DEV_ID) {
577 if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
578 writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
579 while (1)
580 if (readl(PCIE1_STATUS) & 0x1)
581 break;
582 writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
583 }
584 } else /* keep this bit set for devices that don't have PCIe1 */
585 kirkwood_clk_ctrl |= CGC_PEX1;
586
587 /* Now gate clock the required units */
588 writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
589 printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
590
591 return 0;
592}
593late_initcall(kirkwood_clock_gate);
594
595void kirkwood_restart(char mode, const char *cmd) 635void kirkwood_restart(char mode, const char *cmd)
596{ 636{
597 /* 637 /*
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index 881933a0b5eb..f26d6cff8bab 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -44,7 +44,7 @@ void kirkwood_enable_pcie(void)
44 writel(curr | CGC_PEX0, CLOCK_GATING_CTRL); 44 writel(curr | CGC_PEX0, CLOCK_GATING_CTRL);
45} 45}
46 46
47void __init kirkwood_pcie_id(u32 *dev, u32 *rev) 47void kirkwood_pcie_id(u32 *dev, u32 *rev)
48{ 48{
49 kirkwood_enable_pcie(); 49 kirkwood_enable_pcie();
50 *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE); 50 *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
@@ -181,7 +181,6 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp)
181 181
182static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) 182static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
183{ 183{
184 extern unsigned int kirkwood_clk_ctrl;
185 struct pcie_port *pp; 184 struct pcie_port *pp;
186 int index; 185 int index;
187 186
@@ -200,12 +199,10 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
200 199
201 switch (index) { 200 switch (index) {
202 case 0: 201 case 0:
203 kirkwood_clk_ctrl |= CGC_PEX0;
204 kirkwood_enable_pcie_clk("0"); 202 kirkwood_enable_pcie_clk("0");
205 pcie0_ioresources_init(pp); 203 pcie0_ioresources_init(pp);
206 break; 204 break;
207 case 1: 205 case 1:
208 kirkwood_clk_ctrl |= CGC_PEX1;
209 kirkwood_enable_pcie_clk("1"); 206 kirkwood_enable_pcie_clk("1");
210 pcie1_ioresources_init(pp); 207 pcie1_ioresources_init(pp);
211 break; 208 break;