Linux CCF 概述

嵌入式系统中,时钟一直以来都是非常重要的部分,几乎所有的数字电路都需要时钟来驱动工作,各种计算机总线以及大多数外设接口都携带了时钟信号来同步数据,现代计算机体系结构中CPU和DDR还支持动态调频技术来调整负载和功耗。在CCF框架出现之前,Linux有一个老旧的时钟框架,该框架只有对时钟相关的编程接口定义,不同的SoC都有一套该框架的实现。随着SoC的发展,很快发现SoC的时钟硬件设计非常相似,导致内核中相关的时钟代码实现也非常相似,这种冗余和复杂的代码设计是不合理的

Linux的通用时钟框架(CCF, Common Clock Framework)提供了一个统一的API来控制设备上各种各样时钟节点,允许软件以独立于硬件的方式管理系统上可用的时钟,包括clock gating(选通)、rate adjustment(速率调整)、muxing(复用)或其他操作

CCF背后的主要思想是将分布在各种SoC平台的时钟驱动代码进行统一和抽象,它引入和时钟提供者(Provider)和时钟消费者(Consumer)的概念

  • 提供者是内核驱动程序,它负责向CCF框架注册时钟节点,并提供对硬件时钟的访问能力
  • 消费者是通过公共API访问CCF的内核驱动程序或子系统

上图位于中间位置的CCF部分就是框架核心层,实现了通用的时钟设备控制逻辑。下方的蓝色部分是时钟提供者,通过CCF核心层提供的统一API向CCF注册时钟节点,对节点连接关系进行描述。上方的时钟消费者使用CCF提供的控制函数接口对需要操作的时钟节点进行操作控制,例如设置时钟频率、设置时钟路径、使能等。左侧的设备树用于描述时钟节点的相关信息

时钟树(clock tree)

现代主流的SoC平台,都有非常复杂的时钟树,在处理器的手册中描述时钟的章节,一定会有一个复杂的时钟树图,下图是Hi3559手册中关于SensorHub时钟的介绍

时钟相关的节点有以下几种类型

  • 时钟源,就是产生时钟的器件,英文一般叫做Oscillator(有源振荡器,也叫谐振荡器)或者Crystal(无源振荡器,也叫晶振)
  • 用于倍频的锁相环(PLL, Phase Locked Loop)
  • 用于分频的divider
  • 用于多路选择的mux
  • 用于时钟门控的gating

各节点之间存在连接关系,SoC提供一组寄存器来对各时钟节点进行配置