aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2012-10-29 22:56:29 -0400
committerPaul Walmsley <paul@pwsan.com>2012-11-08 14:33:08 -0500
commitc4ceedcb18cf7a06059482a3a1828b9aad9f78cf (patch)
treee9b5e9bb75aa84ea70159fa68e103a69518a1eee /arch/arm/mach-omap2/clock.c
parentb6ffa05091978c68e94d2802200f2aaa06a598d9 (diff)
ARM: OMAP2+: CM/clock: convert _omap2_module_wait_ready() to use SoC-independent CM functions
Convert the OMAP clock code's _omap2_module_wait_ready() to use SoC-independent CM functions that are provided by the CM code, rather than using a deprecated function from mach-omap2/prcm.c. This facilitates the future conversion of the CM code to a driver, and also removes a mach-omap2/prcm.c user. mach-omap2/prcm.c will be removed by a subsequent patch. Some modules have IDLEST registers that aren't in the CM module, such as the AM3517 IDLEST bits. So we also need a fallback function for these non-CM odd cases. Create a temporary one in mach-omap2/clock.c, intended to exist until the SCM drivers are ready. Signed-off-by: Paul Walmsley <paul@pwsan.com> Tested-by: Vaibhav Hiremath <hvaibhav@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c56
1 files changed, 53 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 9205ea7d8dde..2fe57d65d0f1 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -33,10 +33,18 @@
33#include "soc.h" 33#include "soc.h"
34#include "clockdomain.h" 34#include "clockdomain.h"
35#include "clock.h" 35#include "clock.h"
36#include "cm.h"
36#include "cm2xxx.h" 37#include "cm2xxx.h"
37#include "cm3xxx.h" 38#include "cm3xxx.h"
38#include "cm-regbits-24xx.h" 39#include "cm-regbits-24xx.h"
39#include "cm-regbits-34xx.h" 40#include "cm-regbits-34xx.h"
41#include "common.h"
42
43/*
44 * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait
45 * for a module to indicate that it is no longer in idle
46 */
47#define MAX_MODULE_ENABLE_WAIT 100000
40 48
41u16 cpu_mask; 49u16 cpu_mask;
42 50
@@ -58,6 +66,40 @@ static DEFINE_SPINLOCK(clockfw_lock);
58 66
59/* Private functions */ 67/* Private functions */
60 68
69
70/**
71 * _wait_idlest_generic - wait for a module to leave the idle state
72 * @reg: virtual address of module IDLEST register
73 * @mask: value to mask against to determine if the module is active
74 * @idlest: idle state indicator (0 or 1) for the clock
75 * @name: name of the clock (for printk)
76 *
77 * Wait for a module to leave idle, where its idle-status register is
78 * not inside the CM module. Returns 1 if the module left idle
79 * promptly, or 0 if the module did not leave idle before the timeout
80 * elapsed. XXX Deprecated - should be moved into drivers for the
81 * individual IP block that the IDLEST register exists in.
82 */
83static int _wait_idlest_generic(void __iomem *reg, u32 mask, u8 idlest,
84 const char *name)
85{
86 int i = 0, ena = 0;
87
88 ena = (idlest) ? 0 : mask;
89
90 omap_test_timeout(((__raw_readl(reg) & mask) == ena),
91 MAX_MODULE_ENABLE_WAIT, i);
92
93 if (i < MAX_MODULE_ENABLE_WAIT)
94 pr_debug("omap clock: module associated with clock %s ready after %d loops\n",
95 name, i);
96 else
97 pr_err("omap clock: module associated with clock %s didn't enable in %d tries\n",
98 name, MAX_MODULE_ENABLE_WAIT);
99
100 return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;
101};
102
61/** 103/**
62 * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE 104 * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
63 * @clk: struct clk * belonging to the module 105 * @clk: struct clk * belonging to the module
@@ -71,7 +113,9 @@ static DEFINE_SPINLOCK(clockfw_lock);
71static void _omap2_module_wait_ready(struct clk *clk) 113static void _omap2_module_wait_ready(struct clk *clk)
72{ 114{
73 void __iomem *companion_reg, *idlest_reg; 115 void __iomem *companion_reg, *idlest_reg;
74 u8 other_bit, idlest_bit, idlest_val; 116 u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
117 s16 prcm_mod;
118 int r;
75 119
76 /* Not all modules have multiple clocks that their IDLEST depends on */ 120 /* Not all modules have multiple clocks that their IDLEST depends on */
77 if (clk->ops->find_companion) { 121 if (clk->ops->find_companion) {
@@ -82,8 +126,14 @@ static void _omap2_module_wait_ready(struct clk *clk)
82 126
83 clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val); 127 clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
84 128
85 omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val, 129 r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id);
86 __clk_get_name(clk)); 130 if (r) {
131 /* IDLEST register not in the CM module */
132 _wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val,
133 clk->name);
134 } else {
135 cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit);
136 };
87} 137}
88 138
89/* Public functions */ 139/* Public functions */