162306a36Sopenharmony_ci=====================
262306a36Sopenharmony_ciThe OMAP PM interface
362306a36Sopenharmony_ci=====================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciThis document describes the temporary OMAP PM interface.  Driver
662306a36Sopenharmony_ciauthors use these functions to communicate minimum latency or
762306a36Sopenharmony_cithroughput constraints to the kernel power management code.
862306a36Sopenharmony_ciOver time, the intention is to merge features from the OMAP PM
962306a36Sopenharmony_ciinterface into the Linux PM QoS code.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciDrivers need to express PM parameters which:
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci- support the range of power management parameters present in the TI SRF;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci- separate the drivers from the underlying PM parameter
1662306a36Sopenharmony_ci  implementation, whether it is the TI SRF or Linux PM QoS or Linux
1762306a36Sopenharmony_ci  latency framework or something else;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci- specify PM parameters in terms of fundamental units, such as
2062306a36Sopenharmony_ci  latency and throughput, rather than units which are specific to OMAP
2162306a36Sopenharmony_ci  or to particular OMAP variants;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci- allow drivers which are shared with other architectures (e.g.,
2462306a36Sopenharmony_ci  DaVinci) to add these constraints in a way which won't affect non-OMAP
2562306a36Sopenharmony_ci  systems,
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci- can be implemented immediately with minimal disruption of other
2862306a36Sopenharmony_ci  architectures.
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ciThis document proposes the OMAP PM interface, including the following
3262306a36Sopenharmony_cifive power management functions for driver code:
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci1. Set the maximum MPU wakeup latency::
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci   (*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci2. Set the maximum device wakeup latency::
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci   (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci3. Set the maximum system DMA transfer start latency (CORE pwrdm)::
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci   (*pdata->set_max_sdma_lat)(struct device *dev, long t)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci4. Set the minimum bus throughput needed by a device::
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci   (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r)
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci5. Return the number of times the device has lost context::
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci   (*pdata->get_dev_context_loss_count)(struct device *dev)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ciFurther documentation for all OMAP PM interface functions can be
5662306a36Sopenharmony_cifound in arch/arm/plat-omap/include/mach/omap-pm.h.
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ciThe OMAP PM layer is intended to be temporary
6062306a36Sopenharmony_ci---------------------------------------------
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ciThe intention is that eventually the Linux PM QoS layer should support
6362306a36Sopenharmony_cithe range of power management features present in OMAP3.  As this
6462306a36Sopenharmony_cihappens, existing drivers using the OMAP PM interface can be modified
6562306a36Sopenharmony_cito use the Linux PM QoS code; and the OMAP PM interface can disappear.
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ciDriver usage of the OMAP PM functions
6962306a36Sopenharmony_ci-------------------------------------
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ciAs the 'pdata' in the above examples indicates, these functions are
7262306a36Sopenharmony_ciexposed to drivers through function pointers in driver .platform_data
7362306a36Sopenharmony_cistructures.  The function pointers are initialized by the `board-*.c`
7462306a36Sopenharmony_cifiles to point to the corresponding OMAP PM functions:
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci- set_max_dev_wakeup_lat will point to
7762306a36Sopenharmony_ci  omap_pm_set_max_dev_wakeup_lat(), etc.  Other architectures which do
7862306a36Sopenharmony_ci  not support these functions should leave these function pointers set
7962306a36Sopenharmony_ci  to NULL.  Drivers should use the following idiom::
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci        if (pdata->set_max_dev_wakeup_lat)
8262306a36Sopenharmony_ci            (*pdata->set_max_dev_wakeup_lat)(dev, t);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ciThe most common usage of these functions will probably be to specify
8562306a36Sopenharmony_cithe maximum time from when an interrupt occurs, to when the device
8662306a36Sopenharmony_cibecomes accessible.  To accomplish this, driver writers should use the
8762306a36Sopenharmony_ciset_max_mpu_wakeup_lat() function to constrain the MPU wakeup
8862306a36Sopenharmony_cilatency, and the set_max_dev_wakeup_lat() function to constrain the
8962306a36Sopenharmony_cidevice wakeup latency (from clk_enable() to accessibility).  For
9062306a36Sopenharmony_ciexample::
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci        /* Limit MPU wakeup latency */
9362306a36Sopenharmony_ci        if (pdata->set_max_mpu_wakeup_lat)
9462306a36Sopenharmony_ci            (*pdata->set_max_mpu_wakeup_lat)(dev, tc);
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci        /* Limit device powerdomain wakeup latency */
9762306a36Sopenharmony_ci        if (pdata->set_max_dev_wakeup_lat)
9862306a36Sopenharmony_ci            (*pdata->set_max_dev_wakeup_lat)(dev, td);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci        /* total wakeup latency in this example: (tc + td) */
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciThe PM parameters can be overwritten by calling the function again
10362306a36Sopenharmony_ciwith the new value.  The settings can be removed by calling the
10462306a36Sopenharmony_cifunction with a t argument of -1 (except in the case of
10562306a36Sopenharmony_ciset_max_bus_tput(), which should be called with an r argument of 0).
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciThe fifth function above, omap_pm_get_dev_context_loss_count(),
10862306a36Sopenharmony_ciis intended as an optimization to allow drivers to determine whether the
10962306a36Sopenharmony_cidevice has lost its internal context.  If context has been lost, the
11062306a36Sopenharmony_cidriver must restore its internal context before proceeding.
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciOther specialized interface functions
11462306a36Sopenharmony_ci-------------------------------------
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ciThe five functions listed above are intended to be usable by any
11762306a36Sopenharmony_cidevice driver.  DSPBridge and CPUFreq have a few special requirements.
11862306a36Sopenharmony_ciDSPBridge expresses target DSP performance levels in terms of OPP IDs.
11962306a36Sopenharmony_ciCPUFreq expresses target MPU performance levels in terms of MPU
12062306a36Sopenharmony_cifrequency.  The OMAP PM interface contains functions for these
12162306a36Sopenharmony_cispecialized cases to convert that input information (OPPs/MPU
12262306a36Sopenharmony_cifrequency) into the form that the underlying power management
12362306a36Sopenharmony_ciimplementation needs:
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci6. `(*pdata->dsp_get_opp_table)(void)`
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci7. `(*pdata->dsp_set_min_opp)(u8 opp_id)`
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci8. `(*pdata->dsp_get_opp)(void)`
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci9. `(*pdata->cpu_get_freq_table)(void)`
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci10. `(*pdata->cpu_set_freq)(unsigned long f)`
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci11. `(*pdata->cpu_get_freq)(void)`
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ciCustomizing OPP for platform
13862306a36Sopenharmony_ci============================
13962306a36Sopenharmony_ciDefining CONFIG_PM should enable OPP layer for the silicon
14062306a36Sopenharmony_ciand the registration of OPP table should take place automatically.
14162306a36Sopenharmony_ciHowever, in special cases, the default OPP table may need to be
14262306a36Sopenharmony_citweaked, for e.g.:
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci * enable default OPPs which are disabled by default, but which
14562306a36Sopenharmony_ci   could be enabled on a platform
14662306a36Sopenharmony_ci * Disable an unsupported OPP on the platform
14762306a36Sopenharmony_ci * Define and add a custom opp table entry
14862306a36Sopenharmony_ci   in these cases, the board file needs to do additional steps as follows:
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ciarch/arm/mach-omapx/board-xyz.c::
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	#include "pm.h"
15362306a36Sopenharmony_ci	....
15462306a36Sopenharmony_ci	static void __init omap_xyz_init_irq(void)
15562306a36Sopenharmony_ci	{
15662306a36Sopenharmony_ci		....
15762306a36Sopenharmony_ci		/* Initialize the default table */
15862306a36Sopenharmony_ci		omapx_opp_init();
15962306a36Sopenharmony_ci		/* Do customization to the defaults */
16062306a36Sopenharmony_ci		....
16162306a36Sopenharmony_ci	}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ciNOTE:
16462306a36Sopenharmony_ci  omapx_opp_init will be omap3_opp_init or as required
16562306a36Sopenharmony_ci  based on the omap family.
166