aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/Makefile3
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpll.c63
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c2
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c2
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.c27
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h3
-rw-r--r--arch/arm/mach-omap2/pm24xx.c12
8 files changed, 105 insertions, 8 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 89274a9f0357..ae44645551c2 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -115,7 +115,8 @@ obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \
115 clkt2xxx_sys.o \ 115 clkt2xxx_sys.o \
116 clkt2xxx_dpllcore.o \ 116 clkt2xxx_dpllcore.o \
117 clkt2xxx_virt_prcm_set.o \ 117 clkt2xxx_virt_prcm_set.o \
118 clkt2xxx_apll.o clkt2xxx_osc.o 118 clkt2xxx_apll.o clkt2xxx_osc.o \
119 clkt2xxx_dpll.o
119obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o 120obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
120obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o 121obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
121obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \ 122obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c
new file mode 100644
index 000000000000..1502a7bc20bb
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c
@@ -0,0 +1,63 @@
1/*
2 * OMAP2-specific DPLL control functions
3 *
4 * Copyright (C) 2011 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/clk.h>
15#include <linux/io.h>
16
17#include <plat/clock.h>
18
19#include "clock.h"
20#include "cm2xxx_3xxx.h"
21#include "cm-regbits-24xx.h"
22
23/* Private functions */
24
25/**
26 * _allow_idle - enable DPLL autoidle bits
27 * @clk: struct clk * of the DPLL to operate on
28 *
29 * Enable DPLL automatic idle control. The DPLL will enter low-power
30 * stop when its downstream clocks are gated. No return value.
31 * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
32 * instead. Add some mechanism to optionally enter this mode.
33 */
34static void _allow_idle(struct clk *clk)
35{
36 if (!clk || !clk->dpll_data)
37 return;
38
39 omap2xxx_cm_set_dpll_auto_low_power_stop();
40}
41
42/**
43 * _deny_idle - prevent DPLL from automatically idling
44 * @clk: struct clk * of the DPLL to operate on
45 *
46 * Disable DPLL automatic idle control. No return value.
47 */
48static void _deny_idle(struct clk *clk)
49{
50 if (!clk || !clk->dpll_data)
51 return;
52
53 omap2xxx_cm_set_dpll_disable_autoidle();
54}
55
56
57/* Public data */
58
59const struct clkops clkops_omap2xxx_dpll_ops = {
60 .allow_idle = _allow_idle,
61 .deny_idle = _deny_idle,
62};
63
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 0725a6ad8b46..9972d892a4af 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -148,6 +148,7 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
148#define omap2_clk_exit_cpufreq_table 0 148#define omap2_clk_exit_cpufreq_table 0
149#endif 149#endif
150 150
151extern const struct clkops clkops_omap2xxx_dpll_ops;
151extern const struct clkops clkops_omap3_noncore_dpll_ops; 152extern const struct clkops clkops_omap3_noncore_dpll_ops;
152extern const struct clkops clkops_omap3_core_dpll_ops; 153extern const struct clkops clkops_omap3_core_dpll_ops;
153extern const struct clkops clkops_omap4_dpllmx_ops; 154extern const struct clkops clkops_omap4_dpllmx_ops;
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index ee73e14ac3c8..30fbcbd0ed81 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -125,7 +125,7 @@ static struct dpll_data dpll_dd = {
125 */ 125 */
126static struct clk dpll_ck = { 126static struct clk dpll_ck = {
127 .name = "dpll_ck", 127 .name = "dpll_ck",
128 .ops = &clkops_null, 128 .ops = &clkops_omap2xxx_dpll_ops,
129 .parent = &sys_ck, /* Can be func_32k also */ 129 .parent = &sys_ck, /* Can be func_32k also */
130 .dpll_data = &dpll_dd, 130 .dpll_data = &dpll_dd,
131 .clkdm_name = "wkup_clkdm", 131 .clkdm_name = "wkup_clkdm",
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index a1298e55d915..1ff150a0f304 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -125,7 +125,7 @@ static struct dpll_data dpll_dd = {
125 */ 125 */
126static struct clk dpll_ck = { 126static struct clk dpll_ck = {
127 .name = "dpll_ck", 127 .name = "dpll_ck",
128 .ops = &clkops_null, 128 .ops = &clkops_omap2xxx_dpll_ops,
129 .parent = &sys_ck, /* Can be func_32k also */ 129 .parent = &sys_ck, /* Can be func_32k also */
130 .dpll_data = &dpll_dd, 130 .dpll_data = &dpll_dd,
131 .clkdm_name = "wkup_clkdm", 131 .clkdm_name = "wkup_clkdm",
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
index 96954aa48671..6b0c7c85ef53 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -25,6 +25,10 @@
25#include "cm-regbits-24xx.h" 25#include "cm-regbits-24xx.h"
26#include "cm-regbits-34xx.h" 26#include "cm-regbits-34xx.h"
27 27
28/* CM_AUTOIDLE_PLL.AUTO_* bit values */
29#define DPLL_AUTOIDLE_DISABLE 0x0
30#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
31
28static const u8 cm_idlest_offs[] = { 32static const u8 cm_idlest_offs[] = {
29 CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 33 CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
30}; 34};
@@ -125,6 +129,29 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
125 _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask); 129 _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
126} 130}
127 131
132/*
133 * DPLL autoidle control
134 */
135
136static void _omap2xxx_set_dpll_autoidle(u8 m)
137{
138 u32 v;
139
140 v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
141 v &= ~OMAP24XX_AUTO_DPLL_MASK;
142 v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
143 omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
144}
145
146void omap2xxx_cm_set_dpll_disable_autoidle(void)
147{
148 _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
149}
150
151void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
152{
153 _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
154}
128 155
129/* 156/*
130 * 157 *
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
index 5e9ea5bd60b9..5f4df1ceafad 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -122,6 +122,9 @@ extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
122extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask); 122extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
123extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask); 123extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
124 124
125extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
126extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
127
125#endif 128#endif
126 129
127/* CM register bits shared between 24XX and 3430 */ 130/* CM register bits shared between 24XX and 3430 */
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index e983c8301f55..297bb21061b8 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -378,6 +378,7 @@ static void __init prcm_setup_regs(void)
378{ 378{
379 int i, num_mem_banks; 379 int i, num_mem_banks;
380 struct powerdomain *pwrdm; 380 struct powerdomain *pwrdm;
381 u32 v;
381 382
382 /* Enable autoidle */ 383 /* Enable autoidle */
383 omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD, 384 omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD,
@@ -468,11 +469,12 @@ static void __init prcm_setup_regs(void)
468 omap2_cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD, 469 omap2_cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD,
469 CM_AUTOIDLE); 470 CM_AUTOIDLE);
470 471
471 /* Put DPLL and both APLLs into autoidle mode */ 472 /* Put both APLLs into autoidle mode */
472 omap2_cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) | 473 v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
473 (0x03 << OMAP24XX_AUTO_96M_SHIFT) | 474 v &= ~(OMAP24XX_AUTO_96M_MASK | OMAP24XX_AUTO_54M_SHIFT);
474 (0x03 << OMAP24XX_AUTO_54M_SHIFT), 475 v |= (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
475 PLL_MOD, CM_AUTOIDLE); 476 (0x03 << OMAP24XX_AUTO_54M_SHIFT);
477 omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
476 478
477 omap2_cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK | 479 omap2_cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK |
478 OMAP24XX_AUTO_WDT1_MASK | 480 OMAP24XX_AUTO_WDT1_MASK |