| 
									
										
										
										
											2009-09-03 20:14:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | The OMAP PM interface | 
					
						
							|  |  |  | ===================== | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This document describes the temporary OMAP PM interface.  Driver | 
					
						
							|  |  |  | authors use these functions to communicate minimum latency or | 
					
						
							|  |  |  | throughput constraints to the kernel power management code. | 
					
						
							|  |  |  | Over time, the intention is to merge features from the OMAP PM | 
					
						
							|  |  |  | interface into the Linux PM QoS code. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Drivers need to express PM parameters which: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - support the range of power management parameters present in the TI SRF; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - separate 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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - specify 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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - allow 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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This document proposes the OMAP PM interface, including the following | 
					
						
							|  |  |  | five 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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 5. Return the number of times the device has lost context | 
					
						
							|  |  |  |    (*pdata->get_dev_context_loss_count)(struct device *dev) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Further documentation for all OMAP PM interface functions can be | 
					
						
							|  |  |  | found in arch/arm/plat-omap/include/mach/omap-pm.h. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The OMAP PM layer is intended to be temporary | 
					
						
							|  |  |  | --------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The intention is that eventually 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). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The fifth function above, omap_pm_get_dev_context_loss_count(), | 
					
						
							|  |  |  | is intended as an optimization to allow drivers to determine whether the | 
					
						
							|  |  |  | device has lost its internal context.  If context has been lost, the | 
					
						
							|  |  |  | driver must restore its internal context before proceeding. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Other specialized interface functions | 
					
						
							|  |  |  | ------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The five functions listed above are intended to be usable by any | 
					
						
							|  |  |  | device driver.  DSPBridge and CPUFreq have a few 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: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 6. (*pdata->dsp_get_opp_table)(void) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 7. (*pdata->dsp_set_min_opp)(u8 opp_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 8. (*pdata->dsp_get_opp)(void) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 9. (*pdata->cpu_get_freq_table)(void) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 10. (*pdata->cpu_set_freq)(unsigned long f) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 11. (*pdata->cpu_get_freq)(void) | 
					
						
							| 
									
										
										
										
											2010-12-09 09:13:46 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | Customizing OPP for platform | 
					
						
							|  |  |  | ============================ | 
					
						
							|  |  |  | Defining CONFIG_PM should enable OPP layer for the silicon | 
					
						
							|  |  |  | and the registration of OPP table should take place automatically. | 
					
						
							|  |  |  | However, in special cases, the default OPP table may need to be | 
					
						
							|  |  |  | tweaked, for e.g.: | 
					
						
							|  |  |  |  * enable default OPPs which are disabled by default, but which | 
					
						
							|  |  |  |    could be enabled on a platform | 
					
						
							|  |  |  |  * Disable an unsupported OPP on the platform | 
					
						
							|  |  |  |  * Define and add a custom opp table entry | 
					
						
							|  |  |  | in these cases, the board file needs to do additional steps as follows: | 
					
						
							|  |  |  | arch/arm/mach-omapx/board-xyz.c | 
					
						
							|  |  |  | 	#include "pm.h" | 
					
						
							|  |  |  | 	.... | 
					
						
							|  |  |  | 	static void __init omap_xyz_init_irq(void) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		.... | 
					
						
							|  |  |  | 		/* Initialize the default table */ | 
					
						
							|  |  |  | 		omapx_opp_init(); | 
					
						
							|  |  |  | 		/* Do customization to the defaults */ | 
					
						
							|  |  |  | 		.... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | NOTE: omapx_opp_init will be omap3_opp_init or as required | 
					
						
							|  |  |  | based on the omap family. |