|
@@ -1,7 +1,7 @@
|
|
|
/*
|
|
|
- * OMAP4 Power Management Routines
|
|
|
+ * OMAP4+ Power Management Routines
|
|
|
*
|
|
|
- * Copyright (C) 2010-2011 Texas Instruments, Inc.
|
|
|
+ * Copyright (C) 2010-2013 Texas Instruments, Inc.
|
|
|
* Rajendra Nayak <rnayak@ti.com>
|
|
|
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
|
|
*
|
|
@@ -135,16 +135,16 @@ static void omap_default_idle(void)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * omap4_pm_init - Init routine for OMAP4 PM
|
|
|
+ * omap4_init_static_deps - Add OMAP4 static dependencies
|
|
|
*
|
|
|
- * Initializes all powerdomain and clockdomain target states
|
|
|
- * and all PRCM settings.
|
|
|
+ * Add needed static clockdomain dependencies on OMAP4 devices.
|
|
|
+ * Return: 0 on success or 'err' on failures
|
|
|
*/
|
|
|
-int __init omap4_pm_init(void)
|
|
|
+static inline int omap4_init_static_deps(void)
|
|
|
{
|
|
|
- int ret;
|
|
|
struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
|
|
|
struct clockdomain *ducati_clkdm, *l3_2_clkdm;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
if (omap_rev() == OMAP4430_REV_ES1_0) {
|
|
|
WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
|
|
@@ -163,7 +163,7 @@ int __init omap4_pm_init(void)
|
|
|
ret = pwrdm_for_each(pwrdms_setup, NULL);
|
|
|
if (ret) {
|
|
|
pr_err("Failed to setup powerdomains\n");
|
|
|
- goto err2;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -171,6 +171,10 @@ int __init omap4_pm_init(void)
|
|
|
* MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
|
|
|
* expected. The hardware recommendation is to enable static
|
|
|
* dependencies for these to avoid system lock ups or random crashes.
|
|
|
+ * The L4 wakeup depedency is added to workaround the OCP sync hardware
|
|
|
+ * BUG with 32K synctimer which lead to incorrect timer value read
|
|
|
+ * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
|
|
|
+ * are part of L4 wakeup clockdomain.
|
|
|
*/
|
|
|
mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
|
|
|
emif_clkdm = clkdm_lookup("l3_emif_clkdm");
|
|
@@ -179,7 +183,7 @@ int __init omap4_pm_init(void)
|
|
|
ducati_clkdm = clkdm_lookup("ducati_clkdm");
|
|
|
if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
|
|
|
(!l3_2_clkdm) || (!ducati_clkdm))
|
|
|
- goto err2;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
|
|
|
ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
|
|
@@ -188,9 +192,42 @@ int __init omap4_pm_init(void)
|
|
|
ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
|
|
|
if (ret) {
|
|
|
pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * omap4_pm_init - Init routine for OMAP4+ devices
|
|
|
+ *
|
|
|
+ * Initializes all powerdomain and clockdomain target states
|
|
|
+ * and all PRCM settings.
|
|
|
+ * Return: Returns the error code returned by called functions.
|
|
|
+ */
|
|
|
+int __init omap4_pm_init(void)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
|
|
|
+ WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_info("Power Management for TI OMAP4+ devices.\n");
|
|
|
+
|
|
|
+ ret = pwrdm_for_each(pwrdms_setup, NULL);
|
|
|
+ if (ret) {
|
|
|
+ pr_err("Failed to setup powerdomains.\n");
|
|
|
goto err2;
|
|
|
}
|
|
|
|
|
|
+ if (cpu_is_omap44xx()) {
|
|
|
+ ret = omap4_init_static_deps();
|
|
|
+ if (ret)
|
|
|
+ goto err2;
|
|
|
+ }
|
|
|
+
|
|
|
ret = omap4_mpuss_init();
|
|
|
if (ret) {
|
|
|
pr_err("Failed to initialise OMAP4 MPUSS\n");
|
|
@@ -206,7 +243,8 @@ int __init omap4_pm_init(void)
|
|
|
/* Overwrite the default cpu_do_idle() */
|
|
|
arm_pm_idle = omap_default_idle;
|
|
|
|
|
|
- omap4_idle_init();
|
|
|
+ if (cpu_is_omap44xx())
|
|
|
+ omap4_idle_init();
|
|
|
|
|
|
err2:
|
|
|
return ret;
|