The interface provides device drivers, CPUFreq, and DSP Bridge with a means of controlling OMAP power management parameters that are not yet supported by the Linux PM PMQOS interface. Copious documentation and rationale is in the patch in Documentation/arm/OMAP/omap_pm and the interface header file, include/asm-arm/arch-omap/omap-pm.h. Signed-off-by: Paul Walmsley --- Documentation/arm/OMAP/omap_pm | 185 +++++++++++++++++++++ arch/arm/mach-omap2/io.c | 4 arch/arm/plat-omap/Kconfig | 13 + arch/arm/plat-omap/Makefile | 1 arch/arm/plat-omap/omap-pm-noop.c | 309 +++++++++++++++++++++++++++++++++++ include/asm-arm/arch-omap/omap-pm.h | 300 ++++++++++++++++++++++++++++++++++ 6 files changed, 812 insertions(+), 0 deletions(-) create mode 100644 Documentation/arm/OMAP/omap_pm create mode 100644 arch/arm/plat-omap/omap-pm-noop.c create mode 100644 include/asm-arm/arch-omap/omap-pm.h diff --git a/Documentation/arm/OMAP/omap_pm b/Documentation/arm/OMAP/omap_pm new file mode 100644 index 0000000..2ec2034 --- /dev/null +++ b/Documentation/arm/OMAP/omap_pm @@ -0,0 +1,185 @@ + +Rationale: the OMAP PM interface +================================ + + +Existing PM interfaces are currently not ideal for OMAP +------------------------------------------------------- + +There are two PM interfaces in use with publicly-distributed OMAP +Linux code: the TI Shared Resource Framework (SRF) and the Linux PM +QoS parameters code. Neither interface is ideal for Linux OMAP code. + +TI Shared Resource Framework: + +The TI CDP 12.14 tree drivers currently use the TI Shared Resource +Framework (SRF) to control chip power management. Use of the SRF +allowed TI to get the drivers up and running quickly with considerable +power savings; and the SRF provided debugging support. However, many +of the SRF parameters are specified in OMAP-specific terms, such as +target OPPs, rather than in terms of actual latency or throughput +requirements. OPPs change depending on OMAP silicon revisions or OMAP +types, and are meaningless for other architectures, so drivers shared +between OMAP and other architectures would also have to #ifdef out the +SRF constraints. + +Linux PM QoS parameters: + +In February 2008, the mainline Linux kernel added code that is +somewhat similar to the SRF: the Linux PM QoS parameters code, located +in kernel/pm_qos_params.c. (This code replaced the latency management +code that was present in earlier kernels.) Ideally, OMAP drivers +would be able to use this Linux PM QoS code directly, but the PM QoS +code has some drawbacks: + +- It combines some power management parameters that should be kept + separate for maximum power savings on OMAP3. For example, in the PM + QoS code, CPU and system DMA wakeup latency are combined into one + parameter; but on OMAP3, these are distinct parameters. The Linux + PM QoS code also combines all network power management knobs into + two non-device-specific parameters. OMAP2/3 systems can have + different network devices with different power management + requirements - for example, a wired Ethernet interface may have + different latency and throughput constraints than a WiFi interface. + +- It does not yet cover all of the power management capabilities of + the OMAP3 architecture. It does not express latency constraints on + a per-device or per-powerdomain basis; it only covers + cpu_dma_latency and network throughput and latency, which would not + cover most of the OMAP3 devices. + +The result is that drivers using the current Linux PM QoS layer +directly are unlikely to reach the same level of power efficiency as +driver code using the Shared Resource Framework. + +To summarize, the SRF provides significant power savings, but +expresses power constraints in an OMAP- and silicon-revision-specific +way; and the PM QoS layer expresses PM constraints in a cross-platform +manner (in terms of fundamental physical units), but does not support +per-powerdomain constraints and does not cover many of the OMAP power +management features. + + +A medium-term alternative: the OMAP PM interface +------------------------------------------------ + +We need a way for driver code to express PM parameters which: + +- supports the range of power management parameters present in the TI SRF; + +- separates the drivers from the underlying PM parameter + implementation, whether it is the TI SRF or Linux PM QoS or Linux + latency framework or something else; + +- specifies PM parameters in terms of fundamental units, such as + latency and throughput, rather than units which are specific to OMAP + or to particular OMAP variants; + +- allows drivers which are shared with other architectures (e.g., + DaVinci) to add these constraints in a way which won't affect non-OMAP + systems, + +- can be implemented immediately with minimal disruption of other + architectures. + + +We therefore propose the OMAP PM interface, including the following +four power management functions for driver code: + +1. Set the maximum MPU wakeup latency: + (*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t) + +2. Set the maximum device wakeup latency: + (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t) + +3. Set the maximum system DMA transfer start latency (CORE pwrdm): + (*pdata->set_max_sdma_lat)(struct device *dev, long t) + +4. Set the minimum bus throughput needed by a device: + (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r) + + +These functions are extensively documented in the OMAP PM interface header +file, included in the patch. + + +The OMAP PM layer is intended to be temporary +--------------------------------------------- + +The intention is that, in time, the Linux PM QoS layer should support +the range of power management features present in OMAP3. As this +happens, existing drivers using the OMAP PM interface can be modified +to use the Linux PM QoS code; and the OMAP PM interface can disappear. + + +Driver usage of the OMAP PM functions +------------------------------------- + +As the 'pdata' in the above examples indicates, these functions are +exposed to drivers through function pointers in driver .platform_data +structures. The function pointers are initialized by the board-*.c +files to point to the corresponding OMAP PM functions: +.set_max_dev_wakeup_lat will point to +omap_pm_set_max_dev_wakeup_lat(), etc. Other architectures which do +not support these functions should leave these function pointers set +to NULL. Drivers should use the following idiom: + + if (pdata->set_max_dev_wakeup_lat) + (*pdata->set_max_dev_wakeup_lat)(dev, t); + +The most common usage of these functions will probably be to specify +the maximum time from when an interrupt occurs, to when the device +becomes accessible. To accomplish this, driver writers should use the +set_max_mpu_wakeup_lat() function to to constrain the MPU wakeup +latency, and the set_max_dev_wakeup_lat() function to constrain the +device wakeup latency (from clk_enable() to accessibility). For +example, + + /* Limit MPU wakeup latency */ + if (pdata->set_max_mpu_wakeup_lat) + (*pdata->set_max_mpu_wakeup_lat)(dev, tc); + + /* Limit device powerdomain wakeup latency */ + if (pdata->set_max_dev_wakeup_lat) + (*pdata->set_max_dev_wakeup_lat)(dev, td); + + /* total wakeup latency in this example: (tc + td) */ + + +The PM parameters can be overwritten by calling the function again +with the new value. The settings can be removed by calling the +function with a t argument of -1 (except in the case of +set_max_bus_tput(), which should be called with an r argument of 0). + + +Other specialized interface functions +------------------------------------- + +The four functions listed above are intended to be usable by any +device driver. However, DSPBridge and CPUFreq have special +requirements. DSPBridge expresses target DSP performance levels in +terms of OPP IDs. CPUFreq expresses target MPU performance levels in +terms of MPU frequency. The OMAP PM interface contains functions for +these specialized cases to convert that input information (OPPs/MPU +frequency) into the form that the underlying power management +implementation needs: + +5. (*pdata->omap_pm_dsp_get_opp_table)(void) + +6. (*pdata->omap_pm_dsp_set_min_opp)(u8 opp_id) + +7. (*pdata->omap_pm_dsp_get_opp)(void) + +8. (*pdata->omap_pm_cpu_get_freq_table)(void) + +9. (*pdata->omap_pm_cpu_set_freq)(unsigned long f) + +10. (*pdata->omap_pm_cpu_get_freq)(void) + + +There are also functions for use by the clockdomain layer to indicate +that a powerdomain should wake up or be put to sleep: + +11. (*pdata->omap_pm_pwrdm_active)(struct powerdomain *pwrdm) + +12. (*pdata->omap_pm_pwrdm_inactive)(struct powerdomain *pwrdm) diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 960c13f..ca790ac 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -247,4 +247,17 @@ config OMAP_SERIAL_WAKE endmenu +choice + prompt "OMAP PM layer selection" + depends on ARCH_OMAP + default OMAP_PM_NOOP + +config OMAP_PM_NONE + bool "No PM layer" + +config OMAP_PM_NOOP + bool "No-op/debug PM layer" + +endchoice + endif diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 93bbb64..d5453d5 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_OMAP_MMU_FWK) += mmu.o # OMAP mailbox framework obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o +obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o \ No newline at end of file diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c new file mode 100644 index 0000000..5ff7962 --- /dev/null +++ b/arch/arm/plat-omap/omap-pm-noop.c @@ -0,0 +1,309 @@ +/* + * omap-pm-noop.c - OMAP power management interface - dummy version + * + * This code implements the OMAP power management interface to + * drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for + * debug/demonstration use, as it does nothing but printk() whenever a + * function is called (when DEBUG is defined, below) + * + * Copyright (C) 2008 Texas Instruments, Inc. + * Copyright (C) 2008 Nokia Corporation + * Paul Walmsley + * + * Interface developed by (in alphabetical order): + * Karthik Dasu, Amish Lakhani, Tony Lindgren, Rajendra Nayak, Sakari + * Poussa, Veeramanikandan Raju, Igor Stoppa, Paul Walmsley, Richard + * Woodruff + */ + +#undef DEBUG + +#include +#include +#include + +/* Interface documentation is in asm/arch/omap-pm.h */ +#include + +#include + +static struct omap_opp *dsp_opps; +static struct omap_opp *mpu_opps; + +/* + * Device-driver-originated constraints (via board-*.c files) + */ + +void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) +{ + if (!dev || t < -1) { + WARN_ON(1); + return; + }; + + if (t == -1) + pr_debug("OMAP PM: remove max MPU wakeup latency constraint: " + "dev %s\n", dev_name(dev)); + else + pr_debug("OMAP PM: add max MPU wakeup latency constraint: " + "dev %s, t = %ld usec\n", dev_name(dev), t); + + /* + * For current Linux, this needs to map the MPU to a + * powerdomain, then go through the list of current max lat + * constraints on the MPU and find the smallest. If + * the latency constraint has changed, the code should + * recompute the state to enter for the next powerdomain + * state. + * + * TI CDP code can call constraint_set here. + */ +} + +void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) +{ + if (!dev || agent_id != OCP_INITIATOR_AGENT || + agent_id != OCP_TARGET_AGENT) { + WARN_ON(1); + return; + }; + + if (r == 0) + 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); + + /* + * This code should model the interconnect and compute the + * required clock frequency, convert that to a VDD2 OPP ID, then + * set the VDD2 OPP appropriately. + * + * TI CDP code can call constraint_set here on the VDD2 OPP. + */ +} + +void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t) +{ + if (!dev || t < -1) { + WARN_ON(1); + return; + }; + + 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); + + /* + * For current Linux, this needs to map the device to a + * powerdomain, then go through the list of current max lat + * constraints on that powerdomain and find the smallest. If + * the latency constraint has changed, the code should + * recompute the state to enter for the next powerdomain + * state. Conceivably, this code should also determine + * whether to actually disable the device clocks or not, + * depending on how long it takes to re-enable the clocks. + * + * TI CDP code can call constraint_set here. + */ +} + +void omap_pm_set_max_sdma_lat(struct device *dev, long t) +{ + if (!dev || t < -1) { + WARN_ON(1); + return; + }; + + if (t == -1) + pr_debug("OMAP PM: remove max DMA latency constraint: " + "dev %s\n", dev_name(dev)); + else + pr_debug("OMAP PM: add max DMA latency constraint: " + "dev %s, t = %ld usec\n", dev_name(dev), t); + + /* + * For current Linux PM QOS params, this code should scan the + * list of maximum CPU and DMA latencies and select the + * smallest, then set cpu_dma_latency pm_qos_param + * accordingly. + * + * For future Linux PM QOS params, with separate CPU and DMA + * latency params, this code should just set the dma_latency param. + * + * TI CDP code can call constraint_set here. + */ + +} + + +/* + * DSP Bridge-specific constraints + */ + +const struct omap_opp *omap_pm_dsp_get_opp_table(void) +{ + pr_debug("OMAP PM: DSP request for OPP table\n"); + + /* + * Return DSP frequency table here: The final item in the + * array should have .rate = .opp_id = 0. + */ + + return NULL; +} + +void omap_pm_dsp_set_min_opp(u8 opp_id) +{ + if (opp_id == 0) { + WARN_ON(1); + return; + } + + pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id); + + /* + * + * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we + * can just test to see which is higher, the CPU's desired OPP + * ID or the DSP's desired OPP ID, and use whichever is + * highest. + * + * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP + * rate is keyed on MPU speed, not the OPP ID. So we need to + * map the OPP ID to the MPU speed for use with clk_set_rate() + * if it is higher than the current OPP clock rate. + * + */ +} + + +u8 omap_pm_dsp_get_opp(void) +{ + pr_debug("OMAP PM: DSP requests current DSP OPP ID\n"); + + /* + * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock + * + * CDP12.14+: + * Call clk_get_rate() on the OPP custom clock, map that to an + * OPP ID using the tables defined in board-*.c/chip-*.c files. + */ + + 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) +{ + pr_debug("OMAP PM: CPUFreq request for frequency table\n"); + + /* + * Return CPUFreq frequency table here: loop over + * all VDD1 clkrates, pull out the mpu_ck frequencies, build + * table + */ + + return NULL; +} + +void omap_pm_cpu_set_freq(unsigned long f) +{ + if (f == 0) { + WARN_ON(1); + return; + } + + pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n", + f); + + /* + * For l-o dev tree, determine whether MPU freq or DSP OPP id + * freq is higher. Find the OPP ID corresponding to the + * higher frequency. Call clk_round_rate() and clk_set_rate() + * on the OPP custom clock. + * + * CDP should just be able to set the VDD1 OPP clock rate here. + */ +} + +unsigned long omap_pm_cpu_get_freq(void) +{ + pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n"); + + /* + * Call clk_get_rate() on the mpu_ck. + */ + + return 0; +} + +/* + * Powerdomain usecounting hooks + */ + +void omap_pm_pwrdm_active(struct powerdomain *pwrdm) +{ + if (!pwrdm) { + WARN_ON(1); + return; + }; + + pr_debug("OMAP PM: powerdomain %s is becoming active\n", pwrdm->name); + + /* + * CDP code apparently will need these for the enable_power_domain() + * and disable_power_domain() functions. + */ +} + +void omap_pm_pwrdm_inactive(struct powerdomain *pwrdm) +{ + if (!pwrdm) { + WARN_ON(1); + return; + }; + + pr_debug("OMAP PM: powerdomain %s is becoming inactive\n", + pwrdm->name); + + /* + * CDP code apparently will need these for the enable_power_domain() + * and disable_power_domain() functions. + */ +} + +/* + * Should be called before clk framework since clk fw will call + * omap_pm_pwrdm_{in,}active() + */ +int __init omap_pm_if_early_init(void) +{ + return 0; +} + +/* Must be called after clock framework is initialized */ +int __init omap_pm_if_init(struct omap_opp *mpu_opp_table, + struct omap_opp *dsp_opp_table) +{ + mpu_opps = mpu_opp_table; + dsp_opps = dsp_opp_table; + return 0; +} + +void omap_pm_if_exit(void) +{ + /* Deallocate CPUFreq frequency table here */ +} + diff --git a/include/asm-arm/arch-omap/omap-pm.h b/include/asm-arm/arch-omap/omap-pm.h new file mode 100644 index 0000000..d272dba --- /dev/null +++ b/include/asm-arm/arch-omap/omap-pm.h @@ -0,0 +1,300 @@ +/* + * omap-pm.h - OMAP power management interface + * + * Copyright (C) 2008 Texas Instruments, Inc. + * Copyright (C) 2008 Nokia Corporation + * Paul Walmsley + * + * Interface developed by (in alphabetical order): Karthik Dasu, Jouni + * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa, + * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, + * Richard Woodruff + */ + +#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H +#define ASM_ARM_ARCH_OMAP_OMAP_PM_H + +#include +#include + +#include "powerdomain.h" + +/** + * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU + * @rate: target clock rate + * @opp_id: OPP ID + * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP + * + * Operating performance point data. Can vary by OMAP chip and board. + */ +struct omap_opp { + unsigned long rate; + u8 opp_id; + u16 min_vdd; +}; + +/* + * agent_id values for use with omap_pm_set_min_bus_tput(): + * + * OCP_INITIATOR_AGENT is only valid for devices that can act as + * initiators -- it represents the device's L3 interconnect + * connection. OCP_TARGET_AGENT represents the device's L4 + * interconnect connection. + */ +#define OCP_TARGET_AGENT 1 +#define OCP_INITIATOR_AGENT 2 + +/** + * omap_pm_if_early_init - OMAP PM init code called before clock fw init + * + * Initialize anything that must be configured before the clock + * framework starts. The "_if_" is to avoid name collisions with the + * PM idle-loop code. + */ +int __init omap_pm_if_early_init(void); + +/** + * omap_pm_if_init - OMAP PM init code called after clock fw init + * @mpu_opp_table: array ptr to struct omap_opp for MPU + * @dsp_opp_table: array ptr to struct omap_opp for DSP + * + * The main initialization code. OPP tables are passed in here. The + * "_if_" is to avoid name collisions with the PM idle-loop code. + */ +int __init omap_pm_if_init(struct omap_opp *mpu_opp_table, + struct omap_opp *dsp_opp_table); + +/** + * omap_pm_if_exit - OMAP PM exit code + * + * Exit code; currently unused. The "_if_" is to avoid name + * collisions with the PM idle-loop code. + */ +void omap_pm_if_exit(void); + +/* + * Device-driver-originated constraints (via board-*.c files, platform_data) + */ + + +/** + * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency + * @dev: struct device * requesting the constraint + * @t: maximum MPU wakeup latency in microseconds + * + * Request that the maximum interrupt latency for the MPU to be no + * greater than 't' microseconds. "Interrupt latency" in this case is + * defined as the elapsed time from the occurrence of a hardware or + * timer interrupt to the time when the device driver's interrupt + * service routine has been entered by the MPU. + * + * It is intended that underlying PM code will use this information to + * determine what power state to put the MPU powerdomain into, and + * possibly the CORE powerdomain as well, since interrupt handling + * code currently runs from SDRAM. Advanced PM or board*.c code may + * also configure interrupt controller priorities, OCP bus priorities, + * CPU speed(s), etc. + * + * This function will not affect device wakeup latency, e.g., time + * elapsed from when a device driver enables a hardware device with + * clk_enable(), to when the device is ready for register access or + * other use. To control this device wakeup latency, use + * set_max_dev_wakeup_lat() + * + * Multiple calls to set_max_mpu_wakeup_lat() will replace the + * previous t value. To remove the latency target for the MPU, call + * with t = -1. + * + * No return value. + */ +void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t); + + +/** + * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device + * @dev: struct device * requesting the constraint + * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT) + * @r: minimum throughput (in KiB/s) + * + * Request that the minimum data throughput on the OCP interconnect + * attached to device 'dev' interconnect agent 'tbus_id' be no less + * than 'r' KiB/s. + * + * It is expected that the OMAP PM or bus code will use this + * information to set the interconnect clock to run at the lowest + * possible speed that satisfies all current system users. The PM or + * bus code will adjust the estimate based on its model of the bus, so + * device driver authors should attempt to specify an accurate + * quantity for their device use case, and let the PM or bus code + * overestimate the numbers as necessary to handle request/response + * latency, other competing users on the system, etc. On OMAP2/3, if + * a driver requests a minimum L4 interconnect speed constraint, the + * code will also need to add an minimum L3 interconnect speed + * constraint, + * + * Multiple calls to set_min_bus_tput() will replace the previous rate + * value for this device. To remove the interconnect throughput + * restriction for this device, call with r = 0. + * + * No return value. + */ +void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r); + + +/** + * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency + * @dev: struct device * + * @t: maximum device wakeup latency in microseconds + * + * Request that the maximum amount of time necessary for a device to + * become accessible after its clocks are enabled should be no greater + * than 't' microseconds. Specifically, this represents the time from + * when a device driver enables device clocks with clk_enable(), to + * when the register reads and writes on the device will succeed. + * This function should be called before clk_disable() is called, + * since the power state transition decision may be made during + * clk_disable(). + * + * It is intended that underlying PM code will use this information to + * determine what power state to put the powerdomain enclosing this + * device into. + * + * Multiple calls to set_max_dev_wakeup_lat() will replace the + * previous wakeup latency values for this device. To remove the wakeup + * latency restriction for this device, call with t = -1. + * + * No return value. + */ +void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t); + + +/** + * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency + * @dev: struct device * + * @t: maximum DMA transfer start latency in microseconds + * + * Request that the maximum system DMA transfer start latency for this + * device 'dev' should be no greater than 't' microseconds. "DMA + * transfer start latency" here is defined as the elapsed time from + * when a device (e.g., McBSP) requests that a system DMA transfer + * start or continue, to the time at which data starts to flow into + * that device from the system DMA controller. + * + * It is intended that underlying PM code will use this information to + * determine what power state to put the CORE powerdomain into. + * + * Since system DMA transfers may not involve the MPU, this function + * will not affect MPU wakeup latency. Use set_max_cpu_lat() to do + * so. Similarly, this function will not affect device wakeup latency + * -- use set_max_dev_wakeup_lat() to affect that. + * + * Multiple calls to set_max_sdma_lat() will replace the previous t + * value for this device. To remove the maximum DMA latency for this + * device, call with t = -1. + * + * No return value. + */ +void omap_pm_set_max_sdma_lat(struct device *dev, long t); + + +/* + * DSP Bridge-specific constraints + */ + +/** + * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table + * + * Intended for use by DSPBridge. Returns an array of OPP->DSP clock + * frequency entries. The final item in the array should have .rate = + * .opp_id = 0. + */ +const struct omap_opp *omap_pm_dsp_get_opp_table(void); + +/** + * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge + * @opp_id: target DSP OPP ID + * + * Set a minimum OPP ID for the DSP. This is intended to be called + * only from the DSP Bridge MPU-side driver. Unfortunately, the only + * information that code receives from the DSP/BIOS load estimator is the + * target OPP ID; hence, this interface. No return value. + */ +void omap_pm_dsp_set_min_opp(u8 opp_id); + +/** + * omap_pm_dsp_get_opp - report the current DSP OPP ID + * + * Report the current OPP for the DSP. Since on OMAP3, the DSP and + * MPU share a single voltage domain, the OPP ID returned back may + * represent a higher DSP speed than the OPP requested via + * omap_pm_dsp_set_min_opp(). + * + * Returns the current VDD1 OPP ID, or 0 upon error. + */ +u8 omap_pm_dsp_get_opp(void); + + +/* + * CPUFreq-originated constraint + * + * In the future, this should be handled by custom OPP clocktype + * functions. + */ + +/** + * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr + * + * Provide a frequency table usable by CPUFreq for the current chip/board. + * Returns a pointer to a struct cpufreq_frequency_table array or NULL + * upon error. + */ +struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void); + +/** + * omap_pm_cpu_set_freq - set the current minimum MPU frequency + * @f: MPU frequency in Hz + * + * Set the current minimum CPU frequency. The actual CPU frequency + * used could end up higher if the DSP requested a higher OPP. + * Intended to be called by plat-omap/cpu_omap.c:omap_target(). No + * return value. + */ +void omap_pm_cpu_set_freq(unsigned long f); + +/** + * omap_pm_cpu_get_freq - report the current CPU frequency + * + * Returns the current MPU frequency, or 0 upon error. + */ +unsigned long omap_pm_cpu_get_freq(void); + + +/* + * Powerdomain usecounting hooks + */ + +/** + * omap_pm_pwrdm_active - indicate that a power domain has become active + * @pwrdm: struct powerdomain * + * + * Notify the OMAP PM layer that the power domain 'pwrdm' has become active, + * presumably due to a device driver enabling an underlying clock. This + * function is intended to be called by a clockdomain node in the clock + * framework. No return value. + */ +void omap_pm_pwrdm_active(struct powerdomain *pwrdm); + + +/** + * omap_pm_pwrdm_inactive - indicate that a power domain has become inactive + * @pwrdm: struct powerdomain * + * + * Notify the OMAP PM layer that the power domain 'pwrdm' has become + * inactive, presumably due to a device driver disabling an underlying + * clock. This function is intended to be called by a clockdomain + * node in the clock framework. No return value. + */ +void omap_pm_pwrdm_inactive(struct powerdomain *pwrdm); + + +#endif -- 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 --- /tmp/io.c 2008-08-11 15:29:32.000000000 +0200 +++ git/arch/arm/mach-omap2/io.c 2008-08-11 15:30:20.083198000 +0200 @@ -38,6 +38,8 @@ #include #include "clockdomains.h" +#include + /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. @@ -197,9 +199,11 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sp) { omap2_mux_init(); + omap_pm_if_early_init(); pwrdm_init(powerdomains_omap); clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); omap2_clk_init(); + omap_pm_if_init(NULL, NULL); omap2_sdrc_init(sp); gpmc_init(); }