aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/omap-pm-interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/omap-pm-interface.c')
-rw-r--r--arch/arm/plat-omap/omap-pm-interface.c251
1 files changed, 251 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/omap-pm-interface.c b/arch/arm/plat-omap/omap-pm-interface.c
new file mode 100644
index 0000000..e166395
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-interface.c
@@ -0,0 +1,251 @@
+/*
+ * omap-pm-interface.c - OMAP power management interface
+ *
+ * This code implements the OMAP power management interface to
+ * drivers, CPUIdle, CPUFreq, and DSP Bridge.
+ *
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
+ * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+/* Interface documentation is in mach/omap-pm.h */
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+
+#include "omap-pm-helper.h"
+#include "../mach-omap2/prm44xx.h"
+
+bool off_mode_enabled;
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ * WARNING: Device drivers need to now use pm_qos directly.
+ */
+int omap_pm_set_max_mpu_wakeup_lat(struct pm_qos_request_list **pmqos_req,
+ long t)
+{
+ WARN(1, "Deprecated %s: Driver should use pm_qos to add request\n",
+ __func__);
+
+ return -EINVAL;
+}
+
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, long r)
+{
+ int ret;
+ if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+ agent_id != OCP_TARGET_AGENT)) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (r == -1)
+ pr_debug("OMAP PM: remove min bus tput constraint: "
+ "dev %s for agent_id %d\n", dev_name(dev), agent_id);
+ else
+ pr_debug("OMAP PM: add min bus tput constraint: "
+ "dev %s for agent_id %d: rate %ld KiB\n",
+ dev_name(dev), agent_id, r);
+
+ ret = omap_pm_set_min_bus_tput_helper(dev, agent_id, r);
+
+ return ret;
+}
+
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+ long t)
+{
+ int ret;
+ if (!req_dev || !dev || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (t == -1)
+ pr_debug("OMAP PM: remove max device latency constraint: "
+ "dev %s\n", dev_name(dev));
+ else
+ pr_debug("OMAP PM: add max device latency constraint: "
+ "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+ ret = omap_pm_set_max_dev_wakeup_lat_helper(req_dev, dev, t);
+
+ return ret;
+}
+
+/* WARNING: Device drivers need to now use pm_qos directly. */
+int omap_pm_set_max_sdma_lat(struct pm_qos_request_list **qos_request, long t)
+{
+ WARN(1, "Deprecated %s: Driver should use pm_qos to add request\n",
+ __func__);
+
+ return -EINVAL;
+}
+
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return -EINVAL;
+}
+
+/*
+ * DSP Bridge-specific constraints
+ * WARNING: Device drivers need to now use opp layer/omap_device_scale directly.
+ */
+const struct omap_opp *omap_pm_dsp_get_opp_table(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return ERR_PTR(-EINVAL);
+}
+
+void omap_pm_dsp_set_min_opp(u8 opp_id)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return;
+}
+
+int omap_pm_set_min_mpu_freq(struct device *dev, unsigned long f)
+{
+ WARN(1, "Deprecated %s: Driver should NOT use this function\n",
+ __func__);
+
+ return -EINVAL;
+
+}
+
+EXPORT_SYMBOL(omap_pm_set_min_mpu_freq);
+
+u8 omap_pm_dsp_get_opp(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return 0;
+}
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return ERR_PTR(-EINVAL);
+}
+
+void omap_pm_cpu_set_freq(unsigned long f)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return;
+}
+
+unsigned long omap_pm_cpu_get_freq(void)
+{
+ WARN(1, "Deprecated %s: Driver should use omap_device_scale/opp\n",
+ __func__);
+
+ return 0;
+}
+
+/**
+ * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been enabled.
+ */
+void omap_pm_enable_off_mode(void)
+{
+ off_mode_enabled = true;
+}
+
+/**
+ * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been disabled.
+ */
+void omap_pm_disable_off_mode(void)
+{
+ off_mode_enabled = false;
+}
+
+bool omap_pm_was_context_lost(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+ struct omap_hwmod *oh;
+
+ if (!dev)
+ goto save_ctx;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = container_of(pdev, struct omap_device, pdev);
+ oh = od->hwmods[0];
+
+ if (!oh || !cpu_is_omap44xx())
+ goto save_ctx;
+
+ if (oh->prcm.omap4.context_reg) {
+ u32 context_reg_val = 0;
+
+ /*Read what context was lost.*/
+ context_reg_val = __raw_readl(oh->prcm.omap4.context_reg);
+
+ /*clear context lost bits after read*/
+ __raw_writel(context_reg_val, oh->prcm.omap4.context_reg);
+
+ /* ABE special case, only report ctx lost when we loose
+ * mem, otherwise, constant firmware reload causes problems.
+ */
+ if (oh->prcm.omap4.context_reg == OMAP4430_RM_ABE_AESS_CONTEXT)
+ context_reg_val &= (1 << 8);
+
+ return (context_reg_val != 0);
+ }
+
+save_ctx:
+ /* by default return true so that driver will restore context*/
+ return true;
+}
+
+/* Should be called before clk framework init */
+int __init omap_pm_if_early_init(void)
+{
+ return 0;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init(void)
+{
+ return omap_pm_if_init_helper();
+}
+
+void omap_pm_if_exit(void)
+{
+ /* Deallocate CPUFreq frequency table here */
+}