Edit online

设计说明

Read time: 8 minute(s)
Edit online

源码说明

Read time: 8 minute(s)
CMU 相关 .c.h 文件分别位于 luban-lite\bsp\artinchip\hal\cmuluban-lite\bsp\artinchip\include\hal 目录。主要源文件说明如下:

文件

说明

aic_clk_id.h

时钟 ID 以及 寄存器设置

aic_hal_clk.h

hal 层 clk api 的头文件

aic_hal_clk.c

hal 层 clk api 的实现

aic_hal_reset.h

hal 层 reset api 的头文件

aic_hal_reset.c

hal 层 reset api 的实现

aic_hal_pll_clk.c

PLL 时钟的具体实现

aic_hal_fixed_rate_clk.c

固定频率时钟的具体实现

aic_hal_fixed_parent_clk.c

单个父时钟的时钟的具体实现

aic_hal_multi_parent_clk.c

多个父时钟的时钟的具体实现

aic_hal_disp_clk.c

DISP 时钟的具体实现

aic_hal_fpga_clk_def_v10.c

CMU V1.0 的 Clock 配置

aic_hal_fpga_clk_def_v11.c

CMU V1.1 的 Clock 配置

aic_hal_fpga_clk_def_v12.c

CMU V1.2 的 Clock 配置

aic_hal_reset_def_v10.c

CMU V1.0 的 Reset 配置

aic_hal_reset_def_v11.c

CMU V1.1 的 Reset 配置

aic_hal_reset_def_v12.c

CMU V1.2 的 Reset 配置

Edit online

Clock 和 Reset 类型

Read time: 8 minute(s)

sw_system10

CMU 驱动的逻辑相对简单,目前只在 HAL 层提供了 Clock 和 Reset 的 API 接口。RTOS 驱动和 Baremetal 驱动都可以直接使用。
注: 相对时钟树来说,仅终端模块才有 Reset 控制的需求。在下列时钟树中,仅 fixed parent clock 同时拥有 Reset 功能。
Edit online

时钟树

Read time: 8 minute(s)

clock_tree

1. 时钟树
CMU 驱动将时钟树中的时钟分为五种类型,每种类型的时钟具有不同的特性和功能:
  • Fixed rate clock:具有固定的输出频率,通常用于驱动一些不需要动态调整频率的外设。时钟频率固定,不能调节频率,不能打开或关闭。固定频率时钟包括 OSC24M、RC1M 和 OSC32K。

  • Fixed parent module clock:从另一个时钟信号派生出来的时钟,其输出频率与父时钟信号的频率相同。该类型时钟可以实现只有一个父时钟源的时钟驱动,主要用于各个外设模块的时钟驱动。该类型时钟可以改变时钟频率,打开或关闭时钟,获取父时钟源参数,但不能设置或改变父时钟源。

  • Multiple parent module clock:可以从多个父时钟源中选择其中一个作为其输入,并根据需要调整输出频率。 该类型时钟可以实现有多个父时钟源的时钟驱动,主要用于各种总线时钟驱动,可以打开或关闭时钟,调节频率,获取或改变父时钟源。

  • Display module clock: 实现了几个与显示模块相关的时钟驱动,除了自身的模块时钟外,显示模块还有一个像素时钟,相应的底层寄存器的设计也不同,所以显示相关的几个时钟重新设计了底层驱动。

  • PLL clock:实现了 CMU 的 PLL 时钟驱动。PLL 是一种能够产生高频时钟信号的电路。PLL 可以将一个低频率的参考时钟信号乘以一个整数倍的频率因子,从而得到一个高频率的时钟信号。

下列表格列出了各种时钟分类对应的时钟树:
类型 时钟
Fixed rate clock OSC24M
OSC32K
RC1M
Fixed parent clock CLK_DMA
CLK_CE
CLK_USBD
CLK_USBH0-1
CLK_USB_PHY0-1
CLK_GMAC0-1
CLK_SPI0-1
CLK_SDMMC0-2
CLK_SYSCON
CLK_RTC
CLK_I2S0-1
CLK_ADDA
CLK_DE
CLK_GE
CLK_VE
CLK_WDOG
CLK_SID
CLK_GTC
CLK_GPIO
CLK_UART0-7
CLK_I2C0-3
CLK_CAN0-1
CLK_PWM
CLK_ADCIM
CLK_GPADC
CLK_RTP
CLK_TSEN
CLK_CIR
CLK_RGB
CLK_LVDS
CLK_MIPIDSI
Multi parent clock CLK_CPU
CLK_AHB0
CLK_APB0
CLK_APB1
CLK_AXI0
CLK_OUT0
CLK_OUT1
CLK_OUT2
CLK_OUT3
PLL clock CLK_PLL_INT0
CLK_PLL_INT1
CLK_PLL_FRA0
CLK_PLL_FRA1
CLK_PLL_FRA2
Disp clock CLK_PIX
CLK_SCLK
Edit online

关键流程设计

Read time: 8 minute(s)

Clock 和 Reset 驱动初始化

CMU 模块的初始化流程包括以下两个主要部分:
  • Clock 驱动初始化

    Clock 驱动主要是给其它驱动调用的,其本身没有初始化步骤。

  • Reset 驱动初始化

    Reset 驱动主要是给其它驱动调用的,其本身没有初始化步骤。

Edit online

数据结构设计

Read time: 8 minute(s)
CMU 模块关键结构体定义如下:

CMU 模块关键结构体定义如下:

aic_clk_fixed_parent_cfg
struct aic_clk_fixed_parent_cfg {
    struct aic_clk_comm_cfg comm;   // 时钟操作的函数集合
    u32 offset_reg;                 // 寄存器偏移地址
    s8 bus_gate_bit;                // 总线使能位偏移
    s8 mod_gate_bit;                // 模块使能位偏移
    u8 div_bit;                     // 分频系数位偏移
    u8 div_mask;                    // 分频系数 Mask
    u8 id;                          // 时钟 id
    u8 type;                        // 时钟类型
    u8 parent_id;                   // 父时钟 id
    u8 flag;
};
aic_clk_multi_parent_cfg
struct aic_clk_multi_parent_cfg {
    struct aic_clk_comm_cfg comm;   // 时钟操作的函数集合
    u32 offset_reg;                 // 寄存器偏移地址
    s32 gate_bit;                   // 时钟使能位偏移
    u8 mux_bit;                     // 父时钟源选择位的 bit 偏移
    u8 mux_mask;                    // 父时钟源选择位 Mask
    u8 div0_bit;                    // 分频系数位偏移
    u8 div0_mask;                   // 分频系数 Mask
    u8 id;                          // 时钟 id
    u8 num_parents;                 // 父时钟个数
    const u8 *parent_ids;           // 父时钟数组
};
aic_clk_pll_cfg
struct aic_clk_pll_cfg {
    struct aic_clk_comm_cfg comm;   // 时钟操作的函数集合
    u32 offset_gen;                 // 整数分频寄存器的偏移
    u32 offset_fra;                 // 小数分频寄存器的偏移
    u32 offset_sdm;                 // 展频寄存器的偏移
    u8 id;                          // 时钟 id
    u8 type;                        // 时钟类型
    u8 parent_id;                   // 父时钟 id
    u8 flag;
};
aic_clk_disp_cfg
struct aic_clk_disp_cfg {
    struct aic_clk_comm_cfg comm;   // 时钟操作的函数集合
    u32 offset_reg;                 // 寄存器偏移地址
    u8 divn_bit;                    // 分频系数 N 位偏移
    u8 divn_mask;                   // 分频系数 N 位 Mask
    u8 divm_bit;                    // 分频系数 M 位偏移
    u8 divm_mask;                   // 分频系数 M 位 Mask
    u8 divl_bit;                    // 分频系数 L 位偏移
    u8 divl_mask;                   // 分频系数 L 位 Mask
    u8 pix_divsel_bit;              // pix 分频系数位偏移
    u8 pix_divsel_mask;             // pix 分频系数位 Mask
    u8 id;                          // 时钟 id
    u8 parent_id;                   // 父时钟 id
};
Edit online

接口设计

Read time: 8 minute(s)

Clock API

CMU 驱动提供了 Clock API 接口函数,不同类型时钟支持的 API 接口函数如下表:
1. Clock API 接口函数

API 函数

功能描述

fixed
rate
clock

fixed
parent
clock

multi
parent
clock

disp
clock

pll
clock

hal_clk_enable()

使能时钟

-

-

hal_clk_disable()

关闭时钟

-

-

hal_clk_enable_deassertrst()

使能时钟的同时放开复位

-

-

-

-

hal_clk_disable_assertrst()

关闭时钟的同时使能复位

-

-

-

-

hal_clk_enable_iter()

迭代的使能时钟及其父时钟

-

-

hal_clk_enable_deassertrst_iter()

迭代的使能时钟及其父时钟
同时放开复位

-

-

-

-

hal_clk_get_freq()

获取时钟频率

hal_clk_set_freq()

设置时钟频率

-

hal_clk_get_parent()

获取父时钟 id

-

-

hal_clk_set_parent()

设置父时钟 id

-

-

-

-

2. hal_clk_enable

函数原型

int hal_clk_enable(uint32_t clk_id)

功能说明

使能时钟

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

3. hal_clk_disable

函数原型

int hal_clk_disable(uint32_t clk_id)

功能说明

关闭时钟

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

4. hal_clk_enable_deassertrst

函数原型

int hal_clk_enable_deassertrst(uint32_t clk_id)

功能说明

使能时钟的同时放开复位

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

5. hal_clk_disable_assertrst

函数原型

int hal_clk_disable_assertrst(uint32_t clk_id)

功能说明

关闭时钟的同时使能复位

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

6. hal_clk_enable_iter

函数原型

int hal_clk_enable_iter(uint32_t clk_id)

功能说明

迭代的使能时钟及其父时钟

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

7. hal_clk_enable_deassertrst_iter

函数原型

int hal_clk_enable_deassertrst_iter(uint32_t clk_id)

功能说明

迭代的使能时钟及其父时钟,同时放开复位

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

8. hal_clk_get_freq

函数原型

unsigned long hal_clk_get_freq(uint32_t clk_id)

功能说明

获取时钟频率

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

时钟频率,单位为 Hz

注意事项

-

9. hal_clk_set_freq

函数原型

int hal_clk_set_freq(uint32_t clk_id, unsigned long freq)

功能说明

设置时钟频率

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)
freq:时钟频率,单位为 Hz

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

10. hal_clk_get_parent

函数原型

unsigned int hal_clk_get_parent(uint32_t clk_id)

功能说明

获取父时钟 ID

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)

返回值

父时钟 ID

注意事项

-

11. hal_clk_set_parent

函数原型

int hal_clk_set_parent(uint32_t clk_id, unsigned int parent_clk_id)

功能说明

设置父时钟 ID

参数定义

clk_id:时钟 ID (CLK_xxxx 格式定义的宏)
parent_clk_id:父时钟 ID

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

Reset API

CMU 驱动提供了 Reset API 接口函数:

API 函数

功能描述

hal_reset_assert()

使能复位

hal_reset_deassert()

放开复位

hal_reset_status()

获取复位状态

12. hal_reset_assert

函数原型

int hal_reset_assert(uint32_t rst_id)

功能说明

使能复位

参数定义

rst_id:Reset ID (RESET_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

13. hal_reset_deassert

函数原型

int hal_reset_deassert(uint32_t rst_id)

功能说明

放开复位

参数定义

rst_id:Reset ID (RESET_xxxx 格式定义的宏)

返回值

操作是否成功 (0=OK, other=Error)

注意事项

-

14. hal_reset_status

函数原型

int hal_reset_status(uint32_t rst_id)

功能说明

查看复位状态

参数定义

rst_id:Reset ID (RESET_xxxx 格式定义的宏)

返回值

操作是否成功 (0=复位有效, 1=复位无效)

注意事项

-