cpu

e2000q cpufreq

phytium e2000q cpu 调频

发布于 2026年7月23日

Phytium E2000Q 平台 CPU 调频架构

平台概述

Phytium 飞腾腾珑 E2000Q 标准版 关键规格:

参数
CPU 架构 ARM64 (ARMv8-A),big.LITTLE 异构多核
CPU 核心 2×飞腾 FTC310 小核(CPU part 0x303)@ 1.5GHz + 2×飞腾 FTC664 大核(CPU part 0x664)@ 2.0GHz
L2 Cache 2MB(大核 cluster)+ 256KB(小核 cluster)
典型功耗 6.4W / TDP 11W
内核电压 0.85V
SCMI 固件 Phytium:E2000,协议 v2.0

调频实现方式:采用 ARM SCMI (System Control and Management Interface) 标准协议

芯片内置一个系统控制处理器(SCP,位于 SoC 内部但独立于 CPU 核心),
Linux 主核通过 SCMI 协议与 SCP 通信,由 SCP 实际操作时钟/电压硬件完成调频。


一、整体架构分层

┌─────────────────────────────────────────────────────────┐
│ 用户态 (Userspace)                                       │
│   /sys/devices/system/cpu/cpufreq/policy*/  (sysfs)     │
│   echo $FREQ > scaling_setspeed                         │
└──────────────────────┬──────────────────────────────────┘
                       │ write
┌──────────────────────▼──────────────────────────────────┐
│ ① cpufreq 核心框架  drivers/cpufreq/cpufreq.c            │
│   + governor (schedutil/ondemand/userspace...)           │
│   决策目标频率                                            │
└──────────────────────┬──────────────────────────────────┘
                       │ cpufreq_driver ops
┌──────────────────────▼──────────────────────────────────┐
│ ② SCMI cpufreq 驱动  drivers/cpufreq/scmi-cpufreq.c     │
│   scmi_cpufreq_set_target() / scmi_cpufreq_fast_switch() │
│   → handle->perf_ops->freq_set()                         │
└──────────────────────┬──────────────────────────────────┘
                       │ scmi_perf_ops
┌──────────────────────▼──────────────────────────────────┐
│ ③ SCMI Performance 协议  drivers/firmware/arm_scmi/perf.c│
│   scmi_perf_level_set()  两条路径:                        │
│     a) FastChannel: iowrite32 共享内存 + ring doorbell   │
│     b) Mailbox: scmi_do_xfer() 标准 SCMI 消息            │
└──────────────────────┬──────────────────────────────────┘
                       │ scmi_transport_ops
        ┌──────────────┴──────────────┐
┌───────▼──────────┐        ┌─────────▼──────────┐
│ ④a Mailbox 传输   │        │ ④b SMC 传输(可选)   │
│ scmi/mailbox.c    │        │ scmi/smc.c          │
│ mbox_send_message │        │ arm_smccc_1_1_invoke│
└───────┬──────────┘        └─────────┬──────────┘
        │ mbox_chan_ops               │ SMC/HVC 异常
┌───────▼──────────┐        ┌─────────▼──────────┐
│ ⑤ Phytium mailbox│        │ PSCI/ATF 固件       │
│ phytium-mailbox.c│        │ (Trusted Firmware)  │
│ 写 INTR_SET 寄存器│        └─────────┬──────────┘
└───────┬──────────┘                  │
        │ 触发硬件中断                 │
════════╪═════════════════════════════╪══════ 硬件边界 ═══
┌───────▼─────────────────────────────▼──────────┐
│ ⑥ SCP 固件 (E2000Q 片内系统控制处理器)           │
│   - 接收中断/SCMI 消息                            │
│   - 解析 PERF_LEVEL_SET 命令                      │
│   - 操作时钟发生器/PLL/电压调节器                  │
│   - 实际性能域划分(基于 policy 推测):            │
│       小核 cluster (cpu0-1) → 一个域             │
│       大核 cpu2 → 一个独立域                     │
│       大核 cpu3 → 一个独立域                     │
│   - 写共享内存返回响应 + 触发中断(? 未确认)        │
└─────────────────────────────────────────────────┘

二、各组件详解

1. cpufreq 核心框架

drivers/cpufreq/cpufreq.c

职责: 通用调频抽象层,与具体硬件无关。

  • 提供 sysfs 接口: scaling_setspeed, scaling_governor, scaling_cur_freq
  • 管理 governor(调频策略):
    • userspace — 用户直接指定频率
    • schedutil — 根据 CPU 负载动态调整(默认)
    • performance/powersave — 固定最高/最低
    • ondemand — 按需调节
  • 决策后调用驱动的 target_index()fast_switch()

E2000Q 上的实际 policy 拓扑(依据设备 /sys/devices/system/cpu/cpufreq/ 输出):

policy affected_cpus 核心类型 最大频率 可用频率(kHz)
policy0 0-1 小核(FTC310) 1.5GHz 187500, 375000, 750000, 1500000
policy2 2 大核(FTC664) 2.0GHz 250000, 500000, 1000000, 2000000
policy3 3 大核(FTC664) 2.0GHz 250000, 500000, 1000000, 2000000

2. SCMI cpufreq 驱动

drivers/cpufreq/scmi-cpufreq.c

职责: 将 cpufreq 通用操作转换为 SCMI 性能协议调用。

关键函数(scmi-cpufreq.c):

函数 用途 调用 SCMI 接口
scmi_cpufreq_set_target() 常规调频(进程上下文) perf_ops->freq_set(handle, domain_id, freq*1000, false)
scmi_cpufreq_fast_switch() 快速切换(中断上下文) perf_ops->freq_set(..., true) (poll 模式)
scmi_cpufreq_get_rate() 读当前频率 perf_ops->freq_get()
scmi_get_sharing_cpus() 获取同 domain 的 CPU 通过 device_domain_id() 聚类

domain 映射(scmi-cpufreq.c):

  • device_domain_id(cpu_dev) 从 DT/ACPI 读取每个 CPU 的 domain
  • 同 domain 的 CPU 被聚到同一个 policy,共享频率
  • E2000Q 实际:cpu0/cpu1 → 同一 domain(推测 domain 0),cpu2 → 独立 domain(推测 domain 1),cpu3 → 独立 domain(推测 domain 2)

3. SCMI Performance 协议

drivers/firmware/arm_scmi/perf.c

职责: 实现 SCMI 规范中的 Performance 协议(协议 ID 0x13),提供 freq_set/freq_get/limits_set 等操作。

两条调频路径(perf.c):

static int scmi_perf_level_set(handle, domain, level, poll) {
    if (dom->fc_info && dom->fc_info->level_set_addr) {
        // 路径 a: Fast Channel —— 直接写共享内存 + 敲 doorbell
        iowrite32(level, dom->fc_info->level_set_addr);
        scmi_perf_fc_ring_db(dom->fc_info->level_set_db);
        return 0;
    }
    // 路径 b: 标准 Mailbox 消息
    return scmi_perf_mb_level_set(handle, domain, level, poll);
}
路径 延迟 上下文 原理
Fast Channel ~µs 级 可用于中断上下文 Linux 直接写预共享的 SRAM,写 doorbell 触发 SCP 中断
Mailbox ~ms 级(实测 ~2.7ms) 进程上下文 完整 SCMI 消息:组帧 → 写 shmem → 发中断 → 等响应

关键 SCMI 命令:

命令 ID 用途
PERF_LEVEL_SET 0x7 设置目标频率等级
PERF_LEVEL_GET 0x8 读当前频率等级
PERF_LIMITS_SET 0x9 设置频率上下限
PERF_NOTIFY_LIMITS 0xA 使能限制变化通知
PERF_NOTIFY_LEVEL 0xB 使能等级变化通知

4. 传输层 (Transport)

a. Mailbox 传输

drivers/firmware/arm_scmi/mailbox.c

  • 适配内核 mailbox 框架
  • chan_lock 互斥锁,保证同一时刻只有一条消息在飞
  • 使用共享内存 (shmem.c) 传递消息内容
  • 关键操作: send_message / fetch_response / fetch_notification / clear_channel

b. SMC 传输

drivers/firmware/arm_scmi/smc.c,可选

  • 通过 arm_smccc_1_1_invoke() 触发 SMC/HVC 陷入 EL3
  • 由 ATF (ARM Trusted Firmware) 转发给 SCP
  • E2000Q 上根据 DT 中 arm,scmi 还是 arm,scmi-smc 选择

5. Phytium Mailbox 控制器驱动

drivers/mailbox/phytium-mailbox.c

职责: 操作 E2000Q 片内 mailbox 硬件(SoC 专用 IP)。

// 发送: 写寄存器触发 SCP 中断
phytium_mbox_send_data():
    writel_relaxed(*arg, mlink->tx_reg + INTR_SET);

// 接收: SCP 回中断
phytium_mbox_rx_irq():
    val = readl_relaxed(mlink->rx_reg + INTR_STAT);
    mbox_chan_received_data(chan, &val);   // 唤醒 SCMI 层
    writel_relaxed(val, mlink->rx_reg + INTR_CLR);

硬件寄存器:

寄存器 偏移 用途
INTR_STAT 0x0 中断状态(读)
INTR_SET 0x8 触发中断(写)
INTR_CLR 0x10 清除中断
TX_REG 0x100 发送通道基址

设备匹配:

  • ACPI: PHYT0009
  • DeviceTree: phytium,mbox

6. SCP 固件(E2000Q 片内)

职责: 实际执行频率切换。

  1. 接收 mailbox 中断或 doorbell
  2. 解析 SCMI PERF_LEVEL_SET 命令(domain_id, level)
  3. 查 OPP 表,操作:
    • 时钟发生器 / PLL 重配置
    • 电压调节(DVFS 配套,0.85V 内核电压)
  4. 实际性能域划分(根据 policy 推测): | CPU | 类型 | domain ID | |—–|——|———–| | cpu0-1 | 小核(FTC310) | 2 | | cpu2 | 大核(FTC664) | 0 | | cpu3 | 大核(FTC664) | 1 |

  5. 写响应到共享内存,触发回执中断
  6. 可主动发送异步通知(如温控降频触发 PERF_NOTIFY_LIMITS

SCP firmware:运行在 SoC 内部 System Control Processor 上的独立固件,
通过 SCMI mailbox/FastChannel 接收 Linux AP 请求,并负责执行 clock、PLL、voltage、power domain 等底层控制。


三、完整调用链(以 userspace 调频为例)

echo 2000000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed(小核调频)为例:

1. sysfs write
   store_scaling_setspeed()              [cpufreq.c]
   └── policy->governor->store_setspeed()  (userspace governor)
       └── cpufreq_driver->target_index()
           │
2. SCMI cpufreq 驱动
           └── scmi_cpufreq_set_target()   [scmi-cpufreq.c]
               └── perf_ops->freq_set(handle, domain_id=0, freq*1000, false)
                   │
3. SCMI perf 协议
                   └── scmi_dvfs_freq_set() → scmi_perf_level_set()
                       [perf.c]
                       ├─ 若 Fast Channel 可用: iowrite32 → ring doorbell → 完成
                       └─ 否则 Mailbox 路径:
                           └── scmi_perf_mb_level_set()  [perf.c]
                               ├── scmi_xfer_get_init()  组 SCMI 消息帧
                               │     (PERF_LEVEL_SET=0x7, proto=0x13)
                               └── scmi_do_xfer()        [driver.c]
                                   │
4. SCMI 核心
                                   └── info->desc->ops->send_message()
                                       │
5. Mailbox 传输
                                       └── mailbox_send_message()
                                           [mailbox.c]
                                           ├── mutex_lock(&chan_lock)
                                           └── mbox_send_message(chan, xfer)
                                               │
6. Mailbox 框架
                                               └── msg_submit → chan->ops->send_data()
                                                   │
7. Phytium 硬件驱动
                                                   └── phytium_mbox_send_data()
                                                       [phytium-mailbox.c]
                                                       └── writel(val, tx_reg + INTR_SET)
                                                           ↓ 触发 SCP 硬件中断
8. SCP 固件 (E2000Q 片内)
   ├── ISR 读取共享内存消息
   ├── 解析 PERF_LEVEL_SET(domain, level)
   ├── 操作对应 PLL/时钟分频器切换频率

四、组件交互关系图

   ┌────────────┐  freq_table   ┌─────────────┐
   │  Governor  │──────────────▶│ cpufreq core│
   │(schedutil) │  决策频率      │  (policy0/2/3)
   └────────────┘               └──────┬──────┘
                                       │ target_index/fast_switch
                                       ▼
                            ┌────────────────────┐
                            │  scmi-cpufreq      │◀──┐
                            │  (cpufreq_driver)  │   │
                            └──────┬─────────────┘   │
                                   │ perf_ops        │ scmi_handle
                                   ▼                 │ (probe 时获得)
                            ┌────────────────────┐   │
                            │ SCMI perf protocol │   │
                            │  perf.c            │───┘
                            │  (domains)         │
                            └──────┬─────────────┘
                                   │ xfer
                ┌──────────────────┼──────────────────┐
                ▼                  ▼                  ▼
        ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
        │ mailbox.c    │  │ smc.c        │  │ notify.c     │
        │(TX 通道)      │  │(SMC 通道)     │  │(RX 异步事件)  │
        └──────┬───────┘  └──────┬───────┘  └──────▲───────┘
               │ mbox_send       │ SMC              │ rx_callback
               ▼                 ▼                  │
        ┌──────────────────────────────────────────┴───────┐
        │  Phytium mailbox 硬件 + 共享内存 (shmem)          │
        └──────────────────────┬───────────────────────────┘
                               │ 中断
                               ▼
                    ┌─────────────────────┐
                    │  SCP 固件 (E2000Q)   │
                    │  多个性能域          │
                    │  DVFS/时钟/电压控制  │
                    └─────────────────────┘

五、关键交互机制

交互对 机制 数据结构
userspace ↔ cpufreq core sysfs 文件读写 cpufreq_policy
governor ↔ cpufreq core 回调函数 cpufreq_governor ops
cpufreq core ↔ scmi-cpufreq 驱动 ops cpufreq_driver
scmi-cpufreq ↔ perf 协议 scmi_handle 句柄 scmi_perf_ops
perf 协议 ↔ 传输层 xfer 消息 scmi_xfer
mailbox 传输 ↔ Phytium 驱动 mbox 框架 API mbox_chan
Phytium 驱动 ↔ SCP 硬件 MMIO 寄存器 + 中断 + 共享内存 INTR_SET/STAT/CLR + shmem
SCP → Linux(异步通知) RX 中断 → notify.c → kfifo → workqueue → notifier chain scmi_notify_ops

六、E2000Q big.LITTLE 架构特性

6.1 性能域和调频策略

设备实际显示:

  • 小核集群(cpu0-1):共享一个 policy(policy0),频率范围 187.5kHz ~ 1.5GHz,共 4 档。
  • 大核(cpu2):独立 policy(policy2),频率范围 250kHz ~ 2.0GHz,共 4 档。
  • 大核(cpu3):独立 policy(policy3),频率范围相同。

这意味着大核之间频率不强制同步,系统可以分别调节每个大核的频率,提供更精细的功耗/性能控制。

┌─────────────────────────────────────────────────────────────┐
│                       E2000Q SoC                            │
│                                                             │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐     │
│  │ FTC310 小核   │   │ FTC664 大核  │   │ FTC664 大核   │     │
│  │  cpu0,cpu1   │   │  cpu2        │   │  cpu3        │     │
│  │  ≤ 1.5 GHz   │   │  ≤ 2.0 GHz   │   │  ≤ 2.0 GHz   │     │
│  └──────┬───────┘   └──────┬───────┘   └──────┬───────┘     │
│         │                  │                  │             │
│         │                  │                  │             │
│      PLL (小核)        PLL (大核2)        PLL (大核3)         │
│         │                  │                  │             │
│  ┌──────▼─────┐     ┌──────▼─────┐     ┌──────▼─────┐       │
│  │  domain 2  │     │  domain 0  │     │  domain 1  │       │
│  └────────────┘     └────────────┘     └────────────┘       │
│                                                             │
│                                                             │
│             ┌────────────────────────────┐                  │
│             │        SCP 固件             │                  │
│             │  管理所有性能域              │                  │
│             └────────────────────────────┘                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6.2 查看设置频率

# 查看所有 policy
ls /sys/devices/system/cpu/cpufreq/
# 输出:policy0  policy2  policy3

# 查看每个 policy 影响的 CPU
cat /sys/devices/system/cpu/cpufreq/policy0/affected_cpus   # 输出:0 1
cat /sys/devices/system/cpu/cpufreq/policy2/affected_cpus   # 输出:2
cat /sys/devices/system/cpu/cpufreq/policy3/affected_cpus   # 输出:3

# 查看频率表
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies
# 187500 375000 750000 1500000
cat /sys/devices/system/cpu/cpufreq/policy2/scaling_available_frequencies
# 250000 500000 1000000 2000000
cat /sys/devices/system/cpu/cpufreq/policy3/scaling_available_frequencies
# 250000 500000 1000000 2000000

# 独立调频验证(大核各自设置不同频率)
echo 1000000 > /sys/devices/system/cpu/cpufreq/policy2/scaling_setspeed
echo 2000000 > /sys/devices/system/cpu/cpufreq/policy3/scaling_setspeed
cat /sys/devices/system/cpu/cpufreq/policy2/scaling_cur_freq  # 应为 1000000
cat /sys/devices/system/cpu/cpufreq/policy3/scaling_cur_freq  # 应为 2000000

6.3 调频验证

bdrt:/sys/devices/system/cpu/cpufreq/policy2$ cat affected_cpus
2
bdrt:/sys/devices/system/cpu/cpufreq/policy2$ taskset -c 2 busybox sh -c 'while :; do :; done' &
bdrt:/sys/devices/system/cpu/cpufreq/policy2$
bdrt:/sys/devices/system/cpu/cpufreq/policy2$
bdrt:/sys/devices/system/cpu/cpufreq/policy2$
bdrt:/sys/devices/system/cpu/cpufreq/policy2$ echo 2000000 > scaling_setspeed
bdrt:/sys/devices/system/cpu/cpufreq/policy2$ cat cpuinfo_cur_freq
2000000
bdrt:/sys/devices/system/cpu/cpufreq/policy2$ perf stat -e cycles -C 2 sleep 10

 Performance counter stats for 'CPU(s) 2':

       20004449692      cycles

      10.002217960 seconds time elapsed

bdrt:/sys/devices/system/cpu/cpufreq/policy2$ echo 250000 > scaling_setspeed
bdrt:/sys/devices/system/cpu/cpufreq/policy2$ cat cpuinfo_cur_freq
250000
bdrt:/sys/devices/system/cpu/cpufreq/policy2$ cat scaling_cur_freq
250000
bdrt:/sys/devices/system/cpu/cpufreq/policy2$ perf stat -e cycles -C 2 sleep 10

 Performance counter stats for 'CPU(s) 2':

        2500662426      cycles

      10.002596800 seconds time elapsed

结果对比

设置频率 scaling_cur_freq cpuinfo_cur_freq perf cycles (10s) 频率比 cycles 比
250 kHz 250000 250000 2,500,662,426 1x 1x
2000 MHz 2000000 2000000 20,004,449,692 8x ~8.0x

观察

  • cycles 比值 ≈ 8.0,与频率比值(2000/250 = 8)吻合。
  • 证明 CPU2 硬件确实以所设频率运行,调频成功。

6.4 低功耗场景特性

E2000Q 典型功耗 6.4W / TDP 11W,面向嵌入式无风扇场景:

  • 温控联动降频:SCP 固件可通过 PERF_NOTIFY_LIMITS 通知 Linux 调整 scaling_max_freq
  • schedutil governor 节能:小核可降至最低档(187.5kHz),大核可降至最低档(250kHz)。
  • 大核独立调频:可以在轻负载时单独降频某一个大核,进一步节能。
  • Fast Channel 的价值:若固件支持,可大幅降低调频延迟,提升 schedutil 的响应速度,但当前实测平台使用 Mailbox。

七、参考代码位置

内核版本linux-5.4.74

组件 文件路径
cpufreq 核心 drivers/cpufreq/cpufreq.c
SCMI cpufreq 驱动 drivers/cpufreq/scmi-cpufreq.c
SCMI perf 协议 drivers/firmware/arm_scmi/perf.c
SCMI 核心 drivers/firmware/arm_scmi/driver.c
SCMI 通知子系统 drivers/firmware/arm_scmi/notify.c
Mailbox 传输 drivers/firmware/arm_scmi/mailbox.c
SMC 传输 drivers/firmware/arm_scmi/smc.c
共享内存操作 drivers/firmware/arm_scmi/shmem.c
Phytium mailbox 驱动 drivers/mailbox/phytium-mailbox.c
SCMI 公共头文件 include/linux/scmi_protocol.h