summaryrefslogtreecommitdiffstats
path: root/target/linux/kirkwood/patches/003-gating.patch
blob: c858d01a9aa6fa6ac3a7ed5798bda7aef7114838 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
From: Rabeeh Khoury <rabeeh@marvell.com>
Date: Sun, 22 Mar 2009 15:30:32 +0000 (+0200)
Subject: [ARM] Kirkwood: peripherals clock gating for power management
X-Git-Url: http://git.marvell.com/?p=orion.git;a=commitdiff_plain;h=c0c3df02efed0e5dea9aa4d8313e06e1f68f2cb4;hp=039b97666e1335eac517c7d35a0fa1143af689f0

[ARM] Kirkwood: peripherals clock gating for power management

1. Enabling clock gating of unused peripherals
2. PLL and PHY of the units are also disabled (when possible.

Signed-off-by: Rabeeh Khoury <rabeeh@marvell.com>

[ This needs to be revisited to make power handling dynamic and per device.  -- Nico ]

---

--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -786,6 +786,38 @@ static void __init kirkwood_l2_init(void
 #endif
 }
 
+void __init kirkwood_clock_gate(u32 reg)
+{
+	printk(KERN_INFO "Kirkwood: Gating clock using mask 0x%x\n", reg);
+	/* First make sure that the units are accessible */
+	writel(readl(CLOCK_GATING_CTRL) | reg, CLOCK_GATING_CTRL);
+	/* For SATA first shutdown the phy */
+	if (reg & CGC_SATA0) {
+		/* Disable PLL and IVREF */
+		writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
+		/* Disable PHY */
+		writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
+	}
+	if (reg & CGC_SATA1) {
+		/* Disable PLL and IVREF */
+		writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
+		/* Disable PHY */
+		writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
+	}
+	/* For PCI-E first shutdown the phy */
+	if (reg & CGC_PEX0) {
+		writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
+		while (1) {
+			if (readl(PCIE_STATUS) & 0x1)
+				break;
+		}
+		writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
+	}
+	/* Now gate clock the required units */
+	writel(readl(CLOCK_GATING_CTRL) & ~reg, CLOCK_GATING_CTRL);
+	return;
+}
+
 void __init kirkwood_init(void)
 {
 	printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -22,6 +22,7 @@ struct mvsdio_platform_data;
 void kirkwood_map_io(void);
 void kirkwood_init(void);
 void kirkwood_init_irq(void);
+void __init kirkwood_clock_gate(u32 reg);
 
 extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
 void kirkwood_setup_cpu_mbus(void);
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -39,4 +39,20 @@
 #define L2_CONFIG_REG		(BRIDGE_VIRT_BASE | 0x0128)
 #define L2_WRITETHROUGH		0x00000010
 
+#define CLOCK_GATING_CTRL	(BRIDGE_VIRT_BASE | 0x11c)
+#define CGC_GE0			0x1
+#define CGC_PEX0		0x4
+#define CGC_USB0		0x8
+#define CGC_SDIO		0x10
+#define CGC_TSU			0x20
+#define CGC_NAND_SPI		0x80
+#define CGC_XOR0		0x100
+#define CGC_AUDIO		0x200
+#define CGC_SATA0		0x4000
+#define CGC_SATA1		0x8000
+#define CGC_XOR1		0x10000
+#define CGC_CRYPTO		0x20000
+#define CGC_GE1			0x80000
+#define CGC_TDM			0x100000
+
 #endif
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -64,6 +64,8 @@
 #define BRIDGE_VIRT_BASE	(KIRKWOOD_REGS_VIRT_BASE | 0x20000)
 
 #define PCIE_VIRT_BASE		(KIRKWOOD_REGS_VIRT_BASE | 0x40000)
+#define PCIE_LINK_CTRL		(PCIE_VIRT_BASE | 0x70)
+#define PCIE_STATUS		(PCIE_VIRT_BASE | 0x1a04)
 
 #define USB_PHYS_BASE		(KIRKWOOD_REGS_PHYS_BASE | 0x50000)
 
@@ -80,6 +82,11 @@
 #define GE01_PHYS_BASE		(KIRKWOOD_REGS_PHYS_BASE | 0x74000)
 
 #define SATA_PHYS_BASE		(KIRKWOOD_REGS_PHYS_BASE | 0x80000)
+#define SATA_VIRT_BASE		(KIRKWOOD_REGS_VIRT_BASE | 0x80000)
+#define SATA0_IF_CTRL		(SATA_VIRT_BASE | 0x2050)
+#define SATA0_PHY_MODE_2	(SATA_VIRT_BASE | 0x2330)
+#define SATA1_IF_CTRL		(SATA_VIRT_BASE | 0x4050)
+#define SATA1_PHY_MODE_2	(SATA_VIRT_BASE | 0x4330)
 
 #define SDIO_PHYS_BASE		(KIRKWOOD_REGS_PHYS_BASE | 0x90000)
 
--- a/arch/arm/mach-kirkwood/sheevaplug-setup.c
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -19,6 +19,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
 #include <plat/mvsdio.h>
 #include <plat/orion_nand.h>
 #include "common.h"
@@ -122,6 +123,8 @@ static void __init sheevaplug_init(void)
 
 	platform_device_register(&sheevaplug_nand_flash);
 	platform_device_register(&sheevaplug_leds);
+	kirkwood_clock_gate(CGC_PEX0 | CGC_TSU | CGC_AUDIO | CGC_SATA0 |\
+				CGC_SATA1 | CGC_CRYPTO | CGC_GE1 | CGC_TDM);
 }
 
 MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")