1*4882a593Smuzhiyun===================== 2*4882a593SmuzhiyunThe OMAP PM interface 3*4882a593Smuzhiyun===================== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunThis document describes the temporary OMAP PM interface. Driver 6*4882a593Smuzhiyunauthors use these functions to communicate minimum latency or 7*4882a593Smuzhiyunthroughput constraints to the kernel power management code. 8*4882a593SmuzhiyunOver time, the intention is to merge features from the OMAP PM 9*4882a593Smuzhiyuninterface into the Linux PM QoS code. 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunDrivers need to express PM parameters which: 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun- support the range of power management parameters present in the TI SRF; 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun- separate the drivers from the underlying PM parameter 16*4882a593Smuzhiyun implementation, whether it is the TI SRF or Linux PM QoS or Linux 17*4882a593Smuzhiyun latency framework or something else; 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun- specify PM parameters in terms of fundamental units, such as 20*4882a593Smuzhiyun latency and throughput, rather than units which are specific to OMAP 21*4882a593Smuzhiyun or to particular OMAP variants; 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun- allow drivers which are shared with other architectures (e.g., 24*4882a593Smuzhiyun DaVinci) to add these constraints in a way which won't affect non-OMAP 25*4882a593Smuzhiyun systems, 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun- can be implemented immediately with minimal disruption of other 28*4882a593Smuzhiyun architectures. 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun 31*4882a593SmuzhiyunThis document proposes the OMAP PM interface, including the following 32*4882a593Smuzhiyunfive power management functions for driver code: 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun1. Set the maximum MPU wakeup latency:: 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun (*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t) 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun2. Set the maximum device wakeup latency:: 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t) 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun3. Set the maximum system DMA transfer start latency (CORE pwrdm):: 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun (*pdata->set_max_sdma_lat)(struct device *dev, long t) 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun4. Set the minimum bus throughput needed by a device:: 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r) 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun5. Return the number of times the device has lost context:: 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun (*pdata->get_dev_context_loss_count)(struct device *dev) 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun 55*4882a593SmuzhiyunFurther documentation for all OMAP PM interface functions can be 56*4882a593Smuzhiyunfound in arch/arm/plat-omap/include/mach/omap-pm.h. 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun 59*4882a593SmuzhiyunThe OMAP PM layer is intended to be temporary 60*4882a593Smuzhiyun--------------------------------------------- 61*4882a593Smuzhiyun 62*4882a593SmuzhiyunThe intention is that eventually the Linux PM QoS layer should support 63*4882a593Smuzhiyunthe range of power management features present in OMAP3. As this 64*4882a593Smuzhiyunhappens, existing drivers using the OMAP PM interface can be modified 65*4882a593Smuzhiyunto use the Linux PM QoS code; and the OMAP PM interface can disappear. 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun 68*4882a593SmuzhiyunDriver usage of the OMAP PM functions 69*4882a593Smuzhiyun------------------------------------- 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunAs the 'pdata' in the above examples indicates, these functions are 72*4882a593Smuzhiyunexposed to drivers through function pointers in driver .platform_data 73*4882a593Smuzhiyunstructures. The function pointers are initialized by the `board-*.c` 74*4882a593Smuzhiyunfiles to point to the corresponding OMAP PM functions: 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun- set_max_dev_wakeup_lat will point to 77*4882a593Smuzhiyun omap_pm_set_max_dev_wakeup_lat(), etc. Other architectures which do 78*4882a593Smuzhiyun not support these functions should leave these function pointers set 79*4882a593Smuzhiyun to NULL. Drivers should use the following idiom:: 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun if (pdata->set_max_dev_wakeup_lat) 82*4882a593Smuzhiyun (*pdata->set_max_dev_wakeup_lat)(dev, t); 83*4882a593Smuzhiyun 84*4882a593SmuzhiyunThe most common usage of these functions will probably be to specify 85*4882a593Smuzhiyunthe maximum time from when an interrupt occurs, to when the device 86*4882a593Smuzhiyunbecomes accessible. To accomplish this, driver writers should use the 87*4882a593Smuzhiyunset_max_mpu_wakeup_lat() function to constrain the MPU wakeup 88*4882a593Smuzhiyunlatency, and the set_max_dev_wakeup_lat() function to constrain the 89*4882a593Smuzhiyundevice wakeup latency (from clk_enable() to accessibility). For 90*4882a593Smuzhiyunexample:: 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun /* Limit MPU wakeup latency */ 93*4882a593Smuzhiyun if (pdata->set_max_mpu_wakeup_lat) 94*4882a593Smuzhiyun (*pdata->set_max_mpu_wakeup_lat)(dev, tc); 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /* Limit device powerdomain wakeup latency */ 97*4882a593Smuzhiyun if (pdata->set_max_dev_wakeup_lat) 98*4882a593Smuzhiyun (*pdata->set_max_dev_wakeup_lat)(dev, td); 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun /* total wakeup latency in this example: (tc + td) */ 101*4882a593Smuzhiyun 102*4882a593SmuzhiyunThe PM parameters can be overwritten by calling the function again 103*4882a593Smuzhiyunwith the new value. The settings can be removed by calling the 104*4882a593Smuzhiyunfunction with a t argument of -1 (except in the case of 105*4882a593Smuzhiyunset_max_bus_tput(), which should be called with an r argument of 0). 106*4882a593Smuzhiyun 107*4882a593SmuzhiyunThe fifth function above, omap_pm_get_dev_context_loss_count(), 108*4882a593Smuzhiyunis intended as an optimization to allow drivers to determine whether the 109*4882a593Smuzhiyundevice has lost its internal context. If context has been lost, the 110*4882a593Smuzhiyundriver must restore its internal context before proceeding. 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun 113*4882a593SmuzhiyunOther specialized interface functions 114*4882a593Smuzhiyun------------------------------------- 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunThe five functions listed above are intended to be usable by any 117*4882a593Smuzhiyundevice driver. DSPBridge and CPUFreq have a few special requirements. 118*4882a593SmuzhiyunDSPBridge expresses target DSP performance levels in terms of OPP IDs. 119*4882a593SmuzhiyunCPUFreq expresses target MPU performance levels in terms of MPU 120*4882a593Smuzhiyunfrequency. The OMAP PM interface contains functions for these 121*4882a593Smuzhiyunspecialized cases to convert that input information (OPPs/MPU 122*4882a593Smuzhiyunfrequency) into the form that the underlying power management 123*4882a593Smuzhiyunimplementation needs: 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun6. `(*pdata->dsp_get_opp_table)(void)` 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun7. `(*pdata->dsp_set_min_opp)(u8 opp_id)` 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun8. `(*pdata->dsp_get_opp)(void)` 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun9. `(*pdata->cpu_get_freq_table)(void)` 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun10. `(*pdata->cpu_set_freq)(unsigned long f)` 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun11. `(*pdata->cpu_get_freq)(void)` 136*4882a593Smuzhiyun 137*4882a593SmuzhiyunCustomizing OPP for platform 138*4882a593Smuzhiyun============================ 139*4882a593SmuzhiyunDefining CONFIG_PM should enable OPP layer for the silicon 140*4882a593Smuzhiyunand the registration of OPP table should take place automatically. 141*4882a593SmuzhiyunHowever, in special cases, the default OPP table may need to be 142*4882a593Smuzhiyuntweaked, for e.g.: 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun * enable default OPPs which are disabled by default, but which 145*4882a593Smuzhiyun could be enabled on a platform 146*4882a593Smuzhiyun * Disable an unsupported OPP on the platform 147*4882a593Smuzhiyun * Define and add a custom opp table entry 148*4882a593Smuzhiyun in these cases, the board file needs to do additional steps as follows: 149*4882a593Smuzhiyun 150*4882a593Smuzhiyunarch/arm/mach-omapx/board-xyz.c:: 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun #include "pm.h" 153*4882a593Smuzhiyun .... 154*4882a593Smuzhiyun static void __init omap_xyz_init_irq(void) 155*4882a593Smuzhiyun { 156*4882a593Smuzhiyun .... 157*4882a593Smuzhiyun /* Initialize the default table */ 158*4882a593Smuzhiyun omapx_opp_init(); 159*4882a593Smuzhiyun /* Do customization to the defaults */ 160*4882a593Smuzhiyun .... 161*4882a593Smuzhiyun } 162*4882a593Smuzhiyun 163*4882a593SmuzhiyunNOTE: 164*4882a593Smuzhiyun omapx_opp_init will be omap3_opp_init or as required 165*4882a593Smuzhiyun based on the omap family. 166