aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/Kconfig9
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c4
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpllcore.c11
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c24
-rw-r--r--arch/arm/mach-omap2/clock.c38
-rw-r--r--arch/arm/mach-omap2/clock.h2
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c67
-rw-r--r--arch/arm/mach-omap2/cm2xxx.h8
-rw-r--r--arch/arm/mach-omap2/cm3xxx.c22
-rw-r--r--arch/arm/mach-omap2/cm3xxx.h1
-rw-r--r--arch/arm/mach-omap2/control.c54
-rw-r--r--arch/arm/mach-omap2/control.h1
-rw-r--r--arch/arm/mach-omap2/mcbsp.c16
-rw-r--r--arch/arm/mach-omap2/pm24xx.c24
-rw-r--r--arch/arm/mach-omap2/pm34xx.c3
15 files changed, 178 insertions, 106 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b5fb5f7992df..c94624429680 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -8,7 +8,6 @@ config ARCH_OMAP2
8 select CPU_V6 8 select CPU_V6
9 select MULTI_IRQ_HANDLER 9 select MULTI_IRQ_HANDLER
10 select SOC_HAS_OMAP2_SDRC 10 select SOC_HAS_OMAP2_SDRC
11 select COMMON_CLK
12 11
13config ARCH_OMAP3 12config ARCH_OMAP3
14 bool "TI OMAP3" 13 bool "TI OMAP3"
@@ -22,7 +21,6 @@ config ARCH_OMAP3
22 select PM_OPP if PM 21 select PM_OPP if PM
23 select PM_RUNTIME if CPU_IDLE 22 select PM_RUNTIME if CPU_IDLE
24 select SOC_HAS_OMAP2_SDRC 23 select SOC_HAS_OMAP2_SDRC
25 select COMMON_CLK
26 select USB_ARCH_HAS_EHCI if USB_SUPPORT 24 select USB_ARCH_HAS_EHCI if USB_SUPPORT
27 25
28config ARCH_OMAP4 26config ARCH_OMAP4
@@ -45,7 +43,6 @@ config ARCH_OMAP4
45 select PM_OPP if PM 43 select PM_OPP if PM
46 select PM_RUNTIME if CPU_IDLE 44 select PM_RUNTIME if CPU_IDLE
47 select USB_ARCH_HAS_EHCI if USB_SUPPORT 45 select USB_ARCH_HAS_EHCI if USB_SUPPORT
48 select COMMON_CLK
49 select ARM_ERRATA_754322 46 select ARM_ERRATA_754322
50 select ARM_ERRATA_775420 47 select ARM_ERRATA_775420
51 48
@@ -59,7 +56,6 @@ config SOC_OMAP5
59 select HAVE_ARM_SCU if SMP 56 select HAVE_ARM_SCU if SMP
60 select HAVE_ARM_TWD if LOCAL_TIMERS 57 select HAVE_ARM_TWD if LOCAL_TIMERS
61 select HAVE_SMP 58 select HAVE_SMP
62 select COMMON_CLK
63 select HAVE_ARM_ARCH_TIMER 59 select HAVE_ARM_ARCH_TIMER
64 select ARM_ERRATA_798181 if SMP 60 select ARM_ERRATA_798181 if SMP
65 61
@@ -70,7 +66,6 @@ config SOC_AM33XX
70 select ARM_CPU_SUSPEND if PM 66 select ARM_CPU_SUSPEND if PM
71 select CPU_V7 67 select CPU_V7
72 select MULTI_IRQ_HANDLER 68 select MULTI_IRQ_HANDLER
73 select COMMON_CLK
74 69
75config SOC_AM43XX 70config SOC_AM43XX
76 bool "TI AM43x" 71 bool "TI AM43x"
@@ -79,7 +74,6 @@ config SOC_AM43XX
79 select ARCH_OMAP2PLUS 74 select ARCH_OMAP2PLUS
80 select MULTI_IRQ_HANDLER 75 select MULTI_IRQ_HANDLER
81 select ARM_GIC 76 select ARM_GIC
82 select COMMON_CLK
83 select MACH_OMAP_GENERIC 77 select MACH_OMAP_GENERIC
84 78
85config ARCH_OMAP2PLUS 79config ARCH_OMAP2PLUS
@@ -89,11 +83,10 @@ config ARCH_OMAP2PLUS
89 select ARCH_HAS_HOLES_MEMORYMODEL 83 select ARCH_HAS_HOLES_MEMORYMODEL
90 select ARCH_OMAP 84 select ARCH_OMAP
91 select ARCH_REQUIRE_GPIOLIB 85 select ARCH_REQUIRE_GPIOLIB
92 select CLKDEV_LOOKUP
93 select CLKSRC_MMIO 86 select CLKSRC_MMIO
87 select COMMON_CLK
94 select GENERIC_CLOCKEVENTS 88 select GENERIC_CLOCKEVENTS
95 select GENERIC_IRQ_CHIP 89 select GENERIC_IRQ_CHIP
96 select HAVE_CLK
97 select OMAP_DM_TIMER 90 select OMAP_DM_TIMER
98 select PINCTRL 91 select PINCTRL
99 select PROC_DEVICETREE if PROC_FS 92 select PROC_DEVICETREE if PROC_FS
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
index 25b1feed480d..c78e893eba7d 100644
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -52,7 +52,7 @@ static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
52 52
53 apll_mask = EN_APLL_LOCKED << clk->enable_bit; 53 apll_mask = EN_APLL_LOCKED << clk->enable_bit;
54 54
55 r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); 55 r = omap2xxx_cm_get_pll_status();
56 56
57 return ((r & apll_mask) == apll_mask) ? true : false; 57 return ((r & apll_mask) == apll_mask) ? true : false;
58} 58}
@@ -126,7 +126,7 @@ u32 omap2xxx_get_apll_clkin(void)
126{ 126{
127 u32 aplls, srate = 0; 127 u32 aplls, srate = 0;
128 128
129 aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); 129 aplls = omap2xxx_cm_get_pll_config();
130 aplls &= OMAP24XX_APLLS_CLKIN_MASK; 130 aplls &= OMAP24XX_APLLS_CLKIN_MASK;
131 aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT; 131 aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
132 132
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
index d8620105c42a..3ff32543493c 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -60,8 +60,7 @@ unsigned long omap2xxx_clk_get_core_rate(void)
60 60
61 core_clk = omap2_get_dpll_rate(dpll_core_ck); 61 core_clk = omap2_get_dpll_rate(dpll_core_ck);
62 62
63 v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); 63 v = omap2xxx_cm_get_core_clk_src();
64 v &= OMAP24XX_CORE_CLK_SRC_MASK;
65 64
66 if (v == CORE_CLK_SRC_32K) 65 if (v == CORE_CLK_SRC_32K)
67 core_clk = 32768; 66 core_clk = 32768;
@@ -79,8 +78,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
79{ 78{
80 u32 high, low, core_clk_src; 79 u32 high, low, core_clk_src;
81 80
82 core_clk_src = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); 81 core_clk_src = omap2xxx_cm_get_core_clk_src();
83 core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
84 82
85 if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */ 83 if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
86 high = curr_prcm_set->dpll_speed * 2; 84 high = curr_prcm_set->dpll_speed * 2;
@@ -120,8 +118,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
120 const struct dpll_data *dd; 118 const struct dpll_data *dd;
121 119
122 cur_rate = omap2xxx_clk_get_core_rate(); 120 cur_rate = omap2xxx_clk_get_core_rate();
123 mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); 121 mult = omap2xxx_cm_get_core_clk_src();
124 mult &= OMAP24XX_CORE_CLK_SRC_MASK;
125 122
126 if ((rate == (cur_rate / 2)) && (mult == 2)) { 123 if ((rate == (cur_rate / 2)) && (mult == 2)) {
127 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); 124 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
@@ -145,7 +142,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
145 tmpset.cm_clksel1_pll &= ~(dd->mult_mask | 142 tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
146 dd->div1_mask); 143 dd->div1_mask);
147 div = ((curr_prcm_set->xtal_speed / 1000000) - 1); 144 div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
148 tmpset.cm_clksel2_pll = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); 145 tmpset.cm_clksel2_pll = omap2xxx_cm_get_core_pll_config();
149 tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK; 146 tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
150 if (rate > low) { 147 if (rate > low) {
151 tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2; 148 tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index ae2b35e76dc8..b935ed2922d8 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -98,7 +98,7 @@ long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
98int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate, 98int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
99 unsigned long parent_rate) 99 unsigned long parent_rate)
100{ 100{
101 u32 cur_rate, done_rate, bypass = 0, tmp; 101 u32 cur_rate, done_rate, bypass = 0;
102 const struct prcm_config *prcm; 102 const struct prcm_config *prcm;
103 unsigned long found_speed = 0; 103 unsigned long found_speed = 0;
104 unsigned long flags; 104 unsigned long flags;
@@ -141,23 +141,11 @@ int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
141 else 141 else
142 done_rate = CORE_CLK_SRC_DPLL; 142 done_rate = CORE_CLK_SRC_DPLL;
143 143
144 /* MPU divider */ 144 omap2xxx_cm_set_mod_dividers(prcm->cm_clksel_mpu,
145 omap2_cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL); 145 prcm->cm_clksel_dsp,
146 146 prcm->cm_clksel_gfx,
147 /* dsp + iva1 div(2420), iva2.1(2430) */ 147 prcm->cm_clksel1_core,
148 omap2_cm_write_mod_reg(prcm->cm_clksel_dsp, 148 prcm->cm_clksel_mdm);
149 OMAP24XX_DSP_MOD, CM_CLKSEL);
150
151 omap2_cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
152
153 /* Major subsystem dividers */
154 tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
155 omap2_cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
156 CM_CLKSEL1);
157
158 if (cpu_is_omap2430())
159 omap2_cm_write_mod_reg(prcm->cm_clksel_mdm,
160 OMAP2430_MDM_MOD, CM_CLKSEL);
161 149
162 /* x2 to enter omap2xxx_sdrc_init_params() */ 150 /* x2 to enter omap2xxx_sdrc_init_params() */
163 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); 151 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 0c38ca96c840..c7c5d31e9082 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -543,6 +543,44 @@ int omap2_clk_disable_autoidle_all(void)
543} 543}
544 544
545/** 545/**
546 * omap2_clk_deny_idle - disable autoidle on an OMAP clock
547 * @clk: struct clk * to disable autoidle for
548 *
549 * Disable autoidle on an OMAP clock.
550 */
551int omap2_clk_deny_idle(struct clk *clk)
552{
553 struct clk_hw_omap *c;
554
555 if (__clk_get_flags(clk) & CLK_IS_BASIC)
556 return -EINVAL;
557
558 c = to_clk_hw_omap(__clk_get_hw(clk));
559 if (c->ops && c->ops->deny_idle)
560 c->ops->deny_idle(c);
561 return 0;
562}
563
564/**
565 * omap2_clk_allow_idle - enable autoidle on an OMAP clock
566 * @clk: struct clk * to enable autoidle for
567 *
568 * Enable autoidle on an OMAP clock.
569 */
570int omap2_clk_allow_idle(struct clk *clk)
571{
572 struct clk_hw_omap *c;
573
574 if (__clk_get_flags(clk) & CLK_IS_BASIC)
575 return -EINVAL;
576
577 c = to_clk_hw_omap(__clk_get_hw(clk));
578 if (c->ops && c->ops->allow_idle)
579 c->ops->allow_idle(c);
580 return 0;
581}
582
583/**
546 * omap2_clk_enable_init_clocks - prepare & enable a list of clocks 584 * omap2_clk_enable_init_clocks - prepare & enable a list of clocks
547 * @clk_names: ptr to an array of strings of clock names to enable 585 * @clk_names: ptr to an array of strings of clock names to enable
548 * @num_clocks: number of clock names in @clk_names 586 * @num_clocks: number of clock names in @clk_names
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 7aa32cd292f9..82916cc82c92 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -411,6 +411,8 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
411void omap2_init_clk_hw_omap_clocks(struct clk *clk); 411void omap2_init_clk_hw_omap_clocks(struct clk *clk);
412int omap2_clk_enable_autoidle_all(void); 412int omap2_clk_enable_autoidle_all(void);
413int omap2_clk_disable_autoidle_all(void); 413int omap2_clk_disable_autoidle_all(void);
414int omap2_clk_allow_idle(struct clk *clk);
415int omap2_clk_deny_idle(struct clk *clk);
414void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); 416void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
415int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name); 417int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
416void omap2_clk_print_new_rates(const char *hfclkin_ck_name, 418void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index 6774a53a3874..ce25abbcffae 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -327,6 +327,73 @@ struct clkdm_ops omap2_clkdm_operations = {
327 .clkdm_clk_disable = omap2xxx_clkdm_clk_disable, 327 .clkdm_clk_disable = omap2xxx_clkdm_clk_disable,
328}; 328};
329 329
330int omap2xxx_cm_fclks_active(void)
331{
332 u32 f1, f2;
333
334 f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
335 f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
336
337 return (f1 | f2) ? 1 : 0;
338}
339
340int omap2xxx_cm_mpu_retention_allowed(void)
341{
342 u32 l;
343
344 /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
345 l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
346 if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK |
347 OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK |
348 OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK))
349 return 0;
350 /* Check for UART3. */
351 l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
352 if (l & OMAP24XX_EN_UART3_MASK)
353 return 0;
354
355 return 1;
356}
357
358u32 omap2xxx_cm_get_core_clk_src(void)
359{
360 u32 v;
361
362 v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
363 v &= OMAP24XX_CORE_CLK_SRC_MASK;
364
365 return v;
366}
367
368u32 omap2xxx_cm_get_core_pll_config(void)
369{
370 return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
371}
372
373u32 omap2xxx_cm_get_pll_config(void)
374{
375 return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
376}
377
378u32 omap2xxx_cm_get_pll_status(void)
379{
380 return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
381}
382
383void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm)
384{
385 u32 tmp;
386
387 omap2_cm_write_mod_reg(mpu, MPU_MOD, CM_CLKSEL);
388 omap2_cm_write_mod_reg(dsp, OMAP24XX_DSP_MOD, CM_CLKSEL);
389 omap2_cm_write_mod_reg(gfx, GFX_MOD, CM_CLKSEL);
390 tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) &
391 OMAP24XX_CLKSEL_DSS2_MASK;
392 omap2_cm_write_mod_reg(core | tmp, CORE_MOD, CM_CLKSEL1);
393 if (cpu_is_omap2430())
394 omap2_cm_write_mod_reg(mdm, OMAP2430_MDM_MOD, CM_CLKSEL);
395}
396
330/* 397/*
331 * 398 *
332 */ 399 */
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
index 4cbb39b051d2..891d81c3c8f4 100644
--- a/arch/arm/mach-omap2/cm2xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx.h
@@ -62,6 +62,14 @@ extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
62 u8 idlest_shift); 62 u8 idlest_shift);
63extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, 63extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
64 s16 *prcm_inst, u8 *idlest_reg_id); 64 s16 *prcm_inst, u8 *idlest_reg_id);
65extern int omap2xxx_cm_fclks_active(void);
66extern int omap2xxx_cm_mpu_retention_allowed(void);
67extern u32 omap2xxx_cm_get_core_clk_src(void);
68extern u32 omap2xxx_cm_get_core_pll_config(void);
69extern u32 omap2xxx_cm_get_pll_config(void);
70extern u32 omap2xxx_cm_get_pll_status(void);
71extern void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core,
72 u32 mdm);
65 73
66extern int __init omap2xxx_cm_init(void); 74extern int __init omap2xxx_cm_init(void);
67 75
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index 9061c307d915..f6f028867bfe 100644
--- a/arch/arm/mach-omap2/cm3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -636,6 +636,28 @@ void omap3_cm_restore_context(void)
636 OMAP3_CM_CLKOUT_CTRL_OFFSET); 636 OMAP3_CM_CLKOUT_CTRL_OFFSET);
637} 637}
638 638
639void omap3_cm_save_scratchpad_contents(u32 *ptr)
640{
641 *ptr++ = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
642 *ptr++ = omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
643 *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
644
645 /*
646 * As per erratum i671, ROM code does not respect the PER DPLL
647 * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
648 * Then, in anycase, clear these bits to avoid extra latencies.
649 */
650 *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
651 ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
652 *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
653 *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
654 *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
655 *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
656 *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
657 *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
658 *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
659}
660
639/* 661/*
640 * 662 *
641 */ 663 */
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h
index e8e146f4a43f..8224c91b4d7a 100644
--- a/arch/arm/mach-omap2/cm3xxx.h
+++ b/arch/arm/mach-omap2/cm3xxx.h
@@ -83,6 +83,7 @@ extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
83 83
84extern void omap3_cm_save_context(void); 84extern void omap3_cm_save_context(void);
85extern void omap3_cm_restore_context(void); 85extern void omap3_cm_restore_context(void);
86extern void omap3_cm_save_scratchpad_contents(u32 *ptr);
86 87
87extern int __init omap3xxx_cm_init(void); 88extern int __init omap3xxx_cm_init(void);
88 89
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 31e0dfe4a4ea..44bb4d544dcf 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -46,17 +46,7 @@ struct omap3_scratchpad {
46struct omap3_scratchpad_prcm_block { 46struct omap3_scratchpad_prcm_block {
47 u32 prm_clksrc_ctrl; 47 u32 prm_clksrc_ctrl;
48 u32 prm_clksel; 48 u32 prm_clksel;
49 u32 cm_clksel_core; 49 u32 cm_contents[11];
50 u32 cm_clksel_wkup;
51 u32 cm_clken_pll;
52 u32 cm_autoidle_pll;
53 u32 cm_clksel1_pll;
54 u32 cm_clksel2_pll;
55 u32 cm_clksel3_pll;
56 u32 cm_clken_pll_mpu;
57 u32 cm_autoidle_pll_mpu;
58 u32 cm_clksel1_pll_mpu;
59 u32 cm_clksel2_pll_mpu;
60 u32 prcm_block_size; 50 u32 prcm_block_size;
61}; 51};
62 52
@@ -347,34 +337,9 @@ void omap3_save_scratchpad_contents(void)
347 prcm_block_contents.prm_clksel = 337 prcm_block_contents.prm_clksel =
348 omap2_prm_read_mod_reg(OMAP3430_CCR_MOD, 338 omap2_prm_read_mod_reg(OMAP3430_CCR_MOD,
349 OMAP3_PRM_CLKSEL_OFFSET); 339 OMAP3_PRM_CLKSEL_OFFSET);
350 prcm_block_contents.cm_clksel_core = 340
351 omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL); 341 omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents);
352 prcm_block_contents.cm_clksel_wkup = 342
353 omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
354 prcm_block_contents.cm_clken_pll =
355 omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
356 /*
357 * As per erratum i671, ROM code does not respect the PER DPLL
358 * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
359 * Then, in anycase, clear these bits to avoid extra latencies.
360 */
361 prcm_block_contents.cm_autoidle_pll =
362 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
363 ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
364 prcm_block_contents.cm_clksel1_pll =
365 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
366 prcm_block_contents.cm_clksel2_pll =
367 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
368 prcm_block_contents.cm_clksel3_pll =
369 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
370 prcm_block_contents.cm_clken_pll_mpu =
371 omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
372 prcm_block_contents.cm_autoidle_pll_mpu =
373 omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
374 prcm_block_contents.cm_clksel1_pll_mpu =
375 omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
376 prcm_block_contents.cm_clksel2_pll_mpu =
377 omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
378 prcm_block_contents.prcm_block_size = 0x0; 343 prcm_block_contents.prcm_block_size = 0x0;
379 344
380 /* Populate the SDRC block contents */ 345 /* Populate the SDRC block contents */
@@ -604,4 +569,15 @@ int omap3_ctrl_save_padconf(void)
604 return 0; 569 return 0;
605} 570}
606 571
572/**
573 * omap3_ctrl_set_iva_bootmode_idle - sets the IVA2 bootmode to idle
574 *
575 * Sets the bootmode for IVA2 to idle. This is needed by the PM code to
576 * force disable IVA2 so that it does not prevent any low-power states.
577 */
578void omap3_ctrl_set_iva_bootmode_idle(void)
579{
580 omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
581 OMAP343X_CONTROL_IVA2_BOOTMOD);
582}
607#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ 583#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index f7d7c2ef1b40..da054801b114 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -427,6 +427,7 @@ extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr);
427extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode); 427extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode);
428extern void omap3630_ctrl_disable_rta(void); 428extern void omap3630_ctrl_disable_rta(void);
429extern int omap3_ctrl_save_padconf(void); 429extern int omap3_ctrl_save_padconf(void);
430extern void omap3_ctrl_set_iva_bootmode_idle(void);
430extern void omap2_set_globals_control(void __iomem *ctrl, 431extern void omap2_set_globals_control(void __iomem *ctrl,
431 void __iomem *ctrl_pad); 432 void __iomem *ctrl_pad);
432#else 433#else
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 5d8768075dd9..b4ac3af1160c 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -25,6 +25,7 @@
25 25
26#include "soc.h" 26#include "soc.h"
27#include "omap_device.h" 27#include "omap_device.h"
28#include "clock.h"
28 29
29/* 30/*
30 * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. 31 * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
@@ -33,22 +34,18 @@
33#include "cm3xxx.h" 34#include "cm3xxx.h"
34#include "cm-regbits-34xx.h" 35#include "cm-regbits-34xx.h"
35 36
37static struct clk *mcbsp_iclks[5];
38
36static int omap3_enable_st_clock(unsigned int id, bool enable) 39static int omap3_enable_st_clock(unsigned int id, bool enable)
37{ 40{
38 unsigned int w;
39
40 /* 41 /*
41 * Sidetone uses McBSP ICLK - which must not idle when sidetones 42 * Sidetone uses McBSP ICLK - which must not idle when sidetones
42 * are enabled or sidetones start sounding ugly. 43 * are enabled or sidetones start sounding ugly.
43 */ 44 */
44 w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
45 if (enable) 45 if (enable)
46 w &= ~(1 << (id - 2)); 46 return omap2_clk_deny_idle(mcbsp_iclks[id]);
47 else 47 else
48 w |= 1 << (id - 2); 48 return omap2_clk_allow_idle(mcbsp_iclks[id]);
49 omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
50
51 return 0;
52} 49}
53 50
54static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) 51static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
@@ -58,6 +55,7 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
58 struct omap_hwmod *oh_device[2]; 55 struct omap_hwmod *oh_device[2];
59 struct omap_mcbsp_platform_data *pdata = NULL; 56 struct omap_mcbsp_platform_data *pdata = NULL;
60 struct platform_device *pdev; 57 struct platform_device *pdev;
58 char clk_name[11];
61 59
62 sscanf(oh->name, "mcbsp%d", &id); 60 sscanf(oh->name, "mcbsp%d", &id);
63 61
@@ -99,6 +97,8 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
99 oh_device[1] = omap_hwmod_lookup(( 97 oh_device[1] = omap_hwmod_lookup((
100 (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); 98 (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone);
101 pdata->enable_st_clock = omap3_enable_st_clock; 99 pdata->enable_st_clock = omap3_enable_st_clock;
100 sprintf(clk_name, "mcbsp%d_ick", id);
101 mcbsp_iclks[id] = clk_get(NULL, clk_name);
102 count++; 102 count++;
103 } 103 }
104 pdev = omap_device_build_ss(name, id, oh_device, count, pdata, 104 pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index ce956b0a7ba4..8c0759496c8d 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -62,16 +62,6 @@ static struct clockdomain *dsp_clkdm, *mpu_clkdm, *wkup_clkdm, *gfx_clkdm;
62 62
63static struct clk *osc_ck, *emul_ck; 63static struct clk *osc_ck, *emul_ck;
64 64
65static int omap2_fclks_active(void)
66{
67 u32 f1, f2;
68
69 f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
70 f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
71
72 return (f1 | f2) ? 1 : 0;
73}
74
75static int omap2_enter_full_retention(void) 65static int omap2_enter_full_retention(void)
76{ 66{
77 u32 l; 67 u32 l;
@@ -142,17 +132,7 @@ static int sti_console_enabled;
142 132
143static int omap2_allow_mpu_retention(void) 133static int omap2_allow_mpu_retention(void)
144{ 134{
145 u32 l; 135 if (!omap2xxx_cm_mpu_retention_allowed())
146
147 /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
148 l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
149 if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK |
150 OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK |
151 OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK))
152 return 0;
153 /* Check for UART3. */
154 l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
155 if (l & OMAP24XX_EN_UART3_MASK)
156 return 0; 136 return 0;
157 if (sti_console_enabled) 137 if (sti_console_enabled)
158 return 0; 138 return 0;
@@ -188,7 +168,7 @@ static void omap2_enter_mpu_retention(void)
188 168
189static int omap2_can_sleep(void) 169static int omap2_can_sleep(void)
190{ 170{
191 if (omap2_fclks_active()) 171 if (omap2xxx_cm_fclks_active())
192 return 0; 172 return 0;
193 if (__clk_is_enabled(osc_ck)) 173 if (__clk_is_enabled(osc_ck))
194 return 0; 174 return 0;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 5a2d8034c8de..93b80e5da8d4 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -430,8 +430,7 @@ static void __init omap3_iva_idle(void)
430 OMAP3430_IVA2_MOD, CM_FCLKEN); 430 OMAP3430_IVA2_MOD, CM_FCLKEN);
431 431
432 /* Set IVA2 boot mode to 'idle' */ 432 /* Set IVA2 boot mode to 'idle' */
433 omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, 433 omap3_ctrl_set_iva_bootmode_idle();
434 OMAP343X_CONTROL_IVA2_BOOTMOD);
435 434
436 /* Un-reset IVA2 */ 435 /* Un-reset IVA2 */
437 omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); 436 omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);