* [PATCH 0/5] Clockdomain split series
@ 2011-01-05 14:22 Rajendra Nayak
2011-01-05 14:22 ` [PATCH 1/5] OMAP: clockdomain: Infrastructure to put arch specific code Rajendra Nayak
0 siblings, 1 reply; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-05 14:22 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman, b-cousson, Rajendra Nayak
This patch series is an effort to split the clockdomain
framework into platform independent and platform specific parts
as was done for the powerdomain framework.
This certainlly helps remove the various cpu_is_* checks
which exist today in the framework and makes
the code more maintainable and readable.
The series is boot tested on OMAP2430/3430/4430SDP platforms.
Also on OMAP3430SDP, OFF mode in suspend path is validated
using the omap3_pm_defconfig.
This series is based on latest linux-omap master and
can be found here
git://gitorious.org/omap-pm/linux.git clockdomain-split
Rajendra Nayak (5):
OMAP: clockdomain: Infrastructure to put arch specific code
OMAP: clockdomain: Arch specific funcs to handle deps
OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm
OMAP: clockdomain: Arch specific funcs for hwsup control of clkdm
OMAP: clockdomain: Arch specific funcs for clkdm_clk_enable/disable
arch/arm/mach-omap2/Makefile | 3 +
arch/arm/mach-omap2/clock.c | 6 +-
arch/arm/mach-omap2/clockdomain.c | 313 +++++-----------------
arch/arm/mach-omap2/clockdomain.h | 58 ++++-
arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 268 ++++++++++++++++++
arch/arm/mach-omap2/clockdomain44xx.c | 77 ++++++
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 9 +-
arch/arm/mach-omap2/clockdomains44xx_data.c | 2 +-
arch/arm/mach-omap2/cpuidle34xx.c | 4 +-
arch/arm/mach-omap2/io.c | 6 +-
arch/arm/mach-omap2/pm.c | 6 +-
arch/arm/mach-omap2/pm24xx.c | 8 +-
arch/arm/mach-omap2/pm34xx.c | 6 +-
13 files changed, 494 insertions(+), 272 deletions(-)
create mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
create mode 100644 arch/arm/mach-omap2/clockdomain44xx.c
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/5] OMAP: clockdomain: Infrastructure to put arch specific code
2011-01-05 14:22 [PATCH 0/5] Clockdomain split series Rajendra Nayak
@ 2011-01-05 14:22 ` Rajendra Nayak
2011-01-05 14:22 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Rajendra Nayak
0 siblings, 1 reply; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-05 14:22 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman, b-cousson, Rajendra Nayak
Put infrastructure in place, so arch specific func pointers
can be hooked up to the platform-independent part of the
framework.
This is in preparation of splitting the clockdomain framework into
platform-independent part (for all omaps) and platform-specific
parts.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/clockdomain.c | 10 +++++-
arch/arm/mach-omap2/clockdomain.h | 37 +++++++++++++++++++++-
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 2 +-
arch/arm/mach-omap2/clockdomains44xx_data.c | 2 +-
4 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index e20b986..3e40184 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -44,6 +44,7 @@ static LIST_HEAD(clkdm_list);
/* array of clockdomain deps to be added/removed when clkdm in hwsup mode */
static struct clkdm_autodep *autodeps;
+static struct clkdm_ops *arch_clkdm;
/* Private functions */
@@ -292,6 +293,7 @@ static void _disable_hwsup(struct clockdomain *clkdm)
* clkdm_init - set up the clockdomain layer
* @clkdms: optional pointer to an array of clockdomains to register
* @init_autodeps: optional pointer to an array of autodeps to register
+ * @custom_funcs: func pointers for arch specfic implementations
*
* Set up internal state. If a pointer to an array of clockdomains
* @clkdms was supplied, loop through the list of clockdomains,
@@ -300,12 +302,18 @@ static void _disable_hwsup(struct clockdomain *clkdm)
* @init_autodeps was provided, register those. No return value.
*/
void clkdm_init(struct clockdomain **clkdms,
- struct clkdm_autodep *init_autodeps)
+ struct clkdm_autodep *init_autodeps,
+ struct clkdm_ops *custom_funcs)
{
struct clockdomain **c = NULL;
struct clockdomain *clkdm;
struct clkdm_autodep *autodep = NULL;
+ if (!custom_funcs)
+ WARN(1, "No custom clkdm functions registered\n");
+ else
+ arch_clkdm = custom_funcs;
+
if (clkdms)
for (c = clkdms; *c; c++)
_clkdm_register(*c);
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index de3faa2..346efa2 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -118,7 +118,42 @@ struct clockdomain {
struct list_head node;
};
-void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps);
+/**
+ * struct clkdm_ops - Arch specfic function implementations
+ * @clkdm_add_wkdep: Add a wakeup dependency between clk domains
+ * @clkdm_del_wkdep: Delete a wakeup dependency between clk domains
+ * @clkdm_read_wkdep: Read wakeup dependency state between clk domains
+ * @clkdm_clear_all_wkdeps: Remove all wakeup dependencies from the clk domain
+ * @clkdm_add_sleepdep: Add a sleep dependency between clk domains
+ * @clkdm_del_sleepdep: Delete a sleep dependency between clk domains
+ * @clkdm_read_sleepdep: Read sleep dependency state between clk domains
+ * @clkdm_clear_all_sleepdeps: Remove all sleep dependencies from the clk domain
+ * @clkdm_sleep: Force a clockdomain to sleep
+ * @clkdm_wakeup: Force a clockdomain to wakeup
+ * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain
+ * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
+ * @clkdm_clk_enable: Put the clkdm in right state for a clock enable
+ * @clkdm_clk_disable: Put the clkdm in right state for a clock disable
+ */
+struct clkdm_ops {
+ void (*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ void (*clkdm_del_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_read_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ void (*clkdm_clear_all_wkdeps)(struct clockdomain *clkdm);
+ void (*clkdm_add_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ void (*clkdm_del_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_read_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ void (*clkdm_clear_all_sleepdeps)(struct clockdomain *clkdm);
+ int (*clkdm_sleep)(struct clockdomain *clkdm);
+ int (*clkdm_wakeup)(struct clockdomain *clkdm);
+ void (*clkdm_allow_idle)(struct clockdomain *clkdm);
+ void (*clkdm_deny_idle)(struct clockdomain *clkdm);
+ int (*clkdm_clk_enable)(struct clockdomain *clkdm);
+ int (*clkdm_clk_disable)(struct clockdomain *clkdm);
+};
+
+void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps,
+ struct clkdm_ops *custom_funcs);
struct clockdomain *clkdm_lookup(const char *name);
int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
index e4a7133..8cab07a 100644
--- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -856,5 +856,5 @@ static struct clockdomain *clockdomains_omap2[] __initdata = {
void __init omap2_clockdomains_init(void)
{
- clkdm_init(clockdomains_omap2, clkdm_autodeps);
+ clkdm_init(clockdomains_omap2, clkdm_autodeps, NULL);
}
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 51920fc..f04abc5 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -307,5 +307,5 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = {
void __init omap44xx_clockdomains_init(void)
{
- clkdm_init(clockdomains_omap44xx, NULL);
+ clkdm_init(clockdomains_omap44xx, NULL, NULL);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
2011-01-05 14:22 ` [PATCH 1/5] OMAP: clockdomain: Infrastructure to put arch specific code Rajendra Nayak
@ 2011-01-05 14:22 ` Rajendra Nayak
2011-01-05 14:22 ` [PATCH 3/5] OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm Rajendra Nayak
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-05 14:22 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman, b-cousson, Rajendra Nayak
Define the following architecture specific funtions for omap2/3
.clkdm_add_wkdep
.clkdm_del_wkdep
.clkdm_read_wkdep
.clkdm_clear_all_wkdeps
.clkdm_add_sleepdep
.clkdm_del_sleepdep
.clkdm_read_sleepdep
.clkdm_clear_all_sleepdeps
Convert the platform-independent framework to call these functions.
With this also move the clkdm lookups for all wkdep_srcs and
sleepdep_srcs at clkdm_init.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/Makefile | 2 +
arch/arm/mach-omap2/clockdomain.c | 80 ++++++---------
arch/arm/mach-omap2/clockdomain.h | 2 +
arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 113 ++++++++++++++++++++++
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 2 +-
5 files changed, 150 insertions(+), 49 deletions(-)
create mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 4ab82f6..d28db0a 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -102,8 +102,10 @@ obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \
# PRCM clockdomain control
obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
+ clockdomain2xxx_3xxx.o \
clockdomains2xxx_3xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
+ clockdomain2xxx_3xxx.o \
clockdomains2xxx_3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
clockdomains44xx_data.o
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 3e40184..c32480c 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -308,6 +308,7 @@ void clkdm_init(struct clockdomain **clkdms,
struct clockdomain **c = NULL;
struct clockdomain *clkdm;
struct clkdm_autodep *autodep = NULL;
+ struct clkdm_dep *cd;
if (!custom_funcs)
WARN(1, "No custom clkdm functions registered\n");
@@ -333,7 +334,18 @@ void clkdm_init(struct clockdomain **clkdms,
else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
omap2_clkdm_deny_idle(clkdm);
+ for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+ }
clkdm_clear_all_wkdeps(clkdm);
+
+ for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+ }
clkdm_clear_all_sleepdeps(clkdm);
}
}
@@ -445,8 +457,8 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
pr_debug("clockdomain: hardware will wake up %s when %s wakes "
"up\n", clkdm1->name, clkdm2->name);
- omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ if (arch_clkdm && arch_clkdm->clkdm_add_wkdep)
+ arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
}
return 0;
@@ -480,8 +492,8 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
pr_debug("clockdomain: hardware will no longer wake up %s "
"after %s wakes up\n", clkdm1->name, clkdm2->name);
- omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ if (arch_clkdm && arch_clkdm->clkdm_del_wkdep)
+ arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
}
return 0;
@@ -516,8 +528,10 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
}
/* XXX It's faster to return the atomic wkdep_usecount */
- return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
- (1 << clkdm2->dep_bit));
+ if (arch_clkdm && arch_clkdm->clkdm_read_wkdep)
+ return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
+
+ return -EINVAL;
}
/**
@@ -532,25 +546,11 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
*/
int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
{
- struct clkdm_dep *cd;
- u32 mask = 0;
-
if (!clkdm)
return -EINVAL;
- for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
-
- if (!cd->clkdm && cd->clkdm_name)
- cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
- /* PRM accesses are slow, so minimize them */
- mask |= 1 << cd->clkdm->dep_bit;
- atomic_set(&cd->wkdep_usecount, 0);
- }
-
- omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ if (arch_clkdm && arch_clkdm->clkdm_clear_all_wkdeps)
+ arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
return 0;
}
@@ -589,9 +589,8 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
pr_debug("clockdomain: will prevent %s from sleeping if %s "
"is active\n", clkdm1->name, clkdm2->name);
- omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP);
+ if (arch_clkdm && arch_clkdm->clkdm_add_sleepdep)
+ arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
}
return 0;
@@ -632,9 +631,8 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
"sleeping if %s is active\n", clkdm1->name,
clkdm2->name);
- omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
- clkdm1->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP);
+ if (arch_clkdm && arch_clkdm->clkdm_del_sleepdep)
+ arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
}
return 0;
@@ -675,9 +673,10 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
}
/* XXX It's faster to return the atomic sleepdep_usecount */
- return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP,
- (1 << clkdm2->dep_bit));
+ if (arch_clkdm && arch_clkdm->clkdm_read_sleepdep)
+ return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
+
+ return -EINVAL;
}
/**
@@ -692,29 +691,14 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
*/
int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
{
- struct clkdm_dep *cd;
- u32 mask = 0;
-
if (!cpu_is_omap34xx())
return -EINVAL;
if (!clkdm)
return -EINVAL;
- for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
-
- if (!cd->clkdm && cd->clkdm_name)
- cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
- /* PRM accesses are slow, so minimize them */
- mask |= 1 << cd->clkdm->dep_bit;
- atomic_set(&cd->sleepdep_usecount, 0);
- }
-
- omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
- OMAP3430_CM_SLEEPDEP);
+ if (arch_clkdm && arch_clkdm->clkdm_clear_all_sleepdeps)
+ arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
return 0;
}
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 346efa2..a9cda27 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -181,4 +181,6 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
extern void __init omap2_clockdomains_init(void);
extern void __init omap44xx_clockdomains_init(void);
+extern struct clkdm_ops omap2_clkdm_operations;
+
#endif
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
new file mode 100644
index 0000000..a7303bd
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -0,0 +1,113 @@
+/*
+ * OMAP2 and OMAP3 clockdomain control
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <plat/prcm.h>
+#include "prm.h"
+#include "prm2xxx_3xxx.h"
+#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+#include "clockdomain.h"
+
+static void omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+}
+
+static void omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+}
+
+static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ PM_WKDEP, (1 << clkdm2->dep_bit));
+}
+
+static void omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
+{
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+
+ /* PRM accesses are slow, so minimize them */
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->wkdep_usecount, 0);
+ }
+
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ PM_WKDEP);
+}
+
+static void omap2_clkdm_add_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+}
+
+static void omap2_clkdm_del_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+}
+
+static int omap2_clkdm_read_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
+}
+
+static void omap2_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
+{
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+
+ /* PRM accesses are slow, so minimize them */
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->sleepdep_usecount, 0);
+ }
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+}
+
+struct clkdm_ops omap2_clkdm_operations = {
+ .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
+ .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
+ .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
+ .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
+ .clkdm_add_sleepdep = omap2_clkdm_add_sleepdep,
+ .clkdm_del_sleepdep = omap2_clkdm_del_sleepdep,
+ .clkdm_read_sleepdep = omap2_clkdm_read_sleepdep,
+ .clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
+};
diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
index 8cab07a..ba0bbbd 100644
--- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -856,5 +856,5 @@ static struct clockdomain *clockdomains_omap2[] __initdata = {
void __init omap2_clockdomains_init(void)
{
- clkdm_init(clockdomains_omap2, clkdm_autodeps, NULL);
+ clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/5] OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm
2011-01-05 14:22 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Rajendra Nayak
@ 2011-01-05 14:22 ` Rajendra Nayak
2011-01-05 14:22 ` [PATCH 4/5] OMAP: clockdomain: Arch specific funcs for hwsup control " Rajendra Nayak
2011-01-11 1:05 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Paul Walmsley
2011-01-11 1:32 ` Paul Walmsley
2 siblings, 1 reply; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-05 14:22 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman, b-cousson, Rajendra Nayak
Define the following architecture specific funtions for omap2/3/4
.clkdm_sleep
.clkdm_wakeup
Convert the platform-independent framework to call these functions.
Also rename the api's by removing the omap2_ preamble.
Hence call omap2_clkdm_wakeup as clkdm_wakeup and
omap2_clkdm_sleep as clkdm_sleep.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/Makefile | 1 +
arch/arm/mach-omap2/clockdomain.c | 56 ++++-----------------
arch/arm/mach-omap2/clockdomain.h | 9 ++-
arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 46 ++++++++++++++++++
arch/arm/mach-omap2/clockdomain44xx.c | 35 +++++++++++++
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 7 ++-
arch/arm/mach-omap2/clockdomains44xx_data.c | 2 +-
arch/arm/mach-omap2/io.c | 6 +-
arch/arm/mach-omap2/pm.c | 4 +-
arch/arm/mach-omap2/pm24xx.c | 6 +-
arch/arm/mach-omap2/pm34xx.c | 2 +-
11 files changed, 115 insertions(+), 59 deletions(-)
create mode 100644 arch/arm/mach-omap2/clockdomain44xx.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index d28db0a..9990d88 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -108,6 +108,7 @@ obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
clockdomain2xxx_3xxx.o \
clockdomains2xxx_3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
+ clockdomain44xx.o \
clockdomains44xx_data.o
# Clock framework
obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index c32480c..ce55279 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -330,7 +330,7 @@ void clkdm_init(struct clockdomain **clkdms,
*/
list_for_each_entry(clkdm, &clkdm_list, node) {
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
- omap2_clkdm_wakeup(clkdm);
+ clkdm_wakeup(clkdm);
else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
omap2_clkdm_deny_idle(clkdm);
@@ -704,7 +704,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
}
/**
- * omap2_clkdm_sleep - force clockdomain sleep transition
+ * clkdm_sleep - force clockdomain sleep transition
* @clkdm: struct clockdomain *
*
* Instruct the CM to force a sleep transition on the specified
@@ -712,7 +712,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
* clockdomain does not support software-initiated sleep; 0 upon
* success.
*/
-int omap2_clkdm_sleep(struct clockdomain *clkdm)
+int clkdm_sleep(struct clockdomain *clkdm)
{
if (!clkdm)
return -EINVAL;
@@ -725,31 +725,14 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
- if (cpu_is_omap24xx()) {
-
- omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
- clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
-
- } else if (cpu_is_omap34xx()) {
-
- omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- } else if (cpu_is_omap44xx()) {
-
- omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
- clkdm->cm_inst,
- clkdm->clkdm_offs);
-
- } else {
- BUG();
- };
+ if (arch_clkdm && arch_clkdm->clkdm_sleep)
+ return arch_clkdm->clkdm_sleep(clkdm);
return 0;
}
/**
- * omap2_clkdm_wakeup - force clockdomain wakeup transition
+ * clkdm_wakeup - force clockdomain wakeup transition
* @clkdm: struct clockdomain *
*
* Instruct the CM to force a wakeup transition on the specified
@@ -757,7 +740,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
* clockdomain does not support software-controlled wakeup; 0 upon
* success.
*/
-int omap2_clkdm_wakeup(struct clockdomain *clkdm)
+int clkdm_wakeup(struct clockdomain *clkdm)
{
if (!clkdm)
return -EINVAL;
@@ -770,25 +753,8 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
- if (cpu_is_omap24xx()) {
-
- omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
- clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
-
- } else if (cpu_is_omap34xx()) {
-
- omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- } else if (cpu_is_omap44xx()) {
-
- omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
- clkdm->cm_inst,
- clkdm->clkdm_offs);
-
- } else {
- BUG();
- };
+ if (arch_clkdm && arch_clkdm->clkdm_wakeup)
+ return arch_clkdm->clkdm_wakeup(clkdm);
return 0;
}
@@ -931,7 +897,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
_clkdm_add_autodeps(clkdm);
_enable_hwsup(clkdm);
} else {
- omap2_clkdm_wakeup(clkdm);
+ clkdm_wakeup(clkdm);
}
pwrdm_wait_transition(clkdm->pwrdm.ptr);
@@ -1003,7 +969,7 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
_clkdm_del_autodeps(clkdm);
_enable_hwsup(clkdm);
} else {
- omap2_clkdm_sleep(clkdm);
+ clkdm_sleep(clkdm);
}
pwrdm_clkdm_state_switch(clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index a9cda27..9f28aa9 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -172,15 +172,18 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
-int omap2_clkdm_wakeup(struct clockdomain *clkdm);
-int omap2_clkdm_sleep(struct clockdomain *clkdm);
+int clkdm_wakeup(struct clockdomain *clkdm);
+int clkdm_sleep(struct clockdomain *clkdm);
int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
-extern void __init omap2_clockdomains_init(void);
+extern void __init omap2xxx_clockdomains_init(void);
+extern void __init omap3xxx_clockdomains_init(void);
extern void __init omap44xx_clockdomains_init(void);
extern struct clkdm_ops omap2_clkdm_operations;
+extern struct clkdm_ops omap3_clkdm_operations;
+extern struct clkdm_ops omap4_clkdm_operations;
#endif
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index a7303bd..555e394 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -20,6 +20,7 @@
#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"
+#include "prm-regbits-24xx.h"
#include "clockdomain.h"
static void omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
@@ -101,6 +102,36 @@ static void omap2_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
OMAP3430_CM_SLEEPDEP);
}
+static int omap2_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap3_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
+
+static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
+
struct clkdm_ops omap2_clkdm_operations = {
.clkdm_add_wkdep = omap2_clkdm_add_wkdep,
.clkdm_del_wkdep = omap2_clkdm_del_wkdep,
@@ -110,4 +141,19 @@ struct clkdm_ops omap2_clkdm_operations = {
.clkdm_del_sleepdep = omap2_clkdm_del_sleepdep,
.clkdm_read_sleepdep = omap2_clkdm_read_sleepdep,
.clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
+ .clkdm_sleep = omap2_clkdm_sleep,
+ .clkdm_wakeup = omap2_clkdm_wakeup,
+};
+
+struct clkdm_ops omap3_clkdm_operations = {
+ .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
+ .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
+ .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
+ .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
+ .clkdm_add_sleepdep = omap2_clkdm_add_sleepdep,
+ .clkdm_del_sleepdep = omap2_clkdm_del_sleepdep,
+ .clkdm_read_sleepdep = omap2_clkdm_read_sleepdep,
+ .clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
+ .clkdm_sleep = omap3_clkdm_sleep,
+ .clkdm_wakeup = omap3_clkdm_wakeup,
};
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
new file mode 100644
index 0000000..9ccb406
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -0,0 +1,35 @@
+/*
+ * OMAP4 clockdomain control
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "clockdomain.h"
+#include "cminst44xx.h"
+
+static int omap4_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+struct clkdm_ops omap4_clkdm_operations = {
+ .clkdm_sleep = omap4_clkdm_sleep,
+ .clkdm_wakeup = omap4_clkdm_wakeup,
+};
diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
index ba0bbbd..f85de72 100644
--- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -854,7 +854,12 @@ static struct clockdomain *clockdomains_omap2[] __initdata = {
NULL,
};
-void __init omap2_clockdomains_init(void)
+void __init omap2xxx_clockdomains_init(void)
{
clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations);
}
+
+void __init omap3xxx_clockdomains_init(void)
+{
+ clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap3_clkdm_operations);
+}
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index f04abc5..2fe1570 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -307,5 +307,5 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = {
void __init omap44xx_clockdomains_init(void)
{
- clkdm_init(clockdomains_omap44xx, NULL, NULL);
+ clkdm_init(clockdomains_omap44xx, NULL, &omap4_clkdm_operations);
}
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index e66687b..e1c5e76 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -339,15 +339,15 @@ void __init omap2_init_common_infrastructure(void)
if (cpu_is_omap242x()) {
omap2xxx_powerdomains_init();
- omap2_clockdomains_init();
+ omap2xxx_clockdomains_init();
omap2420_hwmod_init();
} else if (cpu_is_omap243x()) {
omap2xxx_powerdomains_init();
- omap2_clockdomains_init();
+ omap2xxx_clockdomains_init();
omap2430_hwmod_init();
} else if (cpu_is_omap34xx()) {
omap3xxx_powerdomains_init();
- omap2_clockdomains_init();
+ omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
} else if (cpu_is_omap44xx()) {
omap44xx_powerdomains_init();
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index d5a102c..74c3100 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -124,7 +124,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
sleep_switch = LOWPOWERSTATE_SWITCH;
} else {
- omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+ clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
pwrdm_wait_transition(pwrdm);
sleep_switch = FORCEWAKEUP_SWITCH;
}
@@ -142,7 +142,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
else
- omap2_clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+ clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
break;
case LOWPOWERSTATE_SWITCH:
pwrdm_set_lowpwrstchange(pwrdm);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index dac2d1d..c14113b 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -370,7 +370,7 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
omap2_clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
atomic_read(&clkdm->usecount) == 0)
- omap2_clkdm_sleep(clkdm);
+ clkdm_sleep(clkdm);
return 0;
}
@@ -405,11 +405,11 @@ static void __init prcm_setup_regs(void)
pwrdm = clkdm_get_pwrdm(dsp_clkdm);
pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
- omap2_clkdm_sleep(dsp_clkdm);
+ clkdm_sleep(dsp_clkdm);
pwrdm = clkdm_get_pwrdm(gfx_clkdm);
pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
- omap2_clkdm_sleep(gfx_clkdm);
+ clkdm_sleep(gfx_clkdm);
/*
* Clear clockdomain wakeup dependencies and enable
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 5b323f2..c7712c7 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -992,7 +992,7 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
omap2_clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
atomic_read(&clkdm->usecount) == 0)
- omap2_clkdm_sleep(clkdm);
+ clkdm_sleep(clkdm);
return 0;
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] OMAP: clockdomain: Arch specific funcs for hwsup control of clkdm
2011-01-05 14:22 ` [PATCH 3/5] OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm Rajendra Nayak
@ 2011-01-05 14:22 ` Rajendra Nayak
2011-01-05 14:22 ` [PATCH 5/5] OMAP: clockdomain: Arch specific funcs for clkdm_clk_enable/disable Rajendra Nayak
0 siblings, 1 reply; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-05 14:22 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman, b-cousson, Rajendra Nayak
Define the following architecture specific funtions for omap2/3/4
.clkdm_allow_idle
.clkdm_deny_idle
Convert the platform-independent framework to call these functions.
Also rename the api's by removing the omap2_ preamble.
Hence call omap2_clkdm_allow_idle as clkdm_allow_idle and
omap2_clkdm_deny_idle as clkdm_deny_idle.
Make the _clkdm_add_autodeps and _clkdm_del_autodeps as non-static
so they can be accessed from OMAP2/3 platform specific code.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/clockdomain.c | 46 +++++++--------------------
arch/arm/mach-omap2/clockdomain.h | 6 ++-
arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 40 ++++++++++++++++++++++++
arch/arm/mach-omap2/clockdomain44xx.c | 14 ++++++++
arch/arm/mach-omap2/cpuidle34xx.c | 4 +-
arch/arm/mach-omap2/pm.c | 2 +-
arch/arm/mach-omap2/pm24xx.c | 2 +-
arch/arm/mach-omap2/pm34xx.c | 4 +-
8 files changed, 76 insertions(+), 42 deletions(-)
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index ce55279..1dafbb1 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -178,7 +178,7 @@ static void _autodep_lookup(struct clkdm_autodep *autodep)
* XXX autodeps are deprecated and should be removed at the earliest
* opportunity
*/
-static void _clkdm_add_autodeps(struct clockdomain *clkdm)
+void _clkdm_add_autodeps(struct clockdomain *clkdm)
{
struct clkdm_autodep *autodep;
@@ -212,7 +212,7 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)
* XXX autodeps are deprecated and should be removed at the earliest
* opportunity
*/
-static void _clkdm_del_autodeps(struct clockdomain *clkdm)
+void _clkdm_del_autodeps(struct clockdomain *clkdm)
{
struct clkdm_autodep *autodep;
@@ -332,7 +332,7 @@ void clkdm_init(struct clockdomain **clkdms,
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
clkdm_wakeup(clkdm);
else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
- omap2_clkdm_deny_idle(clkdm);
+ clkdm_deny_idle(clkdm);
for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
if (!omap_chip_is(cd->omap_chip))
@@ -760,7 +760,7 @@ int clkdm_wakeup(struct clockdomain *clkdm)
}
/**
- * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
+ * clkdm_allow_idle - enable hwsup idle transitions for clkdm
* @clkdm: struct clockdomain *
*
* Allow the hardware to automatically switch the clockdomain @clkdm into
@@ -769,7 +769,7 @@ int clkdm_wakeup(struct clockdomain *clkdm)
* framework, wkdep/sleepdep autodependencies are added; this is so
* device drivers can read and write to the device. No return value.
*/
-void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+void clkdm_allow_idle(struct clockdomain *clkdm)
{
if (!clkdm)
return;
@@ -783,25 +783,14 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
clkdm->name);
- /*
- * XXX This should be removed once TI adds wakeup/sleep
- * dependency code and data for OMAP4.
- */
- if (cpu_is_omap44xx()) {
- WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
- "support is not yet implemented\n");
- } else {
- if (atomic_read(&clkdm->usecount) > 0)
- _clkdm_add_autodeps(clkdm);
+ if (arch_clkdm && arch_clkdm->clkdm_allow_idle) {
+ arch_clkdm->clkdm_allow_idle(clkdm);
+ pwrdm_clkdm_state_switch(clkdm);
}
-
- _enable_hwsup(clkdm);
-
- pwrdm_clkdm_state_switch(clkdm);
}
/**
- * omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm
+ * clkdm_deny_idle - disable hwsup idle transitions for clkdm
* @clkdm: struct clockdomain *
*
* Prevent the hardware from automatically switching the clockdomain
@@ -809,7 +798,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
* downstream clocks enabled in the clock framework, wkdep/sleepdep
* autodependencies are removed. No return value.
*/
-void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+void clkdm_deny_idle(struct clockdomain *clkdm)
{
if (!clkdm)
return;
@@ -823,19 +812,8 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
clkdm->name);
- _disable_hwsup(clkdm);
-
- /*
- * XXX This should be removed once TI adds wakeup/sleep
- * dependency code and data for OMAP4.
- */
- if (cpu_is_omap44xx()) {
- WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
- "support is not yet implemented\n");
- } else {
- if (atomic_read(&clkdm->usecount) > 0)
- _clkdm_del_autodeps(clkdm);
- }
+ if (arch_clkdm && arch_clkdm->clkdm_deny_idle)
+ arch_clkdm->clkdm_deny_idle(clkdm);
}
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 9f28aa9..fe220f7 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -169,8 +169,8 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
-void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
-void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
+void clkdm_allow_idle(struct clockdomain *clkdm);
+void clkdm_deny_idle(struct clockdomain *clkdm);
int clkdm_wakeup(struct clockdomain *clkdm);
int clkdm_sleep(struct clockdomain *clkdm);
@@ -181,6 +181,8 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
extern void __init omap2xxx_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);
extern void __init omap44xx_clockdomains_init(void);
+extern void _clkdm_add_autodeps(struct clockdomain *clkdm);
+extern void _clkdm_del_autodeps(struct clockdomain *clkdm);
extern struct clkdm_ops omap2_clkdm_operations;
extern struct clkdm_ops omap3_clkdm_operations;
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 555e394..2bc9970 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -118,6 +118,24 @@ static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
return 0;
}
+static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_add_autodeps(clkdm);
+
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_del_autodeps(clkdm);
+}
+
static int omap3_clkdm_sleep(struct clockdomain *clkdm)
{
omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
@@ -132,6 +150,24 @@ static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
return 0;
}
+static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_add_autodeps(clkdm);
+
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_del_autodeps(clkdm);
+}
+
struct clkdm_ops omap2_clkdm_operations = {
.clkdm_add_wkdep = omap2_clkdm_add_wkdep,
.clkdm_del_wkdep = omap2_clkdm_del_wkdep,
@@ -143,6 +179,8 @@ struct clkdm_ops omap2_clkdm_operations = {
.clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
.clkdm_sleep = omap2_clkdm_sleep,
.clkdm_wakeup = omap2_clkdm_wakeup,
+ .clkdm_allow_idle = omap2_clkdm_allow_idle,
+ .clkdm_deny_idle = omap2_clkdm_deny_idle,
};
struct clkdm_ops omap3_clkdm_operations = {
@@ -156,4 +194,6 @@ struct clkdm_ops omap3_clkdm_operations = {
.clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
.clkdm_sleep = omap3_clkdm_sleep,
.clkdm_wakeup = omap3_clkdm_wakeup,
+ .clkdm_allow_idle = omap3_clkdm_allow_idle,
+ .clkdm_deny_idle = omap3_clkdm_deny_idle,
};
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 9ccb406..a46125f 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -29,7 +29,21 @@ static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
return 0;
}
+static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
struct clkdm_ops omap4_clkdm_operations = {
.clkdm_sleep = omap4_clkdm_sleep,
.clkdm_wakeup = omap4_clkdm_wakeup,
+ .clkdm_allow_idle = omap4_clkdm_allow_idle,
+ .clkdm_deny_idle = omap4_clkdm_deny_idle,
};
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index f3e043f..33837f6 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -97,14 +97,14 @@ static int omap3_idle_bm_check(void)
static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
struct clockdomain *clkdm)
{
- omap2_clkdm_allow_idle(clkdm);
+ clkdm_allow_idle(clkdm);
return 0;
}
static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
struct clockdomain *clkdm)
{
- omap2_clkdm_deny_idle(clkdm);
+ clkdm_deny_idle(clkdm);
return 0;
}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 74c3100..7bb64d8 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -140,7 +140,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
switch (sleep_switch) {
case FORCEWAKEUP_SWITCH:
if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
- omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
else
clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
break;
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index c14113b..dca91ce 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -367,7 +367,7 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
clkdm_clear_all_sleepdeps(clkdm);
if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
- omap2_clkdm_allow_idle(clkdm);
+ clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
atomic_read(&clkdm->usecount) == 0)
clkdm_sleep(clkdm);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index c7712c7..e410f39 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -495,7 +495,7 @@ console_still_active:
pwrdm_post_transition();
- omap2_clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
+ clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
}
int omap3_can_sleep(void)
@@ -989,7 +989,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
{
if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
- omap2_clkdm_allow_idle(clkdm);
+ clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
atomic_read(&clkdm->usecount) == 0)
clkdm_sleep(clkdm);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/5] OMAP: clockdomain: Arch specific funcs for clkdm_clk_enable/disable
2011-01-05 14:22 ` [PATCH 4/5] OMAP: clockdomain: Arch specific funcs for hwsup control " Rajendra Nayak
@ 2011-01-05 14:22 ` Rajendra Nayak
0 siblings, 0 replies; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-05 14:22 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman, b-cousson, Rajendra Nayak
Define the following architecture specific funtions for omap2/3/4
.clkdm_clk_enable
.clkdm_clk_disable
Convert the platform-independent framework to call these functions.
Also rename the api's by removing the omap2_ preamble.
Hence call omap2_clkdm_k_enable as clkdm_clk_enable and
omap2_clkdm_clk_disable as clkdm_clk_disable.a
Remove unused functions (_enable/_disable_hwsup) and unsed
headers from clockdomain.c file.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/clock.c | 6 +-
arch/arm/mach-omap2/clockdomain.c | 125 ++--------------------------
arch/arm/mach-omap2/clockdomain.h | 4 +-
arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 69 +++++++++++++++
arch/arm/mach-omap2/clockdomain44xx.c | 28 ++++++
5 files changed, 110 insertions(+), 122 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 2a2f152..e9625fc 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -264,7 +264,7 @@ void omap2_clk_disable(struct clk *clk)
clk->ops->disable(clk);
if (clk->clkdm)
- omap2_clkdm_clk_disable(clk->clkdm, clk);
+ clkdm_clk_disable(clk->clkdm, clk);
if (clk->parent)
omap2_clk_disable(clk->parent);
@@ -304,7 +304,7 @@ int omap2_clk_enable(struct clk *clk)
}
if (clk->clkdm) {
- ret = omap2_clkdm_clk_enable(clk->clkdm, clk);
+ ret = clkdm_clk_enable(clk->clkdm, clk);
if (ret) {
WARN(1, "clock: %s: could not enable clockdomain %s: "
"%d\n", clk->name, clk->clkdm->name, ret);
@@ -322,7 +322,7 @@ int omap2_clk_enable(struct clk *clk)
oce_err3:
if (clk->clkdm)
- omap2_clkdm_clk_disable(clk->clkdm, clk);
+ clkdm_clk_disable(clk->clkdm, clk);
oce_err2:
if (clk->parent)
omap2_clk_disable(clk->parent);
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 1dafbb1..767579d 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -26,17 +26,8 @@
#include <linux/bitops.h>
-#include "prm2xxx_3xxx.h"
-#include "prm-regbits-24xx.h"
-#include "cm2xxx_3xxx.h"
-#include "cm-regbits-24xx.h"
-#include "cminst44xx.h"
-#include "prcm44xx.h"
-
#include <plat/clock.h>
-#include "powerdomain.h"
#include "clockdomain.h"
-#include <plat/prcm.h>
/* clkdm_list contains all registered struct clockdomains */
static LIST_HEAD(clkdm_list);
@@ -235,58 +226,6 @@ void _clkdm_del_autodeps(struct clockdomain *clkdm)
}
}
-/**
- * _enable_hwsup - place a clockdomain into hardware-supervised idle
- * @clkdm: struct clockdomain *
- *
- * Place the clockdomain into hardware-supervised idle mode. No return
- * value.
- *
- * XXX Should this return an error if the clockdomain does not support
- * hardware-supervised idle mode?
- */
-static void _enable_hwsup(struct clockdomain *clkdm)
-{
- if (cpu_is_omap24xx())
- omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- else if (cpu_is_omap34xx())
- omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- else if (cpu_is_omap44xx())
- return omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst,
- clkdm->clkdm_offs);
- else
- BUG();
-}
-
-/**
- * _disable_hwsup - place a clockdomain into software-supervised idle
- * @clkdm: struct clockdomain *
- *
- * Place the clockdomain @clkdm into software-supervised idle mode.
- * No return value.
- *
- * XXX Should this return an error if the clockdomain does not support
- * software-supervised idle mode?
- */
-static void _disable_hwsup(struct clockdomain *clkdm)
-{
- if (cpu_is_omap24xx())
- omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- else if (cpu_is_omap34xx())
- omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- else if (cpu_is_omap44xx())
- return omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst,
- clkdm->clkdm_offs);
- else
- BUG();
-}
-
/* Public functions */
/**
@@ -820,7 +759,7 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
/* Clockdomain-to-clock framework interface code */
/**
- * omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm
+ * clkdm_clk_enable - add an enabled downstream clock to this clkdm
* @clkdm: struct clockdomain *
* @clk: struct clk * of the enabled downstream clock
*
@@ -833,10 +772,8 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
* by on-chip processors. Returns -EINVAL if passed null pointers;
* returns 0 upon success or if the clockdomain is in hwsup idle mode.
*/
-int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
+int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
{
- bool hwsup = false;
-
/*
* XXX Rewrite this code to maintain a list of enabled
* downstream clocks for debugging purposes?
@@ -853,30 +790,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
clk->name);
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- } else if (cpu_is_omap44xx()) {
-
- hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst,
- clkdm->clkdm_offs);
-
- }
-
- if (hwsup) {
- /* Disable HW transitions when we are changing deps */
- _disable_hwsup(clkdm);
- _clkdm_add_autodeps(clkdm);
- _enable_hwsup(clkdm);
- } else {
- clkdm_wakeup(clkdm);
- }
+ if (arch_clkdm && arch_clkdm->clkdm_clk_enable)
+ arch_clkdm->clkdm_clk_enable(clkdm);
pwrdm_wait_transition(clkdm->pwrdm.ptr);
pwrdm_clkdm_state_switch(clkdm);
@@ -885,7 +800,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
}
/**
- * omap2_clkdm_clk_disable - remove an enabled downstream clock from this clkdm
+ * clkdm_clk_disable - remove an enabled downstream clock from this clkdm
* @clkdm: struct clockdomain *
* @clk: struct clk * of the disabled downstream clock
*
@@ -898,10 +813,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
* is enabled; or returns 0 upon success or if the clockdomain is in
* hwsup idle mode.
*/
-int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
+int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
{
- bool hwsup = false;
-
/*
* XXX Rewrite this code to maintain a list of enabled
* downstream clocks for debugging purposes?
@@ -925,30 +838,8 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
clk->name);
- if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- } else if (cpu_is_omap44xx()) {
-
- hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
- clkdm->cm_inst,
- clkdm->clkdm_offs);
-
- }
-
- if (hwsup) {
- /* Disable HW transitions when we are changing deps */
- _disable_hwsup(clkdm);
- _clkdm_del_autodeps(clkdm);
- _enable_hwsup(clkdm);
- } else {
- clkdm_sleep(clkdm);
- }
+ if (arch_clkdm && arch_clkdm->clkdm_clk_disable)
+ arch_clkdm->clkdm_clk_disable(clkdm);
pwrdm_clkdm_state_switch(clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index fe220f7..c1cd1cd 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -175,8 +175,8 @@ void clkdm_deny_idle(struct clockdomain *clkdm);
int clkdm_wakeup(struct clockdomain *clkdm);
int clkdm_sleep(struct clockdomain *clkdm);
-int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
-int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
+int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
+int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
extern void __init omap2xxx_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 2bc9970..5104601 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -136,6 +136,71 @@ static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
_clkdm_del_autodeps(clkdm);
}
+static void _enable_hwsup(struct clockdomain *clkdm)
+{
+ if (cpu_is_omap24xx())
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap34xx())
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void _disable_hwsup(struct clockdomain *clkdm)
+{
+ if (cpu_is_omap24xx())
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap34xx())
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+
+static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ _disable_hwsup(clkdm);
+ _clkdm_add_autodeps(clkdm);
+ _enable_hwsup(clkdm);
+ } else {
+ clkdm_wakeup(clkdm);
+ }
+
+ return 0;
+}
+
+static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ _disable_hwsup(clkdm);
+ _clkdm_del_autodeps(clkdm);
+ _enable_hwsup(clkdm);
+ } else {
+ clkdm_sleep(clkdm);
+ }
+
+ return 0;
+}
+
static int omap3_clkdm_sleep(struct clockdomain *clkdm)
{
omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
@@ -181,6 +246,8 @@ struct clkdm_ops omap2_clkdm_operations = {
.clkdm_wakeup = omap2_clkdm_wakeup,
.clkdm_allow_idle = omap2_clkdm_allow_idle,
.clkdm_deny_idle = omap2_clkdm_deny_idle,
+ .clkdm_clk_enable = omap2_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2_clkdm_clk_disable,
};
struct clkdm_ops omap3_clkdm_operations = {
@@ -196,4 +263,6 @@ struct clkdm_ops omap3_clkdm_operations = {
.clkdm_wakeup = omap3_clkdm_wakeup,
.clkdm_allow_idle = omap3_clkdm_allow_idle,
.clkdm_deny_idle = omap3_clkdm_deny_idle,
+ .clkdm_clk_enable = omap2_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2_clkdm_clk_disable,
};
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index a46125f..c0ccc47 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -41,9 +41,37 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
clkdm->cm_inst, clkdm->clkdm_offs);
}
+static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup)
+ clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup)
+ clkdm_sleep(clkdm);
+
+ return 0;
+}
+
struct clkdm_ops omap4_clkdm_operations = {
.clkdm_sleep = omap4_clkdm_sleep,
.clkdm_wakeup = omap4_clkdm_wakeup,
.clkdm_allow_idle = omap4_clkdm_allow_idle,
.clkdm_deny_idle = omap4_clkdm_deny_idle,
+ .clkdm_clk_enable = omap4_clkdm_clk_enable,
+ .clkdm_clk_disable = omap4_clkdm_clk_disable,
};
--
1.7.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
2011-01-05 14:22 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Rajendra Nayak
2011-01-05 14:22 ` [PATCH 3/5] OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm Rajendra Nayak
@ 2011-01-11 1:05 ` Paul Walmsley
2011-01-11 14:22 ` Rajendra Nayak
2011-01-11 1:32 ` Paul Walmsley
2 siblings, 1 reply; 12+ messages in thread
From: Paul Walmsley @ 2011-01-11 1:05 UTC (permalink / raw)
To: Rajendra Nayak; +Cc: linux-omap, khilman, b-cousson
Hi Rajendra
On Wed, 5 Jan 2011, Rajendra Nayak wrote:
> Define the following architecture specific funtions for omap2/3
> .clkdm_add_wkdep
> .clkdm_del_wkdep
> .clkdm_read_wkdep
> .clkdm_clear_all_wkdeps
> .clkdm_add_sleepdep
> .clkdm_del_sleepdep
> .clkdm_read_sleepdep
> .clkdm_clear_all_sleepdeps
>
> Convert the platform-independent framework to call these functions.
> With this also move the clkdm lookups for all wkdep_srcs and
> sleepdep_srcs at clkdm_init.
>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> ---
> arch/arm/mach-omap2/Makefile | 2 +
> arch/arm/mach-omap2/clockdomain.c | 80 ++++++---------
> arch/arm/mach-omap2/clockdomain.h | 2 +
> arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 113 ++++++++++++++++++++++
> arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 2 +-
> 5 files changed, 150 insertions(+), 49 deletions(-)
> create mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 4ab82f6..d28db0a 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -102,8 +102,10 @@ obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \
>
> # PRCM clockdomain control
> obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
> + clockdomain2xxx_3xxx.o \
> clockdomains2xxx_3xxx_data.o
> obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
> + clockdomain2xxx_3xxx.o \
> clockdomains2xxx_3xxx_data.o
> obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
> clockdomains44xx_data.o
> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
> index 3e40184..c32480c 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -308,6 +308,7 @@ void clkdm_init(struct clockdomain **clkdms,
> struct clockdomain **c = NULL;
> struct clockdomain *clkdm;
> struct clkdm_autodep *autodep = NULL;
> + struct clkdm_dep *cd;
>
> if (!custom_funcs)
> WARN(1, "No custom clkdm functions registered\n");
> @@ -333,7 +334,18 @@ void clkdm_init(struct clockdomain **clkdms,
> else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
> omap2_clkdm_deny_idle(clkdm);
>
> + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> + if (!omap_chip_is(cd->omap_chip))
> + continue;
> + cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> + }
> clkdm_clear_all_wkdeps(clkdm);
> +
> + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> + if (!omap_chip_is(cd->omap_chip))
> + continue;
> + cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> + }
> clkdm_clear_all_sleepdeps(clkdm);
> }
> }
> @@ -445,8 +457,8 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> pr_debug("clockdomain: hardware will wake up %s when %s wakes "
> "up\n", clkdm1->name, clkdm2->name);
>
> - omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> - clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> + if (arch_clkdm && arch_clkdm->clkdm_add_wkdep)
> + arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
Putting this test inside the loop doesn't make sense to me; arch_clkdm and
arch_clkdm->clkdm_* only need to be tested once outside the loop. Please
do somtehing like this instead:
cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
if (IS_ERR(cd))
ret = PTR_ERR(cd);
if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
ret = -EINVAL;
if (ret) {
pr_debug("clockdomain: hardware cannot set/clear wake up of "
"%s when %s wakes up\n", clkdm1->name, clkdm2->name);
return ret;
}
if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
pr_debug("clockdomain: hardware will wake up %s when %s wakes "
"up\n", clkdm1->name, clkdm2->name);
arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
}
As in the above code, we should probably return an error if the function
pointers don't exist. That should allow us to get rid of the
if (!cpu_is_omap34xx())
return -EINVAL;
tests in the sleepdep functions, since that can now be handled by just
leaving those function pointers NULL; see the below comments.
These comments also apply to most of the other functions here.
> @@ -480,8 +492,8 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> pr_debug("clockdomain: hardware will no longer wake up %s "
> "after %s wakes up\n", clkdm1->name, clkdm2->name);
>
> - omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> - clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> + if (arch_clkdm && arch_clkdm->clkdm_del_wkdep)
> + arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
> }
>
> return 0;
> @@ -516,8 +528,10 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> }
>
> /* XXX It's faster to return the atomic wkdep_usecount */
> - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
> - (1 << clkdm2->dep_bit));
> + if (arch_clkdm && arch_clkdm->clkdm_read_wkdep)
> + return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
> +
> + return -EINVAL;
> }
>
> /**
> @@ -532,25 +546,11 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> */
> int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> {
> - struct clkdm_dep *cd;
> - u32 mask = 0;
> -
> if (!clkdm)
> return -EINVAL;
>
> - for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> - if (!omap_chip_is(cd->omap_chip))
> - continue;
> -
> - if (!cd->clkdm && cd->clkdm_name)
> - cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> -
> - /* PRM accesses are slow, so minimize them */
> - mask |= 1 << cd->clkdm->dep_bit;
> - atomic_set(&cd->wkdep_usecount, 0);
> - }
> -
> - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP);
> + if (arch_clkdm && arch_clkdm->clkdm_clear_all_wkdeps)
> + arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
>
> return 0;
> }
> @@ -589,9 +589,8 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> pr_debug("clockdomain: will prevent %s from sleeping if %s "
> "is active\n", clkdm1->name, clkdm2->name);
>
> - omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> - clkdm1->pwrdm.ptr->prcm_offs,
> - OMAP3430_CM_SLEEPDEP);
> + if (arch_clkdm && arch_clkdm->clkdm_add_sleepdep)
> + arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
> }
>
> return 0;
> @@ -632,9 +631,8 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> "sleeping if %s is active\n", clkdm1->name,
> clkdm2->name);
>
> - omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> - clkdm1->pwrdm.ptr->prcm_offs,
> - OMAP3430_CM_SLEEPDEP);
> + if (arch_clkdm && arch_clkdm->clkdm_del_sleepdep)
> + arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
> }
>
> return 0;
> @@ -675,9 +673,10 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> }
>
> /* XXX It's faster to return the atomic sleepdep_usecount */
> - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> - OMAP3430_CM_SLEEPDEP,
> - (1 << clkdm2->dep_bit));
> + if (arch_clkdm && arch_clkdm->clkdm_read_sleepdep)
> + return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
> +
> + return -EINVAL;
> }
>
> /**
> @@ -692,29 +691,14 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
> */
> int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> {
> - struct clkdm_dep *cd;
> - u32 mask = 0;
> -
> if (!cpu_is_omap34xx())
> return -EINVAL;
>
> if (!clkdm)
> return -EINVAL;
>
> - for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> - if (!omap_chip_is(cd->omap_chip))
> - continue;
> -
> - if (!cd->clkdm && cd->clkdm_name)
> - cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> -
> - /* PRM accesses are slow, so minimize them */
> - mask |= 1 << cd->clkdm->dep_bit;
> - atomic_set(&cd->sleepdep_usecount, 0);
> - }
> -
> - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> - OMAP3430_CM_SLEEPDEP);
> + if (arch_clkdm && arch_clkdm->clkdm_clear_all_sleepdeps)
> + arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
>
> return 0;
> }
> diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
> index 346efa2..a9cda27 100644
> --- a/arch/arm/mach-omap2/clockdomain.h
> +++ b/arch/arm/mach-omap2/clockdomain.h
> @@ -181,4 +181,6 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
> extern void __init omap2_clockdomains_init(void);
> extern void __init omap44xx_clockdomains_init(void);
>
> +extern struct clkdm_ops omap2_clkdm_operations;
> +
> #endif
> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> new file mode 100644
> index 0000000..a7303bd
> --- /dev/null
> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> @@ -0,0 +1,113 @@
> +/*
> + * OMAP2 and OMAP3 clockdomain control
> + *
> + * Copyright (C) 2008-2010 Texas Instruments, Inc.
> + * Copyright (C) 2008-2010 Nokia Corporation
> + *
> + * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
> + * Rajendra Nayak <rnayak@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/types.h>
> +#include <plat/prcm.h>
> +#include "prm.h"
> +#include "prm2xxx_3xxx.h"
> +#include "cm.h"
> +#include "cm2xxx_3xxx.h"
> +#include "cm-regbits-24xx.h"
> +#include "cm-regbits-34xx.h"
> +#include "clockdomain.h"
> +
> +static void omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> + struct clockdomain *clkdm2)
> +{
> + omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> +}
> +
> +static void omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> + struct clockdomain *clkdm2)
> +{
> + omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> +}
> +
> +static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> + struct clockdomain *clkdm2)
> +{
> + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> + PM_WKDEP, (1 << clkdm2->dep_bit));
> +}
> +
> +static void omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> +{
> + struct clkdm_dep *cd;
> + u32 mask = 0;
> +
> + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> + if (!omap_chip_is(cd->omap_chip))
> + continue;
> +
> + /* PRM accesses are slow, so minimize them */
> + mask |= 1 << cd->clkdm->dep_bit;
> + atomic_set(&cd->wkdep_usecount, 0);
> + }
> +
> + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> + PM_WKDEP);
> +}
> +
> +static void omap2_clkdm_add_sleepdep(struct clockdomain *clkdm1,
> + struct clockdomain *clkdm2)
> +{
> + omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> + clkdm1->pwrdm.ptr->prcm_offs,
> + OMAP3430_CM_SLEEPDEP);
> +}
OMAP2xxx didn't support software-controlled sleepdeps, so this should not
be present (note the 'OMAP3430' in the OMAP3430_CM_SLEEPDEP macro).
> +
> +static void omap2_clkdm_del_sleepdep(struct clockdomain *clkdm1,
> + struct clockdomain *clkdm2)
> +{
> + omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> + clkdm1->pwrdm.ptr->prcm_offs,
> + OMAP3430_CM_SLEEPDEP);
> +}
as above
> +
> +static int omap2_clkdm_read_sleepdep(struct clockdomain *clkdm1,
> + struct clockdomain *clkdm2)
> +{
> + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> + OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
> +}
as above
> +
> +static void omap2_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> +{
> + struct clkdm_dep *cd;
> + u32 mask = 0;
> +
> + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> + if (!omap_chip_is(cd->omap_chip))
> + continue;
> +
> + /* PRM accesses are slow, so minimize them */
> + mask |= 1 << cd->clkdm->dep_bit;
> + atomic_set(&cd->sleepdep_usecount, 0);
> + }
> + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> + OMAP3430_CM_SLEEPDEP);
> +}
as above
> +
> +struct clkdm_ops omap2_clkdm_operations = {
> + .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
> + .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
> + .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
> + .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
> + .clkdm_add_sleepdep = omap2_clkdm_add_sleepdep,
> + .clkdm_del_sleepdep = omap2_clkdm_del_sleepdep,
> + .clkdm_read_sleepdep = omap2_clkdm_read_sleepdep,
> + .clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
These four function pointers should not be present. OMAP2xxx did not
support software-controlled sleepdeps. You'll probably need to add
omap3_clkdm_operations in this patch.
> +};
> diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
> index 8cab07a..ba0bbbd 100644
> --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
> +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
> @@ -856,5 +856,5 @@ static struct clockdomain *clockdomains_omap2[] __initdata = {
>
> void __init omap2_clockdomains_init(void)
> {
> - clkdm_init(clockdomains_omap2, clkdm_autodeps, NULL);
> + clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations);
> }
> --
> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
- Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
2011-01-05 14:22 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Rajendra Nayak
2011-01-05 14:22 ` [PATCH 3/5] OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm Rajendra Nayak
2011-01-11 1:05 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Paul Walmsley
@ 2011-01-11 1:32 ` Paul Walmsley
2011-01-11 14:20 ` Rajendra Nayak
2 siblings, 1 reply; 12+ messages in thread
From: Paul Walmsley @ 2011-01-11 1:32 UTC (permalink / raw)
To: Rajendra Nayak; +Cc: linux-omap, khilman, b-cousson
On Wed, 5 Jan 2011, Rajendra Nayak wrote:
> Define the following architecture specific funtions for omap2/3
> .clkdm_add_wkdep
> .clkdm_del_wkdep
> .clkdm_read_wkdep
> .clkdm_clear_all_wkdeps
> .clkdm_add_sleepdep
> .clkdm_del_sleepdep
> .clkdm_read_sleepdep
> .clkdm_clear_all_sleepdeps
>
> Convert the platform-independent framework to call these functions.
> With this also move the clkdm lookups for all wkdep_srcs and
> sleepdep_srcs at clkdm_init.
>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> ---
> arch/arm/mach-omap2/Makefile | 2 +
> arch/arm/mach-omap2/clockdomain.c | 80 ++++++---------
> arch/arm/mach-omap2/clockdomain.h | 2 +
> arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 113 ++++++++++++++++++++++
> arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 2 +-
This is definitely a good start, but a lot of OMAP4 stuff still needs
to be done.
For example, OMAP4 has static wakeup dependencies just like OMAP2/3;
described in section 3.1.1.1.7.3 "Wake-Up Dependency" of the OMAP4430 TRM
Rev. L.
OMAP4 also has static sleep dependencies just like OMAP3; described in
section 3.1.1.1.7.1 "Static Dependency" of the OMAP4430 TRM
Rev. L.
The dynamic wakeup dependencies (section 3.1.1.1.7.2 of the TRM) and the
hardware inactivity timer are new for OMAP4.
What's the plan to add support for these?
Based on a brief look, it would seem to make sense to add support now for
static sleep dependencies. These seem quite similar to the OMAP3
implementation, in that they are between clockdomains.
Dynamic wakeup dependencies and the prescaler timer configuration should
be fairly easy to add since it is a new feature, and thus no OMAP2/3
implementation is needed. The dyndep stuff is between clockdomains, so
there shouldn't be any interaction needed with the hwmod code by my
reading.
Static wakeup dependency support appears a little more tricky, since the
dependencies are between modules and clockdomains on OMAP4, rather than
between clockdomains and clockdomains as they were on OMAP2/3. One way to
handle this would be to change the existing wkdep interface for all OMAPs
to be between modules and clockdomains; then for the OMAP2/3
implementations, use the hwmod code/data to get the clockdomain of the
module's main_clk. Another is to add a separate interface to add wkdeps
between a module and clockdomain, use that for OMAP4, but use the existing
clockdomain-to-clockdomain interface for OMAP2/3. It might be necessary
to do both until the hwmod data is more complete, then perhaps phase out
the latter interface. Thoughts?
- Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
2011-01-11 1:32 ` Paul Walmsley
@ 2011-01-11 14:20 ` Rajendra Nayak
2011-01-14 6:20 ` Paul Walmsley
0 siblings, 1 reply; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-11 14:20 UTC (permalink / raw)
To: Paul Walmsley; +Cc: linux-omap, khilman, Benoit Cousson
Hi Paul,
> -----Original Message-----
> From: Paul Walmsley [mailto:paul@pwsan.com]
> Sent: Tuesday, January 11, 2011 7:02 AM
> To: Rajendra Nayak
> Cc: linux-omap@vger.kernel.org; khilman@deeprootsystems.com;
b-cousson@ti.com
> Subject: Re: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to
handle deps
>
> On Wed, 5 Jan 2011, Rajendra Nayak wrote:
>
> > Define the following architecture specific funtions for omap2/3
> > .clkdm_add_wkdep
> > .clkdm_del_wkdep
> > .clkdm_read_wkdep
> > .clkdm_clear_all_wkdeps
> > .clkdm_add_sleepdep
> > .clkdm_del_sleepdep
> > .clkdm_read_sleepdep
> > .clkdm_clear_all_sleepdeps
> >
> > Convert the platform-independent framework to call these functions.
> > With this also move the clkdm lookups for all wkdep_srcs and
> > sleepdep_srcs at clkdm_init.
> >
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > ---
> > arch/arm/mach-omap2/Makefile | 2 +
> > arch/arm/mach-omap2/clockdomain.c | 80
++++++---------
> > arch/arm/mach-omap2/clockdomain.h | 2 +
> > arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 113
++++++++++++++++++++++
> > arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 2 +-
>
> This is definitely a good start, but a lot of OMAP4 stuff still needs
> to be done.
>
> For example, OMAP4 has static wakeup dependencies just like OMAP2/3;
> described in section 3.1.1.1.7.3 "Wake-Up Dependency" of the OMAP4430
TRM
> Rev. L.
>
> OMAP4 also has static sleep dependencies just like OMAP3; described in
> section 3.1.1.1.7.1 "Static Dependency" of the OMAP4430 TRM
> Rev. L.
I already have some patches to support static dependencies for OMAP4.
Still working towards getting the autogen scripts in place, they seem to
be a bit out of sync with whats in mainline today for clockdomains.
I can post early patches as RFC to get your views on it.
The only difference wrt OMAP3 is there is no control on OMAP4 to
set/clear sleep and wakeup dependencies separately and hence
they are called Static dependency and not 'Static wakeup' or 'Static
sleep'.
Setting a static dependency between clock domains on OMAP4 means setting
sleep *as well as* wakeup dependency.
>
> The dynamic wakeup dependencies (section 3.1.1.1.7.2 of the TRM) and the
> hardware inactivity timer are new for OMAP4.
>
> What's the plan to add support for these?
I will be working on supporting these as well. Can be supported easily on
top
of the clockdomain split series. Still need to get the autogen scripts
updated
to generate the dynamic dependency data.
>
> Based on a brief look, it would seem to make sense to add support now
for
> static sleep dependencies. These seem quite similar to the OMAP3
> implementation, in that they are between clockdomains.
Again like I said above, my next patch series will add support for static
(sleep
and wakeup) dependencies. The other 'wakeup dependency' that the TRM
section 3.1.1.1.7.3 talks about is slightly different. See my comments
below.
>
> Dynamic wakeup dependencies and the prescaler timer configuration should
> be fairly easy to add since it is a new feature, and thus no OMAP2/3
> implementation is needed. The dyndep stuff is between clockdomains, so
> there shouldn't be any interaction needed with the hwmod code by my
> reading.
>
> Static wakeup dependency support appears a little more tricky, since the
> dependencies are between modules and clockdomains on OMAP4, rather than
> between clockdomains and clockdomains as they were on OMAP2/3. One way
to
> handle this would be to change the existing wkdep interface for all
OMAPs
> to be between modules and clockdomains; then for the OMAP2/3
> implementations, use the hwmod code/data to get the clockdomain of the
> module's main_clk. Another is to add a separate interface to add wkdeps
> between a module and clockdomain, use that for OMAP4, but use the
existing
> clockdomain-to-clockdomain interface for OMAP2/3. It might be necessary
> to do both until the hwmod data is more complete, then perhaps phase out
> the latter interface. Thoughts?
The wakeup dependency here (between a module and a clock domain)
is very different from the static dependency (between clock domains) and
is
very much like what the PM_<processor>_GRPSEL registers handled in OMAP3.
They are used to control which processor is woken up on a given module/
peripheral wakeup event. I have not given much thought on this for now but
looks like this needs to be handled in some way using hwmod itself.
I need to work some more to see how this can be handled.
Regards,
Rajendra
>
>
> - Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
2011-01-11 1:05 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Paul Walmsley
@ 2011-01-11 14:22 ` Rajendra Nayak
0 siblings, 0 replies; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-11 14:22 UTC (permalink / raw)
To: Paul Walmsley; +Cc: linux-omap, khilman, Benoit Cousson
Hi Paul,
> -----Original Message-----
> From: Paul Walmsley [mailto:paul@pwsan.com]
> Sent: Tuesday, January 11, 2011 6:36 AM
> To: Rajendra Nayak
> Cc: linux-omap@vger.kernel.org; khilman@deeprootsystems.com;
b-cousson@ti.com
> Subject: Re: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to
handle deps
>
> Hi Rajendra
>
> On Wed, 5 Jan 2011, Rajendra Nayak wrote:
>
> > Define the following architecture specific funtions for omap2/3
> > .clkdm_add_wkdep
> > .clkdm_del_wkdep
> > .clkdm_read_wkdep
> > .clkdm_clear_all_wkdeps
> > .clkdm_add_sleepdep
> > .clkdm_del_sleepdep
> > .clkdm_read_sleepdep
> > .clkdm_clear_all_sleepdeps
> >
> > Convert the platform-independent framework to call these functions.
> > With this also move the clkdm lookups for all wkdep_srcs and
> > sleepdep_srcs at clkdm_init.
> >
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > ---
> > arch/arm/mach-omap2/Makefile | 2 +
> > arch/arm/mach-omap2/clockdomain.c | 80
++++++---------
> > arch/arm/mach-omap2/clockdomain.h | 2 +
> > arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 113
++++++++++++++++++++++
> > arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 2 +-
> > 5 files changed, 150 insertions(+), 49 deletions(-)
> > create mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> >
> > diff --git a/arch/arm/mach-omap2/Makefile
b/arch/arm/mach-omap2/Makefile
> > index 4ab82f6..d28db0a 100644
> > --- a/arch/arm/mach-omap2/Makefile
> > +++ b/arch/arm/mach-omap2/Makefile
> > @@ -102,8 +102,10 @@ obj-$(CONFIG_ARCH_OMAP4) +=
$(powerdomain-common) \
> >
> > # PRCM clockdomain control
> > obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
> > + clockdomain2xxx_3xxx.o \
> > clockdomains2xxx_3xxx_data.o
> > obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
> > + clockdomain2xxx_3xxx.o \
> > clockdomains2xxx_3xxx_data.o
> > obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
> > clockdomains44xx_data.o
> > diff --git a/arch/arm/mach-omap2/clockdomain.c
b/arch/arm/mach-omap2/clockdomain.c
> > index 3e40184..c32480c 100644
> > --- a/arch/arm/mach-omap2/clockdomain.c
> > +++ b/arch/arm/mach-omap2/clockdomain.c
> > @@ -308,6 +308,7 @@ void clkdm_init(struct clockdomain **clkdms,
> > struct clockdomain **c = NULL;
> > struct clockdomain *clkdm;
> > struct clkdm_autodep *autodep = NULL;
> > + struct clkdm_dep *cd;
> >
> > if (!custom_funcs)
> > WARN(1, "No custom clkdm functions registered\n");
> > @@ -333,7 +334,18 @@ void clkdm_init(struct clockdomain **clkdms,
> > else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
> > omap2_clkdm_deny_idle(clkdm);
> >
> > + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > + cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > + }
> > clkdm_clear_all_wkdeps(clkdm);
> > +
> > + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name;
cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > + cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > + }
> > clkdm_clear_all_sleepdeps(clkdm);
> > }
> > }
> > @@ -445,8 +457,8 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > pr_debug("clockdomain: hardware will wake up %s when %s
wakes "
> > "up\n", clkdm1->name, clkdm2->name);
> >
> > - omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
PM_WKDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_add_wkdep)
> > + arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
>
> Putting this test inside the loop doesn't make sense to me; arch_clkdm
and
> arch_clkdm->clkdm_* only need to be tested once outside the loop.
Please
> do somtehing like this instead:
Sure, will do the changes.
>
> cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
> if (IS_ERR(cd))
> ret = PTR_ERR(cd);
>
> if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
> ret = -EINVAL;
>
> if (ret) {
> pr_debug("clockdomain: hardware cannot set/clear wake up
of "
> "%s when %s wakes up\n", clkdm1->name,
clkdm2->name);
> return ret;
> }
>
> if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
> pr_debug("clockdomain: hardware will wake up %s when %s
wakes "
> "up\n", clkdm1->name, clkdm2->name);
>
> arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
> }
>
> As in the above code, we should probably return an error if the function
> pointers don't exist. That should allow us to get rid of the
>
> if (!cpu_is_omap34xx())
> return -EINVAL;
>
> tests in the sleepdep functions, since that can now be handled by just
> leaving those function pointers NULL; see the below comments.
>
> These comments also apply to most of the other functions here.
>
> > @@ -480,8 +492,8 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > pr_debug("clockdomain: hardware will no longer wake up %s
"
> > "after %s wakes up\n", clkdm1->name,
clkdm2->name);
> >
> > - omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
PM_WKDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_del_wkdep)
> > + arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
> > }
> >
> > return 0;
> > @@ -516,8 +528,10 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > }
> >
> > /* XXX It's faster to return the atomic wkdep_usecount */
> > - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
PM_WKDEP,
> > - (1 << clkdm2->dep_bit));
> > + if (arch_clkdm && arch_clkdm->clkdm_read_wkdep)
> > + return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
> > +
> > + return -EINVAL;
> > }
> >
> > /**
> > @@ -532,25 +546,11 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > */
> > int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> > {
> > - struct clkdm_dep *cd;
> > - u32 mask = 0;
> > -
> > if (!clkdm)
> > return -EINVAL;
> >
> > - for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> > - if (!omap_chip_is(cd->omap_chip))
> > - continue;
> > -
> > - if (!cd->clkdm && cd->clkdm_name)
> > - cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > -
> > - /* PRM accesses are slow, so minimize them */
> > - mask |= 1 << cd->clkdm->dep_bit;
> > - atomic_set(&cd->wkdep_usecount, 0);
> > - }
> > -
> > - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
PM_WKDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_clear_all_wkdeps)
> > + arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
> >
> > return 0;
> > }
> > @@ -589,9 +589,8 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > pr_debug("clockdomain: will prevent %s from sleeping if %s
"
> > "is active\n", clkdm1->name, clkdm2->name);
> >
> > - omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_add_sleepdep)
> > + arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
> > }
> >
> > return 0;
> > @@ -632,9 +631,8 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1,
struct clockdomain *clkdm2)
> > "sleeping if %s is active\n", clkdm1->name,
> > clkdm2->name);
> >
> > - omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > - clkdm1->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_del_sleepdep)
> > + arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
> > }
> >
> > return 0;
> > @@ -675,9 +673,10 @@ int clkdm_read_sleepdep(struct clockdomain
*clkdm1, struct clockdomain *clkdm2)
> > }
> >
> > /* XXX It's faster to return the atomic sleepdep_usecount */
> > - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP,
> > - (1 << clkdm2->dep_bit));
> > + if (arch_clkdm && arch_clkdm->clkdm_read_sleepdep)
> > + return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
> > +
> > + return -EINVAL;
> > }
> >
> > /**
> > @@ -692,29 +691,14 @@ int clkdm_read_sleepdep(struct clockdomain
*clkdm1, struct clockdomain *clkdm2)
> > */
> > int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> > {
> > - struct clkdm_dep *cd;
> > - u32 mask = 0;
> > -
> > if (!cpu_is_omap34xx())
> > return -EINVAL;
> >
> > if (!clkdm)
> > return -EINVAL;
> >
> > - for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> > - if (!omap_chip_is(cd->omap_chip))
> > - continue;
> > -
> > - if (!cd->clkdm && cd->clkdm_name)
> > - cd->clkdm = _clkdm_lookup(cd->clkdm_name);
> > -
> > - /* PRM accesses are slow, so minimize them */
> > - mask |= 1 << cd->clkdm->dep_bit;
> > - atomic_set(&cd->sleepdep_usecount, 0);
> > - }
> > -
> > - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> > - OMAP3430_CM_SLEEPDEP);
> > + if (arch_clkdm && arch_clkdm->clkdm_clear_all_sleepdeps)
> > + arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
> >
> > return 0;
> > }
> > diff --git a/arch/arm/mach-omap2/clockdomain.h
b/arch/arm/mach-omap2/clockdomain.h
> > index 346efa2..a9cda27 100644
> > --- a/arch/arm/mach-omap2/clockdomain.h
> > +++ b/arch/arm/mach-omap2/clockdomain.h
> > @@ -181,4 +181,6 @@ int omap2_clkdm_clk_disable(struct clockdomain
*clkdm, struct clk *clk);
> > extern void __init omap2_clockdomains_init(void);
> > extern void __init omap44xx_clockdomains_init(void);
> >
> > +extern struct clkdm_ops omap2_clkdm_operations;
> > +
> > #endif
> > diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> > new file mode 100644
> > index 0000000..a7303bd
> > --- /dev/null
> > +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> > @@ -0,0 +1,113 @@
> > +/*
> > + * OMAP2 and OMAP3 clockdomain control
> > + *
> > + * Copyright (C) 2008-2010 Texas Instruments, Inc.
> > + * Copyright (C) 2008-2010 Nokia Corporation
> > + *
> > + * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
> > + * Rajendra Nayak <rnayak@ti.com>
> > + *
> > + * This program is free software; you can redistribute it and/or
modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/types.h>
> > +#include <plat/prcm.h>
> > +#include "prm.h"
> > +#include "prm2xxx_3xxx.h"
> > +#include "cm.h"
> > +#include "cm2xxx_3xxx.h"
> > +#include "cm-regbits-24xx.h"
> > +#include "cm-regbits-34xx.h"
> > +#include "clockdomain.h"
> > +
> > +static void omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> > +}
> > +
> > +static void omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> > +}
> > +
> > +static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> > + PM_WKDEP, (1 << clkdm2->dep_bit));
> > +}
> > +
> > +static void omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> > +{
> > + struct clkdm_dep *cd;
> > + u32 mask = 0;
> > +
> > + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > +
> > + /* PRM accesses are slow, so minimize them */
> > + mask |= 1 << cd->clkdm->dep_bit;
> > + atomic_set(&cd->wkdep_usecount, 0);
> > + }
> > +
> > + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> > + PM_WKDEP);
> > +}
> > +
> > +static void omap2_clkdm_add_sleepdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP);
> > +}
>
> OMAP2xxx didn't support software-controlled sleepdeps, so this should
not
> be present (note the 'OMAP3430' in the OMAP3430_CM_SLEEPDEP macro).
Yup, realized after I sent the patches out. Will fix them in V2.
Thanks
Rajendra
>
> > +
> > +static void omap2_clkdm_del_sleepdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> > + clkdm1->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP);
> > +}
>
> as above
>
> > +
> > +static int omap2_clkdm_read_sleepdep(struct clockdomain *clkdm1,
> > + struct clockdomain
*clkdm2)
> > +{
> > + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP, (1 <<
clkdm2->dep_bit));
> > +}
>
> as above
>
> > +
> > +static void omap2_clkdm_clear_all_sleepdeps(struct clockdomain
*clkdm)
> > +{
> > + struct clkdm_dep *cd;
> > + u32 mask = 0;
> > +
> > + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> > + if (!omap_chip_is(cd->omap_chip))
> > + continue;
> > +
> > + /* PRM accesses are slow, so minimize them */
> > + mask |= 1 << cd->clkdm->dep_bit;
> > + atomic_set(&cd->sleepdep_usecount, 0);
> > + }
> > + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> > + OMAP3430_CM_SLEEPDEP);
> > +}
>
> as above
>
> > +
> > +struct clkdm_ops omap2_clkdm_operations = {
> > + .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
> > + .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
> > + .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
> > + .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
> > + .clkdm_add_sleepdep = omap2_clkdm_add_sleepdep,
> > + .clkdm_del_sleepdep = omap2_clkdm_del_sleepdep,
> > + .clkdm_read_sleepdep = omap2_clkdm_read_sleepdep,
> > + .clkdm_clear_all_sleepdeps = omap2_clkdm_clear_all_sleepdeps,
>
> These four function pointers should not be present. OMAP2xxx did not
> support software-controlled sleepdeps. You'll probably need to add
> omap3_clkdm_operations in this patch.
>
> > +};
> > diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
b/arch/arm/mach-
> omap2/clockdomains2xxx_3xxx_data.c
> > index 8cab07a..ba0bbbd 100644
> > --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
> > +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
> > @@ -856,5 +856,5 @@ static struct clockdomain *clockdomains_omap2[]
__initdata = {
> >
> > void __init omap2_clockdomains_init(void)
> > {
> > - clkdm_init(clockdomains_omap2, clkdm_autodeps, NULL);
> > + clkdm_init(clockdomains_omap2, clkdm_autodeps,
&omap2_clkdm_operations);
> > }
> > --
> > 1.7.0.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-omap"
in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
>
>
> - Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
2011-01-11 14:20 ` Rajendra Nayak
@ 2011-01-14 6:20 ` Paul Walmsley
2011-01-19 11:01 ` Rajendra Nayak
0 siblings, 1 reply; 12+ messages in thread
From: Paul Walmsley @ 2011-01-14 6:20 UTC (permalink / raw)
To: Rajendra Nayak; +Cc: linux-omap, khilman, Benoit Cousson, Rene Sapiens
[-- Attachment #1: Type: TEXT/PLAIN, Size: 4436 bytes --]
(adding René to cc)
Hi Rajendra
On Tue, 11 Jan 2011, Rajendra Nayak wrote:
> > -----Original Message-----
> > From: Paul Walmsley [mailto:paul@pwsan.com]
> > Sent: Tuesday, January 11, 2011 7:02 AM
> > To: Rajendra Nayak
> > Cc: linux-omap@vger.kernel.org; khilman@deeprootsystems.com;
> b-cousson@ti.com
> > Subject: Re: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to
> handle deps
> >
> > For example, OMAP4 has static wakeup dependencies just like OMAP2/3;
> > described in section 3.1.1.1.7.3 "Wake-Up Dependency" of the OMAP4430
> TRM
> > Rev. L.
> >
> > OMAP4 also has static sleep dependencies just like OMAP3; described in
> > section 3.1.1.1.7.1 "Static Dependency" of the OMAP4430 TRM
> > Rev. L.
>
> I already have some patches to support static dependencies for OMAP4.
> Still working towards getting the autogen scripts in place, they seem to
> be a bit out of sync with whats in mainline today for clockdomains.
> I can post early patches as RFC to get your views on it.
OK, great - saw that you posted these. Will take a closer look.
> The only difference wrt OMAP3 is there is no control on OMAP4 to
> set/clear sleep and wakeup dependencies separately and hence they are
> called Static dependency and not 'Static wakeup' or 'Static sleep'.
> Setting a static dependency between clock domains on OMAP4 means setting
> sleep *as well as* wakeup dependency.
OK. The design of your initial implementation of these combined
sleep/wakeup dependencies in the RFC series looks good to me.
> > The dynamic wakeup dependencies (section 3.1.1.1.7.2 of the TRM) and the
> > hardware inactivity timer are new for OMAP4.
> >
> > What's the plan to add support for these?
>
> I will be working on supporting these as well. Can be supported easily
> on top of the clockdomain split series. Still need to get the autogen
> scripts updated to generate the dynamic dependency data.
OK, sounds good.
> > Based on a brief look, it would seem to make sense to add support now
> > for static sleep dependencies. These seem quite similar to the OMAP3
> > implementation, in that they are between clockdomains.
>
> Again like I said above, my next patch series will add support for
> static (sleep and wakeup) dependencies. The other 'wakeup dependency'
> that the TRM section 3.1.1.1.7.3 talks about is slightly different. See
> my comments below.
OK.
> > Static wakeup dependency support appears a little more tricky, since
> > the dependencies are between modules and clockdomains on OMAP4, rather
> > than between clockdomains and clockdomains as they were on OMAP2/3.
> > One way to handle this would be to change the existing wkdep interface
> > for all OMAPs to be between modules and clockdomains; then for the
> > OMAP2/3 implementations, use the hwmod code/data to get the
> > clockdomain of the module's main_clk. Another is to add a separate
> > interface to add wkdeps between a module and clockdomain, use that for
> > OMAP4, but use the existing clockdomain-to-clockdomain interface for
> > OMAP2/3. It might be necessary to do both until the hwmod data is
> > more complete, then perhaps phase out the latter interface.
> > Thoughts?
>
> The wakeup dependency here (between a module and a clock domain) is very
> different from the static dependency (between clock domains) and very
> much like what the PM_<processor>_GRPSEL registers handled in OMAP3.
> They are used to control which processor is woken up on a given module/
> peripheral wakeup event.
According to the 34xx TRM Rev. ZH section 4.8.5.2, both the GRPSEL and
WKDEP bits need to be set for the target clockdomain to be awakened, if
the target clockdomain contains a 'processor'. I had been under the
impression that these were separate mechanisms. Is this also true for
OMAP4 with the WKUPDEP/STATICDEP bits? The implication in section
3.1.1.1.7.3 is that the WKUPDEP bits are simply there for an
'acceleration'.
> I have not given much thought on this for now but looks like this needs
> to be handled in some way using hwmod itself. I need to work some more
> to see how this can be handled.
OK, that's fine. You might want to touch base with René Sapiens on the
GRPSEL/WKUPDEP stuff, I think he was looking at implementing GRPSEL
control in software.
Thanks for the summary,
- Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps
2011-01-14 6:20 ` Paul Walmsley
@ 2011-01-19 11:01 ` Rajendra Nayak
0 siblings, 0 replies; 12+ messages in thread
From: Rajendra Nayak @ 2011-01-19 11:01 UTC (permalink / raw)
To: Paul Walmsley; +Cc: linux-omap, khilman, Benoit Cousson, Rene Sapiens
Hi Paul,
<..>..
>
> > > Static wakeup dependency support appears a little more tricky, since
> > > the dependencies are between modules and clockdomains on OMAP4,
rather
> > > than between clockdomains and clockdomains as they were on OMAP2/3.
> > > One way to handle this would be to change the existing wkdep
interface
> > > for all OMAPs to be between modules and clockdomains; then for the
> > > OMAP2/3 implementations, use the hwmod code/data to get the
> > > clockdomain of the module's main_clk. Another is to add a separate
> > > interface to add wkdeps between a module and clockdomain, use that
for
> > > OMAP4, but use the existing clockdomain-to-clockdomain interface for
> > > OMAP2/3. It might be necessary to do both until the hwmod data is
> > > more complete, then perhaps phase out the latter interface.
> > > Thoughts?
> >
> > The wakeup dependency here (between a module and a clock domain) is
very
> > different from the static dependency (between clock domains) and very
> > much like what the PM_<processor>_GRPSEL registers handled in OMAP3.
> > They are used to control which processor is woken up on a given
module/
> > peripheral wakeup event.
>
> According to the 34xx TRM Rev. ZH section 4.8.5.2, both the GRPSEL and
> WKDEP bits need to be set for the target clockdomain to be awakened, if
> the target clockdomain contains a 'processor'. I had been under the
> impression that these were separate mechanisms. Is this also true for
> OMAP4 with the WKUPDEP/STATICDEP bits? The implication in section
> 3.1.1.1.7.3 is that the WKUPDEP bits are simply there for an
> 'acceleration'.
Yes, on OMAP4, these are used to accelerate wakeup transition
by parallelizing wakeup on several domains.
Both the func spec and the TRM seem to mention that System would
work *without* them, but with slower wakeup transitions, due to the
cascading of wakeup transition over several domains.
Also Table 3-13 in TRM Section 3.1.1.1.6 mentions the following
conditions OR'ed for a clockdomain Wakeup to happen
The SW_WKUP clock transition mode for the clock domain is set. (CLKTRCTRL
= 0x2)
OR At least one wake-up request asserted by one of the modules of the
clock domain.
OR At least one dynamic dependency(1) from another clock domain is active.
OR At least one static dependency(1) from another clock domain is active.
OR At least one wake-up dependency(1) from a module in another clock
domain is active.
>
> > I have not given much thought on this for now but looks like this
needs
> > to be handled in some way using hwmod itself. I need to work some more
> > to see how this can be handled.
>
> OK, that's fine. You might want to touch base with René Sapiens on the
> GRPSEL/WKUPDEP stuff, I think he was looking at implementing GRPSEL
> control in software.
Sure, will get in touch with him.
Thanks,
Rajendra
>
> Thanks for the summary,
>
>
> - Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-01-19 11:07 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-05 14:22 [PATCH 0/5] Clockdomain split series Rajendra Nayak
2011-01-05 14:22 ` [PATCH 1/5] OMAP: clockdomain: Infrastructure to put arch specific code Rajendra Nayak
2011-01-05 14:22 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Rajendra Nayak
2011-01-05 14:22 ` [PATCH 3/5] OMAP: clockdomain: Arch specific funcs for sleep/wakeup of clkdm Rajendra Nayak
2011-01-05 14:22 ` [PATCH 4/5] OMAP: clockdomain: Arch specific funcs for hwsup control " Rajendra Nayak
2011-01-05 14:22 ` [PATCH 5/5] OMAP: clockdomain: Arch specific funcs for clkdm_clk_enable/disable Rajendra Nayak
2011-01-11 1:05 ` [PATCH 2/5] OMAP: clockdomain: Arch specific funcs to handle deps Paul Walmsley
2011-01-11 14:22 ` Rajendra Nayak
2011-01-11 1:32 ` Paul Walmsley
2011-01-11 14:20 ` Rajendra Nayak
2011-01-14 6:20 ` Paul Walmsley
2011-01-19 11:01 ` Rajendra Nayak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox