summaryrefslogtreecommitdiff
path: root/recipes/linux/linux-kirkwood/0002--ARM-Kirkwood-peripherals-clock-gating-for-power-m.patch
blob: b1c7f7ce00dfe9929286b81771a7711e795f708d (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
From 17589962c1787310e6373478a9fcb7641184cd91 Mon Sep 17 00:00:00 2001
From: Rabeeh Khoury <rabeeh@marvell.com>
Date: Sun, 22 Mar 2009 17:30:32 +0200
Subject: [PATCH] [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 ]
---
 arch/arm/mach-kirkwood/common.c                |   32 ++++++++++++++++++++++++
 arch/arm/mach-kirkwood/common.h                |    1 +
 arch/arm/mach-kirkwood/include/mach/kirkwood.h |   23 +++++++++++++++++
 arch/arm/mach-kirkwood/sheevaplug-setup.c      |    2 +
 4 files changed, 58 insertions(+), 0 deletions(-)

Index: git/arch/arm/mach-kirkwood/common.c
===================================================================
--- git.orig/arch/arm/mach-kirkwood/common.c
+++ git/arch/arm/mach-kirkwood/common.c
@@ -779,6 +779,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",
Index: git/arch/arm/mach-kirkwood/common.h
===================================================================
--- git.orig/arch/arm/mach-kirkwood/common.h
+++ git/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);
Index: git/arch/arm/mach-kirkwood/include/mach/kirkwood.h
===================================================================
--- git.orig/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ git/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -65,6 +65,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)
 
@@ -81,9 +83,30 @@
 #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)
 
+#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
+
 /*
  * Supported devices and revisions.
  */
Index: git/arch/arm/mach-kirkwood/sheevaplug-setup.c
===================================================================
--- git.orig/arch/arm/mach-kirkwood/sheevaplug-setup.c
+++ git/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -122,6 +122,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")