1 概要
时钟管理模块是linux系统为统一管理各硬件的时钟而实现管理框架,负责所有模块的时钟调节和电源管理。
1.1 模块功能介绍
时钟管理模块主要负责处理各硬件模块的工作频率调节及电源切换管理。一个硬件模块要正常工作,必须先配置好硬件的工作频率、打开电源开关、总线访问开关等操作,时钟管理模块为设备驱动提供统一的操作接口,使驱动不用关心时钟硬件实现的具体细节。
1.2 相关术语介绍
晶振:晶体振荡器的简称,晶振有固定的振荡频率,如32K/24Mhz等,是芯片所有时钟的源头。
PLL: 锁相环,利用输入信号和反馈信号的差异提升频率输出。
时钟:驱动数字电路运转时的时钟信号。芯片内部的各硬件模块都需要时序控制,因此理解时钟信号对于底层编程非常重要。
1.3 系统时钟频率设置
lichee/tools/pack/chips/sun8iw7p1/configs/dolphin-p1/sys_config.fex 频率配置:
pll_video = 297
pll_ve = 402
pll_periph0 = 600
pll_gpu = 576
pll_periph1 = 600
pll_de = 864
对于没有配置的,系统设置频率为默认值。
系统时钟定义:
系统时钟主要是指一些源时钟,为其他硬件模块提供时钟源输入。系统时钟一般为多个硬件模块共享,不允许随意调节。
模块时钟定义
模块时钟主要是针对一些具体模块(如:gpu、de),在时钟频率配置、电源控制、访问控制等方面进行管理。一个典型的模块如下图所示,包含module gating、ahb gating、dram gating,以及reset控制。要想一个模块能够正常工作,必须在这几个方面作好相关的配置。
AHB,是Advanced High performance Bus的缩写,译作高级高性能总线,这是一种“系统总线”。AHB主要用于高性能模块(如CPU、DMA和DSP等)之间的连接。AHB 系统由主模块、从模块和基础结构(Infrastructure)3部分组成,整个AHB总线上的传输都由主模块发出,由从模块负责回应。
APB,是Advanced Peripheral Bus的缩写,这是一种外围总线。APB主要用于低带宽的周边外设之间的连接,例如UART、1284等,它的总线架构不像 AHB支持多个主模块,在APB里面唯一的主模块就是APB 桥。
这两者都是总线,符合AMBA规范。
2 时钟配置及注册相关代码
注:主要以dma时钟为例
lichee/linux-3.4/drivers/clk
linux-3.4/arch/arm/mach-sunxi/ sun8i.c
MACHINE_START(SUNXI, "sun8i")
.atag_offset = 0x100,
.init_machine = sunxi_dev_init,
.init_early = sunxi_init_early,
.map_io = sunxi_map_io,
#ifndef CONFIG_OF
.init_irq = sun8i_gic_init,
#endif
.handle_irq = gic_handle_irq,
.restart = sun8i_restart,
.timer = &sunxi_timer,
.dt_compat = NULL,
.reserve = sun8i_reserve,
.fixup = sun8i_fixup,
.nr_irqs = NR_IRQS,
#ifdef CONFIG_SMP
.smp = smp_ops(sunxi_smp_ops),
#if defined(CONFIG_ARCH_SUN8IW6) || defined(CONFIG_ARCH_SUN8IW9)
.smp_init = smp_init_ops(sun8i_smp_init_ops),
#endif
#endif
MACHINE_END
MACHINE_START主要是定义了"struct machine_desc"的类型,放在 section(".arch.info.init"),是初始化数据,Kernel 起来之后将被丢弃。
其余各个成员函数在setup_arch()中被赋值到内核结构体,在不同时期被调用:
1. .init_machine