요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=====================
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 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)`
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.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
OMAP PM 인터페이스
1-3이 문서는 OMAP PM interface를 정의합니다.
목적과 설계 요구 사항
4-32이 문서는 임시 OMAP PM interface를 설명합니다. 드라이버 작성자는 이 함수들로 최소 latency 또는 throughput 제약을 커널 power-management 코드에 전달합니다. 장기적으로는 OMAP PM interface의 기능을 Linux PM QoS 코드에 합치는 것이 목표입니다.
드라이버가 표현해야 하는 PM 매개변수의 요구 사항은 다음과 같습니다.
- TI SRF에 존재하는 power-management 매개변수 범위를 지원해야 합니다.
- 기반 구현이 TI SRF, Linux PM QoS, Linux latency framework 또는 다른 무엇이든 드라이버와 구현을 분리해야 합니다.
- OMAP 또는 특정 OMAP variant 고유 단위가 아니라 latency와 throughput 같은 기본 단위로 매개변수를 지정해야 합니다.
- DaVinci처럼 다른 아키텍처와 공유하는 드라이버가 비 OMAP 시스템에 영향을 주지 않고 제약을 추가할 수 있어야 합니다.
- 다른 아키텍처를 거의 방해하지 않으면서 즉시 구현할 수 있어야 합니다.
이 요구를 바탕으로 드라이버 코드가 사용할 다섯 가지 공통 power-management 함수를 제안합니다.
공통 PM 함수
33-58MPU의 최대 wakeup latency를 설정합니다.
(*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t)
장치의 최대 wakeup latency를 설정합니다.
(*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
system DMA transfer의 최대 시작 latency, 즉 CORE pwrdm 제약을 설정합니다.
(*pdata->set_max_sdma_lat)(struct device *dev, long t)
장치에 필요한 최소 bus throughput을 설정합니다.
(*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r)
장치가 context를 잃은 횟수를 반환합니다.
(*pdata->get_dev_context_loss_count)(struct device *dev)
모든 OMAP PM interface 함수의 추가 문서는 `arch/arm/plat-omap/include/mach/omap-pm.h`에서 찾을 수 있습니다.
임시 계층으로서의 OMAP PM
59-67최종적으로 Linux PM QoS 계층이 OMAP3에 있는 power-management 기능 범위를 지원하도록 하는 것이 의도입니다. 지원이 갖춰지면 OMAP PM interface를 쓰던 드라이버를 Linux PM QoS 코드로 바꾸고 OMAP PM interface를 제거할 수 있습니다.
드라이버에서 사용하는 방법
68-112앞의 예제에서 `pdata`가 나타내듯 이 함수들은 드라이버의 `.platform_data` 구조체 안 function pointer를 통해 노출됩니다. `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);
가장 흔한 용도는 interrupt 발생 시점부터 장치에 접근할 수 있게 될 때까지의 최대 시간을 지정하는 것입니다. `set_max_mpu_wakeup_lat()`로 MPU wakeup latency를 제한하고, `set_max_dev_wakeup_lat()`로 `clk_enable()`부터 장치 접근 가능 시점까지의 device wakeup latency를 제한합니다.
/* 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) */
이 예제의 전체 wakeup latency는 `tc + td`입니다. 새 값으로 함수를 다시 호출하면 PM 매개변수를 덮어쓸 수 있습니다. 설정을 제거하려면 `t`를 `-1`로 호출합니다. 다만 원문이 `set_max_bus_tput()`라고 부르는 함수는 `r`을 `0`으로 호출해야 합니다.
다섯 번째 함수인 `omap_pm_get_dev_context_loss_count()`는 장치가 내부 context를 잃었는지 드라이버가 효율적으로 판단하도록 돕는 최적화입니다. context를 잃었다면 드라이버는 계속 진행하기 전에 내부 context를 복원해야 합니다.
특수 목적 인터페이스 함수
113-136앞의 다섯 함수는 모든 장치 드라이버가 사용할 수 있도록 설계되었습니다. DSPBridge와 CPUFreq에는 추가 요구가 있습니다. DSPBridge는 목표 DSP 성능 수준을 OPP ID로 표현하고 CPUFreq는 목표 MPU 성능 수준을 MPU frequency로 표현하므로, OMAP PM interface는 이 입력을 기반 power-management 구현이 필요로 하는 형식으로 변환하는 함수를 제공합니다.
| 번호 | 함수 | 역할 |
|---|---|---|
| 6 | `(*pdata->dsp_get_opp_table)(void)` | DSP OPP table 조회 |
| 7 | `(*pdata->dsp_set_min_opp)(u8 opp_id)` | 최소 DSP OPP 설정 |
| 8 | `(*pdata->dsp_get_opp)(void)` | 현재 DSP OPP 조회 |
| 9 | `(*pdata->cpu_get_freq_table)(void)` | CPU frequency table 조회 |
| 10 | `(*pdata->cpu_set_freq)(unsigned long f)` | CPU frequency 설정 |
| 11 | `(*pdata->cpu_get_freq)(void)` | 현재 CPU frequency 조회 |
플랫폼별 OPP 사용자 정의
137-165`CONFIG_PM`을 정의하면 해당 silicon의 OPP 계층이 활성화되고 OPP table이 자동으로 등록되어야 합니다. 그러나 특별한 경우 기본 OPP table을 조정해야 할 수 있습니다.
- 기본적으로 비활성화되어 있지만 해당 플랫폼에서는 사용할 수 있는 default OPP 활성화
- 플랫폼이 지원하지 않는 OPP 비활성화
- 사용자 정의 OPP table entry 정의 및 추가
이 경우 `arch/arm/mach-omapx/board-xyz.c`의 board file에서 기본 table을 초기화한 뒤 추가 조정을 수행합니다.
#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`는 OMAP family에 따라 `omap3_opp_init` 또는 그에 맞는 초기화 함수가 됩니다.
요약과 해설
omap_pm.rst:1-165OMAP PM interface는 드라이버가 하드웨어 고유 power state를 직접 선택하지 않고 latency와 throughput이라는 기본 단위로 요구 조건을 표현하게 합니다. `.platform_data` function pointer를 사용하므로 같은 드라이버를 비 OMAP 아키텍처에서도 조건부로 재사용할 수 있습니다.
공통 API는 MPU·장치·DMA의 지연, bus 처리량, context loss를 다루고 DSPBridge와 CPUFreq용 변환 API가 이를 보완합니다. 이 계층은 장기적으로 Linux PM QoS로 대체될 임시 호환 계층입니다.
드라이버의 기본 단위 요구가 플랫폼 function pointer를 거쳐 OMAP PM 구현으로 전달되고, 장기적으로 Linux PM QoS가 그 역할을 흡수합니다.