4.2.5. 设计说明

4.2.5.1. 源码说明

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 配置

4.2.5.2. 模块架构

../../../_images/sw_system11.png

CMU 驱动的逻辑比较简单,目前只在 HAL 层提供了 Clock 和 Reset 的 API 接口。RTOS 驱动和 Baremetal 驱动都可以直接使用。

4.2.5.2.1. Clock

4.2.5.2.1.1. 时钟树

../../../_images/clock_tree.png

CMU 驱动将时钟树中的时钟分为五种类型:

  • fixed rate clock 包含 OSC24M、RC1M、OSC32K 三个时钟,这种时钟频率固定,不能调节频率,不能打开或关闭。

  • fixed parent module clock 实现只有一个父时钟源的时钟驱动,主要是各个外设模块的时钟,该类型时钟可以改变时钟频率,打开或关闭时钟,获取父时钟源参数,但不能设置或改变父时钟源。

  • multiple parent module clock 实现有多个父时钟源的时钟驱动,主要是各种总线时钟,该类型的时钟最为复杂,可以打开或关闭时钟,调节频率,获取或改变父时钟源。

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

  • pll clock 实现了 CMU 的 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

4.2.5.2.2. Reset

CMU 在提供 Clock 控制的同时,也提供了 Reset 控制功能。但是相对时钟树来说,并不是每一级的时钟都对应有 Reset 控制,只有终端模块才会有 Reset 控制的需求。对应上一节五种类型的时钟,只有 fixed parent clock 同时拥有 Reset 功能。

4.2.5.3. 关键流程设计

4.2.5.3.1. 初始化流程

4.2.5.3.1.1. Clock 驱动初始化

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

4.2.5.3.1.2. Reset 驱动初始化

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

4.2.5.4. 数据结构设计

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

4.2.5.4.1. 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;
};

4.2.5.4.2. 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;           // 父时钟数组
};

4.2.5.4.3. 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;
};

4.2.5.4.4. 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
};

4.2.5.5. 接口设计

4.2.5.5.1. Clock API

CMU 驱动提供了 Clock API 接口函数,不同类型时钟支持的 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

4.2.5.5.1.1. hal_clk_enable

函数原型

int hal_clk_enable(uint32_t clk_id)

功能说明

使能时钟

参数定义

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

返回值

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

注意事项

4.2.5.5.1.2. hal_clk_disable

函数原型

int hal_clk_disable(uint32_t clk_id)

功能说明

关闭时钟

参数定义

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

返回值

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

注意事项

4.2.5.5.1.3. hal_clk_enable_deassertrst

函数原型

int hal_clk_enable_deassertrst(uint32_t clk_id)

功能说明

使能时钟的同时放开复位

参数定义

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

返回值

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

注意事项

4.2.5.5.1.4. hal_clk_disable_assertrst

函数原型

int hal_clk_disable_assertrst(uint32_t clk_id)

功能说明

关闭时钟的同时使能复位

参数定义

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

返回值

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

注意事项

4.2.5.5.1.5. hal_clk_enable_iter

函数原型

int hal_clk_enable_iter(uint32_t clk_id)

功能说明

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

参数定义

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

返回值

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

注意事项

4.2.5.5.1.6. hal_clk_enable_deassertrst_iter

函数原型

int hal_clk_enable_deassertrst_iter(uint32_t clk_id)

功能说明

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

参数定义

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

返回值

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

注意事项

4.2.5.5.1.7. hal_clk_get_freq

函数原型

unsigned long hal_clk_get_freq(uint32_t clk_id)

功能说明

获取时钟频率

参数定义

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

返回值

时钟频率,单位为 Hz

注意事项

4.2.5.5.1.8. 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)

注意事项

4.2.5.5.1.9. hal_clk_get_parent

函数原型

unsigned int hal_clk_get_parent(uint32_t clk_id)

功能说明

获取时钟频率

参数定义

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

返回值

父时钟 ID

注意事项

4.2.5.5.1.10. hal_clk_set_parent

函数原型

int hal_clk_set_parent(uint32_t clk_id, unsigned int parent_clk_id)

功能说明

设置时钟频率

参数定义

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

返回值

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

注意事项

4.2.5.5.2. Reset API

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

API 函数

功能描述

hal_reset_assert()

使能复位

hal_reset_deassert()

放开复位

hal_reset_status()

获取复位状态

4.2.5.5.2.1. hal_reset_assert

函数原型

int hal_reset_assert(uint32_t rst_id)

功能说明

使能复位

参数定义

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

返回值

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

注意事项

4.2.5.5.2.2. hal_reset_deassert

函数原型

int hal_reset_deassert(uint32_t rst_id)

功能说明

放开复位

参数定义

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

返回值

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

注意事项

4.2.5.5.2.3. hal_reset_status

函数原型

int hal_reset_status(uint32_t rst_id)

功能说明

查看复位状态

参数定义

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

返回值

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

注意事项