OMAP PM 接口

本文档描述了临时的 OMAP PM 接口。驱动程序作者使用这些函数将最小延迟或吞吐量约束传递给内核电源管理代码。随着时间的推移,目的是将 OMAP PM 接口的功能合并到 Linux PM QoS 代码中。

驱动程序需要表达 PM 参数,这些参数:

  • 支持 TI SRF 中存在的电源管理参数范围;

  • 将驱动程序与底层的 PM 参数实现分离,无论是 TI SRF 还是 Linux PM QoS 还是 Linux 延迟框架或其他;

  • 以基本单位(例如延迟和吞吐量)而不是 OMAP 或特定 OMAP 变体特定的单位来指定 PM 参数;

  • 允许与其他架构(例如 DaVinci)共享的驱动程序以不影响非 OMAP 系统的方式添加这些约束,

  • 可以立即实现,且对其他架构的干扰最小。

本文档提出了 OMAP PM 接口,其中包括以下五个用于驱动程序代码的电源管理函数:

  1. 设置最大 MPU 唤醒延迟

    (*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t)
    
  2. 设置最大设备唤醒延迟

    (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
    
  3. 设置最大系统 DMA 传输启动延迟 (CORE pwrdm)

    (*pdata->set_max_sdma_lat)(struct device *dev, long t)
    
  4. 设置设备所需的最小总线吞吐量

    (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r)
    
  5. 返回设备丢失上下文的次数

    (*pdata->get_dev_context_loss_count)(struct device *dev)
    

所有 OMAP PM 接口函数的进一步文档可以在 arch/arm/plat-omap/include/mach/omap-pm.h 中找到。

OMAP PM 层旨在是临时的

目的是最终 Linux PM QoS 层应支持 OMAP3 中存在的电源管理功能范围。当这种情况发生时,可以使用 Linux PM QoS 代码修改使用 OMAP PM 接口的现有驱动程序;OMAP PM 接口可以消失。

驱动程序对 OMAP PM 函数的使用

正如上述示例中的“pdata”所示,这些函数通过驱动程序 .platform_data 结构中的函数指针暴露给驱动程序。函数指针由 board-*.c 文件初始化,以指向相应的 OMAP PM 函数

  • set_max_dev_wakeup_lat 将指向 omap_pm_set_max_dev_wakeup_lat() 等。不支持这些函数的其他架构应将这些函数指针设置为 NULL。驱动程序应使用以下习惯用法

    if (pdata->set_max_dev_wakeup_lat)
        (*pdata->set_max_dev_wakeup_lat)(dev, t);
    

这些函数最常见的用法可能是指定从发生中断到设备变得可访问的最长时间。为了实现这一点,驱动程序编写者应使用 set_max_mpu_wakeup_lat() 函数来约束 MPU 唤醒延迟,并使用 set_max_dev_wakeup_lat() 函数来约束设备唤醒延迟(从 clk_enable() 到可访问性)。例如

/* 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) */

可以通过使用新值再次调用该函数来覆盖 PM 参数。可以通过使用 -1 的 t 参数(set_max_bus_tput() 的情况除外,应使用 0 的 r 参数调用)来删除设置。

上面的第五个函数 omap_pm_get_dev_context_loss_count() 旨在作为一种优化,允许驱动程序确定设备是否丢失了其内部上下文。如果上下文丢失,驱动程序必须在继续之前恢复其内部上下文。

其他专用接口函数

上面列出的五个函数旨在供任何设备驱动程序使用。DSPBridge 和 CPUFreq 有一些特殊要求。DSPBridge 以 OPP ID 的形式表示目标 DSP 性能级别。CPUFreq 以 MPU 频率的形式表示目标 MPU 性能级别。OMAP PM 接口包含用于这些特殊情况的函数,以将该输入信息(OPP/MPU 频率)转换为底层电源管理实现所需的形式

  1. (*pdata->dsp_get_opp_table)(void)

  2. (*pdata->dsp_set_min_opp)(u8 opp_id)

  3. (*pdata->dsp_get_opp)(void)

  4. (*pdata->cpu_get_freq_table)(void)

  5. (*pdata->cpu_set_freq)(unsigned long f)

  6. (*pdata->cpu_get_freq)(void)

为平台自定义 OPP

定义 CONFIG_PM 应为芯片启用 OPP 层,并且应自动进行 OPP 表的注册。但是,在特殊情况下,可能需要调整默认 OPP 表,例如:

  • 启用默认情况下禁用但可以在平台上启用的默认 OPP

  • 在平台上禁用不受支持的 OPP

  • 在这些情况下定义并添加自定义的 opp 表条目,板文件需要执行以下附加步骤:

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 */
        ....
}
注意

omapx_opp_init 将是 omap3_opp_init 或根据 omap 系列的要求。